Skip to content

Improve packet evidence selection quality - #1926

Merged
TheGreenCedar merged 13 commits into
dev/codestory-nextfrom
codex/accuracy-probe-probable-context
Aug 18, 2026
Merged

Improve packet evidence selection quality#1926
TheGreenCedar merged 13 commits into
dev/codestory-nextfrom
codex/accuracy-probe-probable-context

Conversation

@TheGreenCedar

Copy link
Copy Markdown
Owner

Status

Draft quality lane based on the proven 0.17.0 checkpoint now on dev/codestory-next. The branch currently contains four accepted bounded improvements; obligation-aware proof/selection work remains in research and is not yet implemented.

Current source

  • branch head: ccebbe622decb84b20b5c04dd66a26ed4f9a150e
  • release checkpoint ancestor: 37c437607ec1ac77396770118a58c3235df3cc83
  • dev checkpoint merge: 8173044227c012b95a5d409037f14a5e27826ca8

Already on this branch

  • preserve proven connected flow carriers
  • bound concurrent retrieval fanout
  • preserve adaptive owner identities
  • tighten packet retrieval anchors

Next architecture

Move semantic proof authority from name-shaped citation predicates to typed proof atoms over verified source aspects and typed graph receipts. Retrieval queries remain provenance only. Reuse existing retrieval, graph, source-read, cap, drill, and fail-closed machinery.

Do not add repository vocabulary, prompt-token proof heuristics, quoted-path reconstruction, global top-k/ranking changes, or embedding changes.

Gate

Direct exact-binary packets must pass Monolog, AutoMapper, Animate, and the Jekyll guard before any exact-agent A/B. Reuse unchanged baseline rows. Commit only a candidate that improves the affected exact-agent shard without a material latency or reliability regression.

Closes #1925
Refs #1179

@TheGreenCedar

Copy link
Copy Markdown
Owner Author

Checkpoint: stage-0 proof-formula contract accepted (head unchanged at ccebbe62 — design phase, no code yet).

The typed-proof implementation now has an adversarially reviewed design contract: autoresearch.research/obligation-evidence-selector/2026-08-17-stage0-proof-formulas.md (revision 5, untracked research artifact). Five review rounds; the final pass confirmed every atom's discharge inputs trace to receipt fields that exist or to named deltas at verified seams. Key properties: all cross-receipt joins are node-identity joins (segment values demoted to single-receipt classification), containment never reads prompt-chosen window extents, certainty is attributed per edge kind to the component that actually sets it, and the vocabulary-gate demotion (R1) is specified at all five function sites where it is load-bearing plus one stated exemption.

Notable contract decisions vs. the original handoff sketch:

  • PHP construction receipts (syntax:php-new constructor CALLs) are required, not optional — logger_event is not provable by source reread alone.
  • The candidate-resolution boundary gets an identity-only re-prioritizable admission queue (R6) — resolution budget preserved exactly, base order demoted to default; this is where the passive ledger measured the CSS evidence dying (ranks 71/338 vs a ≤50 window).
  • The CSS base stylesheet is characterized structurally (selector uses the vars-file's custom property AND has no keyframe-binding USAGE, truncation-guarded) — verified against the real animate tree that this uniquely selects _base.css against all six var-using sibling files.

Implementation started: stage 1 (pure proof-atom module in codestory-agent) and stage 3a (PHP producer: scope primitive, PHPDoc reader, foreach dispatch, construction) are in flight as isolated lanes. Next proof target: stage-1 module green + F1 adversarial review, then receipt plumbing (stage 2) with the Jekyll-only direct-packet gate.

🤖 Generated with Claude Code

TheGreenCedar and others added 2 commits August 17, 2026 14:25
Typed obligation proof foundation (stage 1 of the obligation-aware
evidence selector): a leaf module in codestory-agent holding the
proof-atom concepts, the three shard formula groups, and a pure
deterministic bounded role-unification matcher. Discharge inputs are
verified source-aspect receipts and typed graph receipts only; all
cross-receipt joins are node-identity joins; certainty gates are
attributed per edge kind; absence facts require untruncated covering
scans with traversal-kind evidence; coverage defaults to unknown and
fails closed. Per-requirement verdicts run under one group-wide role
assignment with fail-closed guards for non-self-standing subsets.

Registered in the agent planning module allowlist with a leaf-ness
assertion; no behavior change (nothing consumes the module yet).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 2 of the obligation-aware evidence selector: flow requirements
carry a proof spec (six shard requirements on the typed formula groups,
everything else explicitly Legacy), and both production finalize sites
build their receipt view through one shared filter that admits a strict
subset of what evidence compilation retains. Formula-bearing
requirements derive proof status exclusively from the proof-atom
matcher; the name-token vocabulary path neither proves nor selects a
public status for them, and remains authoritative for Legacy
requirements bit-for-bit. After evidence compilation a reconciliation
pass re-verifies formula-proven obligations against the compiled
survivors and demotes fail-closed, then recompiles once — sufficient
because support compilation never reads the plan and is idempotent on
its own output, both pinned by tests. Pre-cap preview and capture
receive an explicit anchorless view, so anchor-requiring atoms cannot
discharge before atom-anchored verification exists. Proof verdicts are
exported only through the env-gated step trace, with matcher aborts
distinguishable from honest unproven verdicts.

Jekyll guard verified: disposition supported with both site obligations
proven through the Legacy path on the exact benchmark prompt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TheGreenCedar

Copy link
Copy Markdown
Owner Author

Checkpoint: stages 1–2 landed — head e4e9ea06.

  • 00e12870 adds the pure proof-atom model and matcher (leaf module in codestory-agent, 43 tests, leaf-ness asserted by the architecture contracts). CI fully green including both full-agent-suite lanes.
  • e4e9ea06 threads verified receipts through both obligation-finalization sites with one shared strict-subset filter, routes the six shard requirements to the matcher (everything else explicitly Legacy, bit-identical), adds the post-compile fail-closed reconciliation (single recompile, sufficiency proven by idempotence + plan-independence tests), and keeps proof verdicts in the env-gated step trace only.

Both stages passed adversarial review (F1: two rounds — an unsound absence-scan arm and a per-requirement API gap fixed; F2: one round — a name-token predicate could still select the public status level on the non-Proved path, now always Unsupported). Jekyll guard verified on the exact benchmark prompt: disposition supported, both site obligations proven via Legacy. Expected transitional state: the three affected-shard packets fail closed under honest proof authority until the producers (stage 3, in review: PHP accepted with the Monolog oracle exact; C# in round 2 after the AutoMapper oracle exposed primary-constructor/chained-call/csproj-using gaps) and the admission/protection deltas (stage 4) land.

Process note for future gates: the harness exits 0 even when cache prep fails — verdicts are read from rows and direct packet inspection, never exit codes; and the embedded-model build uses CODESTORY_EMBED_MODEL_SOURCE via scripts/prepare-embedded-model.mjs (the handoff's --features embedded-model flag does not exist).

🤖 Generated with Claude Code

Stage 3 of the obligation-aware evidence selector, three producer waves
verified against their real-target indexes:

PHP: a scope-visibility primitive, a PHPDoc list<T>/T[] element-type
reader, foreach element binding through the manual receiver-call engine
(one combined loop-element marker carrying the exact foreach range so
iteration and callsite containment are same-receipt facts), and
constructor call receipts from object-creation sites with same-namespace
resolution. The marker registry becomes a list-valued family table.

C#: a manual type-usage channel gated on binding tables and stamped
certain producer-side (pending edges finalize against unique same-root
declarations before the index publishes; uncertain edges never
discharge), primary-constructor parameter types, constructor-body and
chained-creation receiver calls with class-anchored sources, and a
same-root-namespace declaration arm in call resolution.

CSS: the structural collector reparses with comment/string blanking;
import statements become MODULE nodes with real spans and file-to-file
IMPORT edges resolved to canonical file identities; custom properties
mint only at declarations; selectors only in selector position;
keyframes become FUNCTION nodes; selector-to-keyframe and
selector-to-custom-property usages resolve across the bidirectional
import-graph component with ambiguity failing closed.

All producers fail closed on hostile shapes; unrelated-edge counts are
invariant against unpatched baseline indexes on the reference targets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TheGreenCedar

Copy link
Copy Markdown
Owner Author

Checkpoint: stage 3 producer wave landed — head cae0114d (30 files, +6658/−991).

Three language producers, each accepted only after its real-target index oracle matched exactly (fixture suites alone were provably insufficient — every wave failed its first oracle on a shape the fixtures missed, and the misses were all general-language semantics, not benchmark tuning):

  • PHP (Monolog oracle): the dispatch edge at Logger.php:391 reproduces the run-6 reference (certain, receiver-owner + receiver-binding:loop-element@369-399 with the callsite inside the range); constructions resolve to __construct including multi-line named-argument, nested, and same-namespace-unqualified shapes (first-oracle miss). Unrelated-edge counts invariant vs an unpatched baseline; certain construction receipts 79→479 after the same-namespace arm.
  • C# (AutoMapper oracle): TypeMapPlanBuilder→TypeMap TYPE_USAGE certain from a C#12 primary-constructor parameter on a ref struct, and the execution-plan handoff CALL at TypeMap.cs:282 (chained call on an object creation in an expression-bodied method) resolves certain — both first-oracle misses, plus csproj-level <Using> directives handled via an engine-side same-root-namespace unique-declaration arm (ambiguity fails closed). TYPE_USAGE certainty is established producer-side (emit or pre-publication finalize; pending/uncertain edges never discharge — contract adjudication recorded).
  • CSS (animate oracle): import statements are MODULE nodes with file-to-file IMPORT edges resolved to canonical file identities (99/99 on the entrypoint); keyframes are FUNCTION nodes with certain selector linkage; custom properties mint only at declarations (repo-wide VARIABLE count 15, down from noise); and the C3 discriminator is exact on the real tree (base selectors: zero keyframe usages; all six impostor files: nonzero). First-oracle miss: var() resolution needed the bidirectional import-graph component (sibling sheets under a shared importer), not the downstream closure.

Review trail in .agent/review-003/004/006.md. Next: stage 4 (admission queue, hydration/protection/anchored-verification deltas, bounded selection) is implementing; the full four-packet direct gate and F3 adversarial review follow before its commit.

🤖 Generated with Claude Code

@TheGreenCedar

Copy link
Copy Markdown
Owner Author

Decision point after gate round 6 — full picture and a recommendation

Committed and green: 00e12870 (proof-atom model + matcher), e4e9ea06 (receipt plumbing through both finalize sites), cae0114d (three language producers). Each passed adversarial review and its own gate; all CI lanes green; main untouched.

Uncommitted: stage 4 (admission, retention, protection, anchored verification, selection) — ~2,000 production lines, nine files, independently verified at runtime 909 / agent 307 / contracts 44, F3-reviewed with its blocker fixed.

Gate status (four-packet direct gate):

  • php-monolog-record-flow PASS, stable — the shard three prior candidates died on now proves end to end from real typed receipts.
  • ruby-jekyll-site-build PASS, stable — the all-Legacy guard, provably untouched.
  • csharp-automapper-map-flow FAIL (files 0.25, claims 1.0) — mapper_config proves for the first time ever, but on a generic binding; the true TypeMapPlanBuilderTypeMap chain (edge verified present in the index) never gets admitted.
  • css-animate-base-and-keyframes FAIL (files 0.6 — that leg passes; symbols 0.5 vs 0.55) — the C chain works and cites entrypoint + _vars.css + _base.css; it cites fadeIn.css where the manifest expects bounce.css/flash.css.

Six rounds eliminated, in order: trail fan-out burning the retrieval stage clock; per-query promotion state with no cross-query bootstrap; unfiltered promotion mass-displacing base evidence; need-set flooding from generic membership/usage patterns; three environmental cache-provenance traps that made rounds 1–4's A/C numbers invalid measurements (documented in .agent/acceptance-protocol.md); and a store-accessor zero-retention pathology. All real, all fixed or documented.

What remains is formula discrimination, not a bug. Admission priority by atom-role multiplicity is in flight and should close AutoMapper. For Animate, C4 treats every animation source as interchangeable while the manifest expects two specific ones — admission cannot fix what the formula accepts, and I deliberately declined to add an import-order preference to make the benchmark's two files win; that would be fitting the benchmark.

Recommendation: commit stage 4 to keep the reviewed work safe, keep this PR draft, and take the C-formula expressiveness question to a scoped contract review rather than a seventh admission round. Full analysis with options in .agent/DECISION-POINT.md.

The exact-agent A/B has NOT been run and will not be until all four packets pass — that gate is exactly why three prior candidates produced worthless numbers.

🤖 Generated with Claude Code

Stage 4 of the obligation-aware evidence selector, plus a matcher
correctness fix.

Admission: candidate resolution becomes a re-prioritizable queue whose
promotion is gated on identities a still-unproven material atom needs,
restricted to the cross-container kinds whose endpoints name
retrieval-underranked containers, bounded by atom-derived per-role
slots, and prioritized by how many role positions an identity fills.
Identities accumulate across a packet's queries so a chain can bootstrap
from the one container that ranks naturally. Retention hydrates
atom-required edge kinds off the retrieval stage clock, over retained
candidates, recording per-trail coverage whose enumerated set is
narrowed to what its own absence claim needs. Protection reserves the
carriers and edges partially matched atoms require, verification anchors
its windows at receipt-carried lines, and the public typed-support
allow-list carries the kinds atoms discharge.

Matcher: when a requirement group cannot prove as a whole, its
requirements are now attempted most-constrained-first rather than in
declaration order, so a weakly constrained requirement can no longer
capture a shared role and force its stronger sibling onto wrong
bindings.

Gate status, honestly: the Monolog and Jekyll packets pass the direct
gate; the AutoMapper and Animate packets do not. Their remaining loss is
downstream of admission — both AutoMapper endpoints are admitted and
resolved, then dropped by the citation cap while a weaker binding holds
the protection. No agent A/B has been run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@TheGreenCedar

Copy link
Copy Markdown
Owner Author

Stage 4 landed as 003a110e — with an honest gate statement, and iteration stopped at 8 rounds

Committed (draft PR only; main untouched, no release path): admission queue with atom-need-gated, cross-container-restricted, slot-bounded, multiplicity-prioritized promotion; off-stage-clock retention with narrowed coverage sets; atom-driven protection; anchored verification; selection. Plus a genuine matcher correctness fix: when a requirement group cannot prove as a whole, requirements are now attempted most-constrained-first rather than in declaration order, so a weakly constrained requirement can no longer capture a shared role and force its stronger sibling onto wrong bindings. Verified independently: agent --lib 312, runtime --lib 912, architecture contracts 44, fmt/diff clean.

Gate status: php-monolog-record-flow and ruby-jekyll-site-build pass, stably, across every round. csharp-automapper-map-flow (files 0.25) and css-animate-base-and-keyframes (files 0.6, symbols 0.5 vs 0.55) do not.

Why I stopped at round 8: gates 6, 7 and 8 produced byte-identical quality numbers under three genuinely different fixes. That invariance is itself the finding — the remaining loss is not in the seam I kept adjusting.

The residual is now named precisely. Trace on the final binary: AutoMapper.TypeMap and AutoMapper.Execution.TypeMapPlanBuilder are both admitted and resolved — six rounds of admission work do deliver the true chain — but neither is cited, and citations appears in the packet's omitted_sections: the citation cap drops them. Meanwhile mapper_config proves on a weaker binding and holds the protection that should have reserved the true chain, and mapper_execution cannot prove because its CALL+MEMBER receipts aren't retained for late-admitted candidates (MEMBER trails run post-pass — i.e. after the citation cap has already selected).

Next seam, concretely: (1) retain an atom's required typed edges for candidates admitted late in the pass, and (2) make partial-atom protection follow the strongest available binding rather than whichever requirement proved first.

What I deliberately did not do: add an import-order or file-position preference to make Animate's two expected files win. C4 accepts any imported keyframe-bearing source; the manifest expects two specific ones. That is a formula-expressiveness question for contract review — tuning admission around it would fit the benchmark and poison the acceptance signal.

No agent A/B has been run and none should be until all four packets pass. Full analysis: .agent/DECISION-POINT.md; round-by-round forensics: .agent/review-008.md; environmental trap checklist for acceptance: .agent/acceptance-protocol.md.

🤖 Generated with Claude Code

Atom-needed evidence had to survive four successive bounded selections
and only the first knew about it. Three of the four are fixed here, and
one of them is a plain defect with no relation to typed proof.

A deadline-cancelled sidecar batch query discarded every hit it had
already resolved, while the single-query path deliberately serves them.
On one benchmark repository that asymmetry threw away 327 resolved hits
before scoring or ranking could see them. The batch path now retains
them in resolution order, still marked retryable, matching the sibling
path's long-standing semantics; proof-atom need only breaks ties among
equal ranks, so packets carrying no formulas keep their previous hits
exactly.

The citation carry and the graph-edge cap now rank atom-required
evidence ahead of unrelated evidence within their existing limits,
instead of letting lexicographic edge ids decide which receipts survive.
The byte trimmer chooses a non-atom edge to shave when one exists but
never treats atom edges as protected, so it can always still trim and
the output-byte ceiling holds. Post-pass hydration walks roots in need
order and skips what it cannot afford rather than stopping at the first
unaffordable one.

Measured over three repeats per packet: the Monolog and Jekyll packets
pass, unchanged. The AutoMapper packet is now stable where it was
swinging run to run, and its file recall doubled. Its remaining gap and
the Animate packet's are single-leg and both trace to formula
discrimination, not to selection: many equally admissible identities
compete for the same slots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@TheGreenCedar

Copy link
Copy Markdown
Owner Author

eb6a82de — three of four bounded selections fixed, and one plain defect found along the way

I was wrong to stop at round 8. Pushing further found the actual mechanism, and it turned out to be four successive bounded selections where atom-needed evidence had to survive and only the first knew about it.

The defect worth flagging on its own merits, unrelated to typed proof: a deadline-cancelled sidecar batch query discarded every hit it had already resolved — 327 of them on AutoMapper — while the single-query path (sidecar_primary_result_rejection_reason) deliberately serves resolved hits from a cancelled query. That asymmetry costs real retrieval work on any deadline-pressured packet in the product. The batch path now matches its sibling: hits retained in resolution order, still retryable, with atom need only breaking ties among equal ranks — so packets carrying no formulas keep their previous hits exactly.

Also fixed: the citation carry and graph-edge cap now rank atom-required evidence ahead of unrelated evidence within existing limits (previously lexicographic edge ids decided which receipts survived); the byte trimmer shaves a non-atom edge when one exists but never treats atom edges as protected, so it can always still trim and max_output_bytes holds; post-pass hydration walks roots in need order and skips what it can't afford instead of stopping at the first unaffordable one.

Gate 10, three repeats per packet (the implementer caught that this shard is unstable run-to-run, so single-run comparisons were sampling noise):

packet files symbols verdict
ruby-jekyll-site-build 1.000 ×3 pass ×3
php-monolog-record-flow 1.000 ×3 0.833 pass ×3
csharp-automapper-map-flow 0.500 ×3 0.667 ✓ fails only file recall (0.60)
css-animate-base-and-keyframes 0.600 ✓ ×3 0.500 fails only symbol recall (0.55)

The generalized retention also stabilized AutoMapper — it was swinging 3/4, 2/4, 2/4 on identical code and is now flat, with file recall doubled from gate 8.

Baseline check: a stage-3-only binary built in an isolated worktree also cancels 32/32 AutoMapper sidecar queries, so the cancellation storm is pre-existing product behaviour, not something this work introduced.

Both remaining gaps are single-leg and both are formula discrimination, not selection: 294 equally-admissible TYPE_USAGE identities compete for 16 file slots (atom-role multiplicity measurably does not separate them — both retention orders gave identical recall), and C4 accepts any imported keyframe-bearing source where the manifest expects two specific ones. I attempted neither A1 discrimination nor any file-position/import-order tiebreak; inventing one that happens to select the benchmark's expected files would be fitting, not fixing.

Record: .agent/review-008.md (round-by-round), .agent/DECISION-POINT.md, .agent/acceptance-protocol.md.

🤖 Generated with Claude Code

TheGreenCedar and others added 4 commits August 18, 2026 09:01
The generalization lint guards production paths against benchmark-family
vocabulary, and two comments added with the selection fixes tripped it:
one named holdout repository types while explaining which candidates the
citation carry had dropped, and one spelled a method call that matches a
compact benchmark marker. Both are reworded to describe the shape rather
than the example.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The draft source-check lane lints workspace libraries with warnings
denied, and three lints introduced across the typed-proof stages had
gone unverified locally: a collapsible if in the proof-atom role
recorder, two double-negated snippet predicates that read better as
is_none_or, and a needless lifetime pair on the C# caller-namespace
helper. Behaviour is unchanged; the predicates are the same function
written positively.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The mapping formula accepted any certain type-usage pair, so on a large
index it proved its configuration step against an arbitrary pair while
the chain the question was about went unproven and unprotected. A plan
builder is a type whose methods get called, so the builder role now also
requires a member method. Measured over nine runs on the same index, the
step stops proving on an arbitrary pair entirely; the packet's graphs
still carry no membership edges for the real chain, which is what leaves
the execution step unproven and is recorded as the next lever.

The release notes carried a claim the product does not implement:
bookmarks have no export or import command. That sentence is replaced by
what actually protects them — the annotation sidecar beside the index —
and by the recovery a downgraded install needs, which is named, scoped
to a 0.17 binary, and given its own section alongside the two other new
repair commands. The notes also now describe the packet changes as
mechanism rather than as a comparative quality claim, since answer
quality and performance are declared unclaimed for this release, and
they carry the release's largest user-visible fix: non-interactive MCP
hosts silently cancelled nineteen of twenty tools.

The user-facing trust and expectation guides no longer describe packet
statuses this release deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four holdout tasks rerun against 0.17 on 2026-08-18, one repeat each,
with the no-CodeStory arm reused from the pinned baseline so both arms
answer the same prompts on the same checkouts.

Two of the four CodeStory answers fail the manifest quality checks, so
the run is reported as a scoped measurement rather than as a release
claim, and both regressions are shown alongside the wins. Where the
packet proved the flow the question asked about, the agent reached the
same verified answer with about 85 percent fewer tokens and one tool
call instead of eighteen or thirty-five. Where it could not, it returned
a bounded follow-up instead of an unsupported answer, and the agent paid
for reading the repository itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@TheGreenCedar
TheGreenCedar marked this pull request as ready for review August 18, 2026 14:08
@TheGreenCedar
TheGreenCedar merged commit 8b8ff8e into dev/codestory-next Aug 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant