feat(craft): outputs reconciler wired into every terminal branch - #14327
Open
nmgarza5 wants to merge 2 commits into
Open
feat(craft): outputs reconciler wired into every terminal branch#14327nmgarza5 wants to merge 2 commits into
nmgarza5 wants to merge 2 commits into
Conversation
Contributor
Greptile SummaryThe PR reconciles sandbox output manifests with persisted artifact rows at terminal turn branches.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains. No blocking failure remains. Important Files Changed
Sequence DiagramsequenceDiagram
participant E as Turn executor
participant S as Sandbox manager
participant R as Output reconciler
participant DB as PostgreSQL
participant C as Cache/SSE
E->>S: get_outputs_manifest()
S-->>E: complete manifest
E->>R: reconcile_session_outputs()
R->>DB: load artifact baseline
R->>DB: upsert changed rows
R->>DB: mark vanished paths deleted
E->>DB: commit
E->>C: announce changed artifacts
C-->>E: merge packets into live stream
Reviews (2): Last reviewed commit: "docs(craft): state the packet rollout an..." | Re-trigger Greptile |
Contributor
Author
This was referenced Aug 27, 2026
nmgarza5
force-pushed
the
nikg/craft-artifact-classifier
branch
from
August 27, 2026 18:56
178110b to
2735d38
Compare
nmgarza5
force-pushed
the
nikg/craft-outputs-reconciler
branch
from
August 27, 2026 18:56
1389886 to
4f3a77f
Compare
Contributor
|
Full-stack Preview (frontend + backend)
|
Diffs the sandbox outputs manifest against the artifact rows at turn end, while the turn still holds its prompt slot, so the next turn never starts against a half-written index. Upserts only rows whose content or type moved, keeping turn_index the turn that last changed each artifact, flags vanished paths in one statement, and announces changed rows over Redis so an attached stream can render artifact packets promptly. Incomplete manifests, truncated or partially unreadable, are never reduced: the rows stay the baseline and the next turn end self-heals. Wired into the interactive executor's owned terminal branches and every owned scheduled-task terminal status, with the docker manifest exec bounded by timeout(1) to match the kubernetes RPC bound.
Clients ignore unknown packet types by design, so the artifact packet ships before its consumer, and the sandbox daemon cannot import onyx.* so its routes raise HTTPException rather than OnyxError. Both were review questions twice over, the code now answers them itself.
nmgarza5
force-pushed
the
nikg/craft-outputs-reconciler
branch
from
August 27, 2026 21:37
4f3a77f to
e1f9523
Compare
nmgarza5
force-pushed
the
nikg/craft-artifact-classifier
branch
from
August 27, 2026 21:37
2735d38 to
7c972f3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Why. Schema (#14319), manifest (#14325), and classifier (#14326) are inert until something runs them at the right moment. The design's requirement is specific: reconcile at turn end, while the turn still holds its prompt slot, so the next turn never starts against a half-written index, and idempotently, so a run skipped by a hard crash self-heals at the next turn end. This PR is that wiring. Stacked on #14326; the diff also carries #14325's commits (the manifest it consumes) until that merges — review this PR's own commits:
outputs_reconciler.py,db/artifact.py,packets.py,session/streaming.py, and both executors.What.
outputs_reconciler.py: fetch the manifest, adapt entries into the classifier, diff derived artifacts against the rows. Upserts only rows whose content or type moved or whose path came back, soturn_indexkeeps naming the turn that last changed each artifact; vanished paths flag deleted in one bulk statement. Incomplete manifests — truncated or partially unreadable — are never reduced, because the delete pass would otherwise flag rows the walk merely failed to see; the rows stay the baseline and the next turn end self-heals.artifactpacket. No shipped client parses the type yet; clients ignore unknown packet types by design and the consumer lands with the output panel frontend.timeout(1)at 30s, matching the kubernetes RPC bound, so a pathological walk cannot hang terminal handling (exec_runhas no timeout of its own).How Has This Been Tested?
test_outputs_reconciler.py, real Postgres + Redis, sandbox stubbed at the manager seam): first reconcile creates rows and packets, unchanged rows stay untouched (turn_index preserved), content change bumps version, vanish/resurrect round-trip without a spurious bump, truncated and partially-unreadable manifests leave rows alone, manifest failures (RuntimeError family and ValidationError) skip cleanly, seeded type drift is corrected, webapp→directory transition bumps, file→directory at one path keeps one row, hidden churn produces zero packets, sessions are isolated, and the announce round-trips in FIFO order.timeout-wrapped exec verified live in the real sandbox image (exit 0, correct JSON,/usr/bin/timeoutpresent and root-owned).Additional Options