{{ message }}
Repository navigation
Conversation
…y/null collision, which defeated sealedFieldsAuthentic's tamper check (evaluated) canon() (packages/flywheel/src/receipts.ts) fell through to JSON.stringify for scalars, which collapses NaN, Infinity, -Infinity, and null to the identical "null" string. Any canon-equality check that exists to prove a live field still matches what was signed — sealedFieldsAuthentic in replay.ts, validAttestation in multigeneration-proof.ts — could not tell "still NaN" from "silently changed to null/Infinity/-Infinity" with no signing key needed. Encodes NaN/Infinity/-Infinity as distinct unquoted literal tokens instead, byte-identical for every other value canon() produces. 60/60 flywheel receipts tests pass (3 fail non-vacuously on baseline); full flywheel suite 146/146, 0 regressions; all 7 real committed ReplayBundle files re-verify PASS unchanged; tsc clean; npm audit clean. Independent adversarial critic: ACCEPT, no blocking caveats. Disclosed, not fixed: packages/avo/src/flywheelGate.ts and packages/turn-credit/src/receipt.ts ship their own separate, still-colliding canon() duplicates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DduZER9F3YMtyJu5TcgL7D
…n row Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DduZER9F3YMtyJu5TcgL7D
Owner
Author
This branch has not been deployed
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.

Closes #422.
Hypothesis
Given a signed
PromotionReceiptor sealed-field-authenticity check (sealedFieldsAuthenticin replay.ts,
validAttestationin multigeneration-proof.ts) that compares a live numericfield against its
canon()-encoded signed counterpart, whencanon()is hardened to encodeNaN,Infinity, and-Infinityas distinct, unambiguous literal tokens (rather thancollapsing them to
nullviaJSON.stringify), then a live field tampered between anon-finite value and
null(or between two non-finite values) is detected, subject tobyte-identical output for every existing finite/string/bool/null/array/object value and 0
regressions on every legitimately-signed existing receipt. Frozen before implementation.
Candidate
packages/flywheel/src/receipts.ts'scanon()fell through toJSON.stringify(v)forscalars.
JSON.stringify(NaN) === JSON.stringify(Infinity) === JSON.stringify(-Infinity) === JSON.stringify(null) === "null"(ECMA-262's own behavior), so any canon-EQUALITY checkinherited a 4-way collision at exactly the values it exists to protect. Fix: encode
NaN/Infinity/-Infinityas distinct unquoted literal tokens before falling through toJSON.stringify— none of those tokens is valid JSON syntax for any string/number/bool/null,so none collides with any other value
canon()produces. 76 insertions / 1 deletion, 2 files(
receipts.ts+ its test file).Evaluation Receipt
git stash -- packages/flywheel/src/receipts.ts): 3/60 new assertions failnon-vacuously — the exact predicted 4-way-collision and the exact predicted false-
"authentic" verdicts on two tampered commits (
primaryDeltaNaN→null,anchorScoreInfinity→NaN, both with no signing key).
@metaharness/flywheelsuite 146/146, 0 regressions.tsc --noEmitclean.ReplayBundle/proof-bundle JSON files in-repo re-verifyACCEPTANCE: PASS, byte-identical (evals-math ×3, radio, darwin-mode/swebench,kimi-k3-harness, experiments/signal-flywheel).
(
avo/__tests__/openrouter-live.test.ts) is a live OpenRouter HTTP 404 on a deprecatedmodel ID, confirmed environmental, unrelated to this diff.
npm audit --omit=dev --audit-level=high: 0 vulnerabilities.Baseline Comparison
See Evaluation Receipt above — baseline (
main, unpatchedcanon()) vs. candidate, sametest file, same real-committed bundles, same downstream suite.
Darwin Lineage
DARWIN=not_applicable— a canonicalization-primitive correctness fix has no tunableparameter space; not one of ADR-071's seven Darwin-eligible mutation surfaces.
Flywheel Evidence
Full OBSERVATION → MEASUREMENT → INFERENCE → HYPOTHESIS → DECISION record:
docs/dream-cycle/2026-10-21-evidence.md.Reward Hack Check
Clear. Diff is additive-only on the test file; no existing assertion/threshold/gold data
weakened, no test skipped, no cost hidden. Independently confirmed by a fresh adversarial
critic (own reproduction, not taken on faith).
Security Review
This candidate is the security hardening itself — closes a tamper-evidence-defeating value
collision in the package's core signed-receipt trust primitive. RFC 8785 (JSON
Canonicalization Scheme) forbids non-finite numbers in canonical JSON for exactly this
reason; the Rust
json-canoncrate documents the identical pitfall independently. Seedocs/dream-cycle/2026-10-21-gist.mdfor the full competitor/citation table.Regression Analysis
0 regressions at every tier measured (package suite, real committed bundles, downstream
11-package sweep,
tsc,npm audit). The 1 downstream failure is a live-networkenvironmental flake in an unrelated file (OpenRouter model deprecation), not caused by this
diff.
ADR
None filed — this is a correctness fix to an existing documented primitive (ADR-274/
ADR-317/ADR-318's canonicalization/receipt model), not a new architectural decision.
Research Gist
docs/dream-cycle/2026-10-21-gist.md— SOTA research, competitor comparison (in-toto/Sigstore, RFC 8785 reference implementations, Darwin Gödel Machine, LangGraph/Microsoft
Agent Framework/CrewAI, K-Veritas), full citations.
Issue
#422
Witness
Merge Policy
Human review required. Do not self-merge. Do not autonomously promote Flywheel state.
Disclosed, not fixed in this PR (future-night candidates):
packages/avo/src/flywheelGate.tsand
packages/turn-credit/src/receipt.tsship their own separate, still-collidingcanon()duplicates;
validate-bundle.ts's fail-closed numeric-domain gate lives only in the CLI path,not in
verifyReplayBundle/verifyMultiGenerationEvidencethemselves.Generated by Claude Code