Repository navigation
fix(gateway): #440 review follow-up: v2 digest tier and location handling (N20) - #550
Merged
Merged
Conversation
…review AGENT_NAME: implementer-alpha Board N20 follow-up. astra (SHIP-WITH-NITS on PR #440) found that matchedCapabilityDigestV2's assuranceTiers validation checked the array's length, then trusted the iterable protocol (`for...of`) to actually walk it -- a caller-substituted Symbol.iterator can serve fewer, different, or zero entries than the checked length, e.g. an empty generator turns a real `[0]` into a hashed `[]`, or a generator yielding `3` launders a real `[99]` (invalid) into a valid-looking committed tier. 440-A fix: read `.length` exactly once, reject outright if the array's Symbol.iterator has been reassigned away from Array.prototype's built-in one (rather than trying to "see through" a substituted iterator), then walk indices 0..length-1 by `hasOwnProperty` (never the iterable protocol) so a hole must throw instead of being skipped or smuggled. Explicit non-empty check on the resulting set before hashing. 440-B: added pins_v1_preimage_and_digest_to_base_vector -- the existing v1-regression test only checked shape/inequality with v2, so a mutation to v1's price precision could still pass it. Computed the exact preimage bytes and digest from the current (#440-unchanged) v1 implementation and pinned them literally. 440-C: MAX_TIER_ENTRIES (16) and the CSD class/version length caps (64/32) are implementation-side restrictions not stated in N20's quoted text. Per operator directive, kept (not removed) and documented explicitly in a contract comment above the constants, flagged for the spec owner to fold into N20's text. No behavior change. Also added the regression tests astra listed for existing (correct) behavior, pinning it against silent drift: ordinary sparse tier arrays throw, a NaN tier throws, -0 normalizes to 0, an identifier containing a quote/backslash cannot forge a second JSON key (verified via JSON.parse, not just canonicalize's own escaping), and a trailing slash in the CSD url throws while a bare query string is accepted literally. Tests: packages/gateway/src/__tests__/matched-capability-digest-v2.test.ts (15 tests, was 8). Also ran matched-capability-digest.test.ts (11) and agentic-decomposer-digest.test.ts (4) -- all green, no regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tion
AGENT_NAME: implementer-alpha
Board N20 round 2, agreed with the gateway lane (#3603). Two conditions
on matchedCapabilityDigestV2's kernelLocation:
(a) an exact {lat:0,lng:0} counts as NO location -- it is not a real
place any kernel is actually registered at, so it must not silently
commit to the Gulf of Guinea geohash cell ("s00000") as if it were
real.
(b) no location (null, absent, or {0,0}) all encode identically as
`"kernelLocationGeohash6": null` -- never a geohash string, never an
omitted key -- so "we don't know" can never be misread as a real
cell by a consumer that just checks the key is present.
kernelLocation is now optional/nullable in MatchedCapabilitySnapshotV2
(verified no production consumer yet -- this encoder is still unused
per astra's #440 review). A real, non-origin location (including valid
edge cases like {lat:0,lng:45} on the equator) still geohashes normally.
Golden vector: computed the null-location preimage/digest from the
implementation and confirmed it matches the gateway lane's agreed
fixture exactly before pinning it -- 536 bytes,
0xfacd369395f056b2ca426c49fff8706146d0ff4bac212bd5c4990e5b72c71925.
{0,0} and an absent kernelLocation key both produce that identical
digest. The existing 540-byte real-location golden
(0x7558a7e581e369241ac072f29f0b60a4d6d6e1de757180f12fa7750e969d29bf) is
verified unchanged.
Tests: packages/gateway/src/__tests__/matched-capability-digest-v2.test.ts
(18 tests, was 15) -- new describe block covers null/{0,0}/absent parity,
the unchanged 540-byte golden, and the {0,0} vs on-equator boundary.
Also ran matched-capability-digest.test.ts (11) and
agentic-decomposer-digest.test.ts (4) -- all green.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… follow-up, confirmation round) astra's confirmation review of bb742a2 reopened 440-A as a MEDIUM. The tier count check refused only exactly 0, so a Proxy reporting a negative length passed it. The index loop then ran zero times and an empty tier set was committed. bb742a2 had removed the post-loop non-empty check on the premise that the count was already above zero, but the code did not guarantee that premise. Reproduced first: the reviewer's Proxy with length -1 did not throw at bb742a2. The count must now be at least one. That makes the premise hold by construction, so the loop pushes or throws at least once. A test covers lengths -1, -16 and 0. Tests: matched-capability-digest v2 19/19, plus the v1 and decomposer digest tests (34 in all). Mutations: reverting to === 0, and dropping the lower bound, are both killed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0171FftEAfqjwbJHowVTqAbz
LamaSu
marked this pull request as ready for review
October 3, 2026 22:38
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.
What
This follow-up to #440 (N20, merged 9/30) carries astra's #440 review fixes. #440 merged before them, so they need their own PR.
Review
134-composition-440-followup-r2-93cefa96.md, in the steward's PASTE ORDER.🤖 Generated with Claude Code