126 · T111 — the submission projection and audit surface - #136
Merged
Merged
Conversation
…face The fold-side scenarios (submitted-with-no-outcome, truncation, positional order, zero-vs-unknown inputs, intent-vs-reality, determinism, and the unchanged artifact document) and the metastore-side ones (live-equals-sync byte identity, idempotent re-sync, in-place upgrade + fresh-store convergence, no foreign keys, the queryable never-completed state, the join to node_attempt, and the four worked audit queries). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… the audit queries `fold_stream` now surfaces `attempt-submitted` records on the `RunArtifact` as `SubmittedAttempt`s — merging the write-ahead record with the additive one that carries the observed identity, and, crucially, surfacing submissions that never produced an attempt-outcome. That case is resolved from the records themselves rather than from the assembled attempt list, which synthesizes coverage rows and would otherwise claim an outcome that never happened. The projection adds two additive, foreign-key-free tables through the existing migration mechanism: `attempt_submitted` (intent and reality in separate columns, `completed`/`outcome_state` carrying submitted-but-never-completed positively, `input_count` keeping zero apart from unknown) and `attempt_submitted_input` (one row per reference, keyed by its declared position). Both are written through the same `build_statements` path, so the live tee and a post-hoc `sync` produce byte-identical rows. `RunArtifact::to_value()` is deliberately untouched: T108's merged additivity guarantee — a stream carrying submission records folds to a byte-identical artifact document — still holds, and the projection reads the folded value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Also folds the `inputs` array read to `Option::cloned`, which is what clippy would have asked for anyway. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`single_match_else` on the merge branch (an `if let … continue` reads better anyway) and `redundant_closure_for_method_calls` in the ordering assertion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Ticket: T111 — docs/implementation/126-T111-submission-projection-and-audit.md
Summary
Projects T108's
attempt-submittedrecords into the run index and ships the auditsurface over them.
fold_streamsurfaces submissions on theRunArtifact— includingsubmissions that never produced an outcome — while staying a deterministic reader with
no store, network, or graph access. An additive
attempt_submittedtable (plus a childattempt_submitted_inputcarrying positional order) lands through the existingmigration mechanism with no foreign keys, produced through the same
build_statementspath so live-tee and
syncrows are byte-identical. Four worked audit queries ship inthe cookbook; no new CLI verb.
Tests-first
Confirmed — failing tests committed first in 555e246.
Definition of done
fold_streamsurfacesattempt-submittedrecords on theRunArtifact, including submissions with no outcome; the fold stays a deterministic reader with no store, network, or graph access.attempt_submittedtable and its indexes land through the existing migration mechanism, with no foreign keys; an existing store upgrades in place and converges with a fresh one.build_statementspath; live-tee andsyncrows are byte-identical andsyncis idempotent.completed=0+ NULLoutcome_state, rather than a tenth state token).dagr-core; the feature stays default-off; a toggle-off run is unchanged; the acceptance-boundary script passes.ubuntu-latestandmacos-latest— pending, confirmed by this PR's CI.GATE=PASS(36 PASS, 1 deliberate SKIP, 0 FAIL), verified on the committed tree, but CI on the PR is the authoritative verdict.Open questions resolved
Both ticket questions plus two in-PR decisions are recorded in the ticket's
## Open questionssection (docs/tasks.mdenumerates M0–M4 only and carries no T111entry):
attempt_submitted_inputtable with a
positioncolumn. Decided against the shipped queries: two of thefour filter on an individual reference, which an encoded column would make
unqueryable.
added.
RunArtifacttype but NOT into_value()— which preservesT108's merged byte-identical-artifact assertion.
completed=0+ NULLoutcome_state, ratherthan introducing a tenth state token into the terminal taxonomy.
Deviations
None.
Notes
Two correctness decisions worth calling out, both about not letting the audit surface
overstate what happened:
attempt list. The assembled list synthesizes coverage rows at try 1, so folding from
it would have claimed an outcome for attempts that never produced one.
assetrow. Submission is intent, andan attempt that never ran consumed nothing.
The four cookbook queries live inside the existing "Querying run state across DAGs" H2,
so
metastore_example_and_docs.rsexecutes them verbatim against a real store (3passed, 123s) and
metastore_docs_claims.rsguards that the surrounding prose staystrue (6 passed).
Boundaries hold: the run index remains a projection, never authoritative for
execution — nothing in the engine reads it back to make a decision. The feature stays
default-off, the metastore keeps no edge onto
dagr-core, and noscripts/check-*.shwas modified — including
check-metastore-acceptance-boundary.sh, which passesunchanged.