You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
assessSubnetDocument (src/review/content-lane/registry-logic.ts:546 onward) is the content lane's
document-shape validator for a registry subnet file. Its root-netuid check is:
if(!Number.isInteger(Number(doc.netuid))){returnfail("unsupported-shape","Subnet document netuid must be an integer.");// :555-556}constnetuid=Number(doc.netuid);// normalize once; thread the canonical integer to entry + (future) grounding
Number() coerces before the integer test, so the check passes for values the message promises it
rejects: Number(null) === 0, Number("") === 0, Number([]) === 0, Number(true) === 1, Number([5]) === 5, Number("0x10") === 16, Number(" 7 ") === 7. A document with "netuid": null is therefore accepted as subnet 0.
That fabricated value is load-bearing downstream. assessSurfaceEntry
(src/review/content-lane/registry-logic.ts:500-510) compares each appended surface against it via Number(surface.netuid) !== netuid, and its own comment explicitly relies on the contract the check
above does not enforce ("the document validator already proved the root netuid is an integer"). So a
submission with a null/blank/boolean root netuid and surfaces declaring netuid: 0 (or null, which
also coerces to 0) passes the consistency check and can reach a decisive merge verdict on the
surface lane — which, per src/review/content-lane-wire.ts's applySurfaceGate, can override an
AI-judgment-only generic failure.
Requirements
The root-netuid check must reject any doc.netuid that is not already a JavaScript number which is
an integer — i.e. validate the raw value's type before any coercion, not Number(raw).
A numeric string (e.g. "7") must ALSO be rejected, and the failure summary must stay "Subnet document netuid must be an integer." with reason code "unsupported-shape" (the string
is asserted by existing tests and rendered into the public close comment).
A negative integer must be rejected (a netuid is a non-negative index); 0 must remain valid.
const netuid = Number(doc.netuid) at :558 must become a direct read of the already-validated
number, so no coercion remains on this path.
No change to assessSurfaceEntry's comparison or to any other assessment branch.
⚠️ Required pattern: the type-first shape of the sibling check three lines below — if (!Array.isArray(doc.surfaces)) at src/review/content-lane/registry-logic.ts:559 — which tests
the raw value's type and never coerces. What does NOT satisfy this issue: keeping Number() and
adding a typeof doc.netuid !== "object" style patch on top; accepting numeric strings "for
leniency"; changing the failure summary text or reason code; or adding a new exported validator
helper instead of fixing this branch in place.
Deliverables
assessSubnetDocument in src/review/content-lane/registry-logic.ts returns fail("unsupported-shape", …) for each of null, "", true, [], [5], "7", "0x10", 1.5, -1, and undefined as doc.netuid, asserted by a new table-driven named case in test/unit/content-lane-registry-logic.test.ts.
The same test asserts netuid: 0 and netuid: 64 still produce a non-unsupported-shape
outcome (the check is not over-tightened).
A named regression test asserts a document with "netuid": null and a surface declaring "netuid": 0 no longer reaches a merged verdict — it fails on unsupported-shape.
const netuid at src/review/content-lane/registry-logic.ts:558 no longer calls Number().
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for
example tightening the check (Deliverable 1) while leaving the Number() normalization at :558 in place — does not resolve this issue.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, and vitest.config.ts's coverage.include covers src/**/*.ts — this file is measured. Both arms of the new condition need
tests (valid integer, and each rejected shape). The end-to-end netuid: null + surface netuid: 0
regression test in Deliverable 3 is required by name.
Expected Outcome
A registry subnet document whose root netuid is not a real integer is rejected with the message the
code already prints, instead of being silently normalized to subnet 0 and threaded into the per-surface
consistency check as if it had been validated.
Links & Resources
src/review/content-lane/registry-logic.ts:546-560 (the defect), :500-510 (the downstream consumer)
src/review/content-lane/orchestrator.ts:371-383 (where the assessment becomes the verdict)
Context
assessSubnetDocument(src/review/content-lane/registry-logic.ts:546onward) is the content lane'sdocument-shape validator for a registry subnet file. Its root-netuid check is:
Number()coerces before the integer test, so the check passes for values the message promises itrejects:
Number(null) === 0,Number("") === 0,Number([]) === 0,Number(true) === 1,Number([5]) === 5,Number("0x10") === 16,Number(" 7 ") === 7. A document with"netuid": nullis therefore accepted as subnet 0.That fabricated value is load-bearing downstream.
assessSurfaceEntry(
src/review/content-lane/registry-logic.ts:500-510) compares each appended surface against it viaNumber(surface.netuid) !== netuid, and its own comment explicitly relies on the contract the checkabove does not enforce ("the document validator already proved the root netuid is an integer"). So a
submission with a null/blank/boolean root netuid and surfaces declaring
netuid: 0(ornull, whichalso coerces to 0) passes the consistency check and can reach a decisive
mergeverdict on thesurface lane — which, per
src/review/content-lane-wire.ts'sapplySurfaceGate, can override anAI-judgment-only generic failure.
Requirements
doc.netuidthat is not already a JavaScriptnumberwhich isan integer — i.e. validate the raw value's type before any coercion, not
Number(raw)."7") must ALSO be rejected, and the failure summary must stay"Subnet document netuid must be an integer."with reason code"unsupported-shape"(the stringis asserted by existing tests and rendered into the public close comment).
0must remain valid.const netuid = Number(doc.netuid)at:558must become a direct read of the already-validatednumber, so no coercion remains on this path.
assessSurfaceEntry's comparison or to any other assessment branch.Deliverables
assessSubnetDocumentinsrc/review/content-lane/registry-logic.tsreturnsfail("unsupported-shape", …)for each ofnull,"",true,[],[5],"7","0x10",1.5,-1, andundefinedasdoc.netuid, asserted by a new table-driven named case intest/unit/content-lane-registry-logic.test.ts.netuid: 0andnetuid: 64still produce a non-unsupported-shapeoutcome (the check is not over-tightened).
"netuid": nulland a surface declaring"netuid": 0no longer reaches amergedverdict — it fails onunsupported-shape.const netuidatsrc/review/content-lane/registry-logic.ts:558no longer callsNumber().All Deliverables above are required in a single PR. A PR that satisfies only some of them — for
example tightening the check (Deliverable 1) while leaving the
Number()normalization at:558in place — does not resolve this issue.Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, and
vitest.config.ts'scoverage.includecoverssrc/**/*.ts— this file is measured. Both arms of the new condition needtests (valid integer, and each rejected shape). The end-to-end
netuid: null+surface netuid: 0regression test in Deliverable 3 is required by name.
Expected Outcome
A registry subnet document whose root
netuidis not a real integer is rejected with the message thecode already prints, instead of being silently normalized to subnet 0 and threaded into the per-surface
consistency check as if it had been validated.
Links & Resources
src/review/content-lane/registry-logic.ts:546-560(the defect),:500-510(the downstream consumer)src/review/content-lane/orchestrator.ts:371-383(where the assessment becomes the verdict)test/unit/content-lane-registry-logic.test.ts