Skip to content

Add artifact publication ledger and export pipeline - #1251

Merged
wesm merged 11 commits into
mainfrom
artifact/2-export-ledger
Jul 28, 2026
Merged

Add artifact publication ledger and export pipeline#1251
wesm merged 11 commits into
mainfrom
artifact/2-export-ledger

Conversation

@wesm

@wesm wesm commented Jul 24, 2026

Copy link
Copy Markdown
Member

Second PR in the artifact-sync split (follows #1242, which froze the wire format and added the docbank-backed store). Extracted from the closed #1239 branch with review fixes applied during extraction.

What this adds

  • SQLite publication ledger (internal/db): artifact_export_queue, artifact_publications, artifact_publication_revisions, artifact_checkpoint_heads/_floors, plus session triggers that enqueue owned-session changes. Triggers are origin-gated — they fire only once an artifact origin exists in pg_sync_state — so archives that never opt in carry no queue writes. Trigger DDL lives in Go and is installed after column migrations (drops run before), so no trigger references session columns while migrations run.
  • Go enqueue hooks for child-only mutations that don't touch trigger-covered session columns: batch message writes (queue generation sampled around the batch, enqueues exactly once when the triggers didn't fire), standalone usage-event replacement, and token-coverage backfill. Queue bootstrap is an explicit call at origin creation, not a migrate-time backfill.
  • Origin lifecycle (internal/artifact): EnsureOrigin/AdoptOrigin/StoredOrigin. Creating or adopting an origin bootstraps the export queue; a failed bootstrap rolls the origin back (deleting the key when there was none before, since the gates test key existence) so a retry re-runs population. Adopting over a different established origin force-requeues every owned session with a generation bump, because prior acknowledgements belong to the old origin.
  • Checkpointed export pipeline (internal/artifact): claims pending queue rows, publishes content-addressed session manifests and segments into the store, records publication revisions, and advances per-origin checkpoint heads with monotone sequence reservation. Stale claims (a writer advanced the generation mid-export) roll back atomically. Incremental export is bounded by the dirty batch; an unchanged archive costs a catalog identity check only. Full export streams all bodies, then re-checks the queue up to 32 settle rounds — hitting the bound returns the accumulated result with an error meaning "made progress, run again."
  • Resync carriage: CopySyncStateFrom carries queue, publication, revision, and checkpoint state across a full resync and re-dirties every copied queue row — the origin gate keeps triggers silent in the rebuild's temp DB, and a parser bump changes manifest hashes anyway, so the exporter must re-verify each session (unchanged content is cheap to skip, being content-addressed).

Scope and limitations

  • Export-side only. Nothing wires the pipeline to the daemon or CLI yet; that lands with folder transport and import in a later PR. There is no import/read path here.
  • The ledger is local SQLite state. PostgreSQL push and shared query shapes are untouched.
  • The wire format is unchanged: no golden churn, format stays frozen at v1.

Where to look

  • internal/db/artifact_publication.go — queue and ledger SQL, origin-gated enqueue
  • internal/db/db.go — trigger DDL split around column migrations, bootstrap/requeue
  • internal/artifact/export.go — publish → manifest → checkpoint ordering and claim lifecycle
  • internal/artifact/origin.go — origin lifecycle and rollback semantics
  • internal/db/orphaned.go — resync carriage and the pending-flag decision

@roborev-ci

roborev-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown

roborev: Combined Review (34b3440)

Export/origin handling has four medium-severity correctness issues that can cause nontermination, missed exports, stale republication, or persistent naming errors.

Medium

  • internal/artifact/export.go:299drain loops until the queue is empty, so concurrent writers can prevent a full export from ever reaching the bounded maxExportDrainRounds loop. Bound each drain invocation or count every processed page toward the global round limit, returning the unsettled-queue error when exhausted.

  • internal/db/orphaned.go:388 — Resync copies queue rows only from the old database. Sessions discovered while building the replacement database may have no queue row in either database and therefore may never be exported if their source remains unchanged. After restoring the origin and old queue state, enqueue all missing live, locally owned sessions from the replacement database in the same transaction.

  • internal/artifact/origin.go:96 — Divergent origin adoption requeues only currently live local sessions. When an earlier origin is readopted, retained publication rows for sessions deleted or transferred under another origin can remain authoritative and be republished indefinitely. Enqueue deletion claims for target-origin publications that are no longer locally owned, or atomically reset that origin’s publication/head state before rebuilding it.

  • internal/artifact/export.go:115GetSessionFull replaces a null display_name with session_name, causing manifests to encode an agent-provided name as though it were a user override. On import, that derived name becomes persistent and blocks later session-name updates. Export the raw session columns without applying the display-name fallback.


Reviewers: 2 done | Synthesis: codex, 12s | Total: 11m52s

@roborev-ci

roborev-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown

roborev: Combined Review (34b3440)

Artifact export has three medium-severity reliability issues involving resync publication, drain convergence, and origin initialization.

Medium

  • internal/db/orphaned.go:388 — Resync copies queue rows only from the old database. Sessions discovered during rebuilding are inserted before the origin key exists and are never queued, so they can remain absent from checkpoints indefinitely—even after a full export creates their dependencies. Enqueue every live local session in the rebuilt database after restoring the origin and old ledger, preserving copied generations for existing rows.

  • internal/artifact/export.go:299drain runs until the queue is empty without honoring maxExportDrainRounds. Continuous concurrent writes can keep any drain running forever, preventing the convergence cap from taking effect. Snapshot the initial queue boundary or enforce a shared bounded drain budget, leaving newly arriving work for the capped terminal rounds.

  • internal/artifact/origin.go:64 — Origin persistence and queue population occur in separate transactions. A crash between SetSyncState and bootstrap/requeue leaves an initialized origin with missing publication work; retries then take the fast path, and origin adoption can leave previously clean sessions unpublished. Atomically store or adopt the origin and populate or re-dirty the export queue in one database transaction.


Reviewers: 2 done | Synthesis: codex, 9s | Total: 26m50s

@wesm
wesm force-pushed the artifact/2-export-ledger branch from 34b3440 to dac339f Compare July 27, 2026 22:04
@roborev-ci

roborev-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

roborev: Combined Review (dac339f)

Code review identified two medium-severity issues in artifact publication recovery and checkpoint sizing.

Medium

  • internal/db/db.go:2465 — Origin adoption requeues only currently live local sessions. If the target origin was previously used, its artifact_publications may retain sessions deleted or made foreign while another origin was active. Because those IDs receive no claim, later checkpoints for the re-adopted origin continue publishing stale sessions.

    • Fix: Also enqueue every session ID previously published under the target origin so non-live entries can be removed. Add coverage for switching away, deleting a session, and switching back.
  • internal/artifact/export.go:744 — Checkpoint generation does not enforce checkpointDecodedLimit, although checkpoint discovery rejects larger entries at internal/artifact/export_checkpoint.go:81. A large publication map can therefore produce and record a checkpoint that head recovery later ignores.

    • Fix: Reject or shard oversized checkpoints before creating or recording them, and add a boundary test.

Reviewers: 2 done | Synthesis: codex, 8s | Total: 11m11s

@roborev-ci

roborev-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

roborev: Combined Review (2f49c04)

Medium-severity issues found in artifact export consistency and manifest decoding.

Medium

  • internal/db/messages.go:1152, 1359 — Standalone message replacement can change export-visible metadata without enqueueing an artifact export. transcriptMessagesEqual ignores token usage, source UUIDs, request IDs, and content-length metadata; if quality signals remain unchanged, no trigger-watched session field changes, leaving the published artifact stale. Add the before/after queue-generation fallback used by writeOneSessionBatchTx to both standalone replacement paths, with regression tests for metadata-only changes.

  • internal/artifact/wire_decode.go:25decodeManifestWithLimits accepts manifest versions older than the current v2 schema. A v1 manifest’s cost_usd is silently ignored by the v2 artifactUsageEvent, losing usage cost during decoding. Reject unsupported older versions or decode them through a version-specific DTO with explicit cost conversion.


Reviewers: 2 done | Synthesis: codex, 9s | Total: 14m20s

@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (8302e2e)

Medium — 3 findings; no High or Critical issues identified.

Medium

  • Origin mismatch can publish under the wrong namespaceinternal/db/artifact_publication.go:157
    Publication changes do not verify that origin matches the persisted artifact_origin_id. Because the queue is global rather than origin-scoped, an exporter using a stale or incorrect origin can claim and acknowledge current work under the wrong namespace, leaving the configured origin stale. Validate the persisted origin within the same locked transaction that validates claims and applies publication changes.

  • Export limits are enforced after unbounded materializationinternal/artifact/export.go:129
    Message and usage limits are checked only after GetAllMessages and GetUsageEvents materialize every row and nested tool collection. An oversized session can consume unbounded memory before safeguards run. Add bounded or streaming export queries that stop at cardinality and decoded-byte limits before constructing the complete object graph.

  • A deterministic failure can permanently starve the publication queueinternal/artifact/export.go:141
    A per-session failure, such as exceeding an export limit, aborts the entire batch before accumulated publication changes are applied or acknowledged. The failed FIFO entry is retried indefinitely, blocking later sessions. Isolate failures per claim, checkpoint and acknowledge successful claims, and rotate, back off, or record permanently rejected claims.


Reviewers: 2 done | Synthesis: codex, 15s | Total: 16m16s

- fix artifact export lifecycle convergence and stale origin recovery
- keep publication metadata and manifest versions consistent
- document bounded export rejection invariants and implementation plan
- bind publication claims to the active persisted origin
- persist generation-scoped rejection diagnostics atomically
- bound SQLite export preflight and nested hydration
- route all export paths through bounded snapshot loading
- isolate deterministic claim failures without starving FIFO work
- cover rejection removal, mutation retry, resync, and adoption lifecycles
- reject malformed canonical message metadata deterministically
@wesm
wesm force-pushed the artifact/2-export-ledger branch from 8302e2e to 7c8425d Compare July 28, 2026 03:21
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (7c8425d)

Medium-severity manifest encoding errors can repeatedly block FIFO artifact exports; no high or critical findings were reported.

Medium

  • internal/artifact/export.go:521 — Manifest encoding failures are returned untyped. A deterministic invalid value, such as a non-finite ContextPressureMax, can repeatedly abort the entire batch instead of rejecting that session, allowing one poisoned FIFO claim to starve later exports.
    • Fix: Wrap canonical manifest encoding errors with ErrArtifactExportRejected and add a mixed-batch regression test.

Reviewers: 2 done | Synthesis: codex, 8s | Total: 15m0s

A non-finite persisted session signal makes canonical manifest encoding fail deterministically for the same generation. Treat that data error as a rejection so one poisoned claim cannot block later FIFO exports.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (b6f5874)

Exports can be repeatedly blocked by noncanonical checkpoint JSON.

Medium

  • internal/artifact/export_checkpoint.go:207 — The checkpoint decoder accepts noncanonical JSON, including extra whitespace or escaped field names. Bootstrap retains the artifact’s raw SHA, but export reconstructs canonical bytes and rejects the resulting SHA mismatch. A semantically valid noncanonical checkpoint can therefore repeatedly block every export for that origin.
    • Fix: Compute canonical SHA and size during decoding, reject or quarantine candidates whose stored identity differs, and add regression tests for whitespace and escaped-key variants.

Reviewers: 2 done | Synthesis: codex, 8s | Total: 14m44s

Checkpoint discovery must not retain raw identities for semantically equivalent but noncanonical JSON, because export reconstructs canonical bytes and would otherwise wedge on a permanent hash mismatch. Verify streamed canonical SHA and size before accepting bootstrap candidates.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (f0f7a45)

One medium-severity issue could block bootstrap exports.

Medium

  • internal/artifact/export_checkpoint.go:112 — If checkpoint decoding fails before the entire body is consumed, Verify or Close returns an incomplete-verification error rather than ErrArtifactCorrupt. The function then aborts instead of skipping the invalid checkpoint, allowing one malformed checkpoint to permanently block bootstrap exports.
    • Suggested fix: After a semantic decode failure, drain the remaining reader to EOF before verification. Skip malformed or corrupt candidates while continuing to propagate operational read errors.

Reviewers: 2 done | Synthesis: codex, 9s | Total: 15m45s

Checkpoint verification already drains unread bytes before authenticating EOF, so an early semantic decode failure cannot turn a malformed candidate into an incomplete-verification error. Make that contract explicit at candidate classification and protect it through the real-store bootstrap path.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (468222d)

Artifact export is generally robust, but two medium-severity correctness issues should be fixed before merging.

Medium

  • Future-version detection can mask checkpoint corruptioninternal/artifact/export_checkpoint.go:216

    A future-version marker is returned before validating the closing object, trailing content, filename sequence, or canonical identity. An authenticated but malformed checkpoint—such as one truncated immediately after "v":2—is treated as a fatal future-version error, permanently blocking export instead of being skipped as corrupt.

    Fix: Record the future version, finish structural, filename, and canonical validation, then return errFutureArtifactVersion. Verification corruption should take precedence over that sentinel.

  • Invalid stored origin prevents authoritative configuration repairinternal/artifact/origin.go:48

    AdoptOrigin validates the existing stored origin before overwriting it. An invalid persisted value therefore prevents the configured origin from repairing the database, contradicting the documented behavior that the configured origin always wins.

    Fix: Remove the StoredOrigin preflight and let AdoptArtifactOrigin atomically read and replace the stored value after validating the new origin.


Reviewers: 2 done | Synthesis: codex, 11s | Total: 16m44s

Bootstrap must distinguish an unsupported but valid checkpoint from malformed or corrupt data, otherwise a poisoned future-version marker can block every export. Configured origin adoption must likewise repair malformed persisted state instead of validating the value it is replacing.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (fcf208e)

Review found two medium-severity correctness issues that should be addressed before merge; no security vulnerabilities were identified.

Medium

  • internal/db/db.go:2573 — New artifact origin does not requeue existing sessions

    Recreating a missing or empty artifact_origin_id uses INSERT OR IGNORE. Previously acknowledged queue rows can remain clean, so live sessions are never published under the newly generated origin.

    Fix: Whenever a new origin is persisted, force-requeue all live local sessions, bump their generations, and clear rejection state—even if the previous origin key was missing or empty.

  • internal/artifact/export.go:134 — Export conflates agent and user-owned session names

    GetSessionFull coalesces a missing user-owned display_name to the agent-owned session_name. Exporting that result writes an incorrect display_name into the manifest, losing the distinction between an agent title and a manual rename.

    Fix: Load raw, uncoalesced session metadata for export and add coverage for a session with a populated session_name and a null display_name.


Reviewers: 2 done | Synthesis: codex, 14s | Total: 12m22s

Recreated origins must republish live local sessions even when the prior state key disappears, otherwise clean ledger rows remain tied to a lost namespace. Manifest generation must also read raw name fields so agent-provided titles are not promoted into user-owned display names.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (db5cfa2)

Overall verdict: One medium-severity checkpoint compatibility issue should be fixed before merging.

Medium

  • internal/artifact/export_checkpoint.go:159 — Future-version checkpoints are parsed against the exact v1 field set before their version is recognized. A valid future format containing new canonical fields may therefore be rejected and skipped, allowing this version to publish a higher-sequence v1 checkpoint instead of deferring to the newer authority.

    Fix: Authenticate and parse future-version checkpoints without enforcing the v1 field set; retain strict canonical-field validation only for the current version.


Reviewers: 2 done | Synthesis: codex, 9s | Total: 19m32s

An authenticated future checkpoint remains authoritative even when its canonical schema adds fields unknown to v1. Parse and hash unknown values generically while retaining the exact v1 field contract for current checkpoints, preventing this exporter from publishing a downgrade checkpoint.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (b745f9e)

Medium-severity issue found in checkpoint version handling.

Medium

  • internal/artifact/export_checkpoint.go:217 — The decoder validates sessions against the v1 schema before reading the canonically last v field. A valid future checkpoint with a changed sessions representation or hash format is therefore treated as malformed instead of returning errFutureArtifactVersion. The exporter may then publish a higher-sequence v1 checkpoint and overwrite future-format authority.
    • Fix: Canonicalize future-version fields generically until the version is known, and call decodeCanonicalCheckpointSessionMap only for the current version. Add coverage for a canonical future checkpoint with a changed sessions representation.

Reviewers: 2 done | Synthesis: codex, 9s | Total: 15m13s

Future checkpoint authority must survive schema changes inside the sessions field, not only additional top-level fields. Authenticate that value generically and apply the current map and hash contract only after confirming v1, preventing downgrade publication over valid newer state.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (84ed008)

Changes requested: one medium-severity checkpoint compatibility issue was identified.

Medium

  • internal/artifact/export.go:198 — Future-checkpoint detection only runs when no database head exists. After a newer binary records a future-format checkpoint, a downgraded binary with hadHead == true may skip decoding it, reserve a higher sequence, and publish a current-format checkpoint that incorrectly supersedes the future schema.

    Suggested fix: Before creating any changed checkpoint, verify the recorded/latest checkpoint’s format version, or persist that version in checkpoint-head state and reject future versions. Add coverage for a dirty export with an already-recorded future-format head.


Reviewers: 2 done | Synthesis: codex, 7s | Total: 19m25s

A database head can outlive the binary format that recorded it, so sequence state alone cannot authorize a downgraded exporter to publish a successor. Authenticate and decode the exact recorded checkpoint before every construction path while preserving the constant-work unchanged fast path, ensuring newer checkpoint authority remains blocking across retries.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (cbfd781)

Medium-severity checkpoint recovery issue found; no High or Critical findings.

Medium

  • internal/db/artifact_publication.go:391 — Recording or migrating a checkpoint head does not advance artifact_checkpoint_floors. If a legacy head exists at sequence N without a floor and the artifact store is missing or reset, reservations restart at sequence 1. Subsequent exports are rejected until sequence N+1 is reached.
    • Fix: Atomically upsert the floor to at least the recorded head sequence whenever a head is recorded or migrated. Add coverage for legacy-head recovery with an empty artifact store.

Reviewers: 2 done | Synthesis: codex, 7s | Total: 31m48s

Checkpoint heads must remain a lower bound for future reservations even when legacy databases or reset stores lack a separate floor row. Advance the floor in the same transaction as head recording and derive it during startup and resync migration so recovery cannot restart below an authoritative head.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (a8a6aee)

High-severity correctness issue: artifact publication hard-codes the wrong local machine identity.

High

  • Artifact ownership incorrectly assumes machine = 'local'internal/db/db.go:2182, internal/db/db.go:2485, internal/artifact/export.go:138

    Production sync stores cfg.LocalMachineName, which defaults to the hostname. As a result, actual local sessions are neither queued nor included in full exports. If manually queued, they are treated as foreign and their publication is removed.

    Fix: Consistently use the configured local machine identity or a durable explicit ownership marker in triggers, bootstrap/requeue queries, session listing, and export validation. Add coverage for a local session whose machine value is a hostname.


Reviewers: 2 done | Synthesis: codex, 8s | Total: 11m2s

Production sessions are tagged with the configured hostname, so treating only the legacy local marker as owned can silently omit every real session or delete its publication. Persist the runtime identity as archive state and use it across queueing, rebuild recovery, ownership listing, and export validation.\n\nChanging or first recording the identity re-dirties the active origin atomically, allowing existing archives to converge while retaining local as a compatibility alias.
@roborev-ci

roborev-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown

roborev: Combined Review (03aaceb)

No issues found.


Reviewers: 2 done | Synthesis: codex | Total: 13m24s

@wesm
wesm merged commit fa96090 into main Jul 28, 2026
20 checks passed
@wesm
wesm deleted the artifact/2-export-ledger branch July 28, 2026 23:04
cursor Bot pushed a commit to diazMelgarejo/periscope that referenced this pull request Jul 29, 2026
Second PR in the artifact-sync split (follows kenn-io#1242, which froze the wire format and added the docbank-backed store). Extracted from the closed kenn-io#1239 branch with review fixes applied during extraction.

- **SQLite publication ledger** (`internal/db`): `artifact_export_queue`, `artifact_publications`, `artifact_publication_revisions`, `artifact_checkpoint_heads`/`_floors`, plus session triggers that enqueue owned-session changes. Triggers are origin-gated — they fire only once an artifact origin exists in `pg_sync_state` — so archives that never opt in carry no queue writes. Trigger DDL lives in Go and is installed after column migrations (drops run before), so no trigger references session columns while migrations run.
- **Go enqueue hooks** for child-only mutations that don't touch trigger-covered session columns: batch message writes (queue generation sampled around the batch, enqueues exactly once when the triggers didn't fire), standalone usage-event replacement, and token-coverage backfill. Queue bootstrap is an explicit call at origin creation, not a migrate-time backfill.
- **Origin lifecycle** (`internal/artifact`): `EnsureOrigin`/`AdoptOrigin`/`StoredOrigin`. Creating or adopting an origin bootstraps the export queue; a failed bootstrap rolls the origin back (deleting the key when there was none before, since the gates test key existence) so a retry re-runs population. Adopting over a different established origin force-requeues every owned session with a generation bump, because prior acknowledgements belong to the old origin.
- **Checkpointed export pipeline** (`internal/artifact`): claims pending queue rows, publishes content-addressed session manifests and segments into the store, records publication revisions, and advances per-origin checkpoint heads with monotone sequence reservation. Stale claims (a writer advanced the generation mid-export) roll back atomically. Incremental export is bounded by the dirty batch; an unchanged archive costs a catalog identity check only. Full export streams all bodies, then re-checks the queue up to 32 settle rounds — hitting the bound returns the accumulated result with an error meaning "made progress, run again."
- **Resync carriage**: `CopySyncStateFrom` carries queue, publication, revision, and checkpoint state across a full resync and re-dirties every copied queue row — the origin gate keeps triggers silent in the rebuild's temp DB, and a parser bump changes manifest hashes anyway, so the exporter must re-verify each session (unchanged content is cheap to skip, being content-addressed).

- Export-side only. Nothing wires the pipeline to the daemon or CLI yet; that lands with folder transport and import in a later PR. There is no import/read path here.
- The ledger is local SQLite state. PostgreSQL push and shared query shapes are untouched.
- The wire format is unchanged: no golden churn, format stays frozen at v1.

- `internal/db/artifact_publication.go` — queue and ledger SQL, origin-gated enqueue
- `internal/db/db.go` — trigger DDL split around column migrations, bootstrap/requeue
- `internal/artifact/export.go` — publish → manifest → checkpoint ordering and claim lifecycle
- `internal/artifact/origin.go` — origin lifecycle and rollback semantics
- `internal/db/orphaned.go` — resync carriage and the pending-flag decision

Co-authored-by: Wes McKinney <wesm@users.noreply.github.com>
cursor Bot added a commit to diazMelgarejo/periscope that referenced this pull request Jul 29, 2026
…b-f559

feat: upstream PR #23 stack onto purified (kenn-io#1274 DuckDB + kenn-io#1251 artifact + kenn-io#1284 Omnigent)
cursor Bot pushed a commit to diazMelgarejo/periscope that referenced this pull request Jul 29, 2026
Two-parent merge retains all original SHAs from both lines:
- parent1: origin/merged (Periscope fork Layer 2+3)
- parent2: origin/cursor/agentsview-purified-onto-kenn-f559 (kenn-io replay + PR #26)

Tree resolution (oramasys-method / ARCHITECTURE.md matryoshka):
- Base tree: purified (upstream modernization + kenn-io#1274/kenn-io#1251/kenn-io#1284)
- Overlay from merged: internal/summarize, internal/llm, context UI,
  install/release/sync scripts, jetbrains-plugin, ECC bundles, branding docs

No synthetic upstream replay commits. Conflict resolution favors implementation
plan layers; single merge commit minimizes artificial history.

Synthetic pass commits preserved on cursor/agentsview-plus-periscope-synthetic-pass-f559.
ryan-williams added a commit to runsascoded/agentsview that referenced this pull request Jul 31, 2026
Final waypoint of the staged upstream catch-up
(specs/merge-upstream-waypoints.md). Merges the last 14 commits of u/main
through b0b0553 (artifact-ledger reliability kenn-io#1251 follow-ups, duckdb
push-watch fix, settings-page host layout, a kit-ui bump). No deep-rewrite
pivots; a light cleanup pass.

- Frontend: adopt upstream's newer kit-ui pin (97be355e); keep the fork's
  redacted-transcript CSS alongside upstream's new .settings-page-host;
  regenerate package-lock.
- All prior fork features intact (snapshot publish, 1h cache pricing in
  microdollars, subagent rollup, private views, longest-prompts).

The branch `cache-1h-and-projects` is now fully current with upstream.

Green: go build/vet, 41 test packages (artifact + sync both pass this run),
2091 vitest tests, svelte-check, make build. (Environmental: the snapshot
test needing a git `origin` remote.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant