Zero annotation touchee, trois citations reparees sur 94 - Scope, BaseType et le compte de membres de NG - et la refutation de where/orderBy/pageSize retiree des deux feuilles.
14 KiB
id, title, parent, depends_on, created, claimed_by, claimed_at, blocked
| id | title | parent | depends_on | created | claimed_by | claimed_at | blocked | |
|---|---|---|---|---|---|---|---|---|
| T01.k | A provenance citation must say which version it describes | T01 |
|
2026-09-21 | worker-T01.k | 2026-09-24 | false |
Description
The provenance mechanism cites a source tree that is THREE RELEASES BEHIND what this repo compiles against, and nothing in an annotation says so. A citation therefore proves "this was true at orm alpha.18", while a reader takes it for "this is true of what we build against".
The established facts - VERIFIED, do not re-derive
Scanning every remote branch of /home/sylvain/projects/nextgraph/nextgraph-rs:
| source | @ng-org/orm version |
|---|---|
upstream/main (the real upstream) |
0.1.2-alpha.18 |
origin/main (a fork) |
0.1.2-alpha.15 |
local checkout HEAD 213338f6 |
0.1.2-alpha.18 |
| what this repo compiles against | 0.1.2-alpha.21 |
So the local checkout is ALREADY at the newest source that exists anywhere reachable. alpha.19, 20 and 21 are published to npm from source that is in no branch of that repository. There is nothing to re-anchor to, and updating the checkout is not the answer. Do not spend time looking for a newer tree; that question is closed.
grep -rho "ref=[^ ]*" packages/polyfill/src/ | grep -cE "engine/|sdk/" counts 96 citations into that tree.
The second-order trap, which has already fired
A claim about alpha.21 REFUTED by reading the pinned tree is refuted against alpha.18 - which is not the same statement. This happened during T01.h: the agent first wrote that alpha.21's where/orderBy/pageSize "became reachable", then retracted it because the pinned engine still has start_orm as json!({}) behind a TODO. The retraction may be right, but the EVIDENCE does not support it at the strength claimed, because the pinned engine is not alpha.21. Re-examine that specific correction in .project/concepts/app-contract/knowledge_what-the-orm-writes-and-deletes-upstream.md and state what can honestly be said about it. A true citation attached to a claim it does not support is the exact failure .project/rules/nextgraph/surface-mirrors-the-sdk.md names.
What to establish - the design is yours
The question is where the version belongs, and the obvious economy is worth weighing before anything else: the version is a property of the CHECKOUT, not of each citation. 96 annotations do not each need to carry it; one place that says "citations into engine/ and sdk/ are anchored at 213338f6 = orm alpha.18, while the build is alpha.21" may carry the whole fact. Weigh that against the alternative, do not assume it.
Then decide what the mechanism should ENFORCE, if anything. packages/polyfill/test/provenance.test.ts already checks that a ref resolves when the sibling checkout is present, and deliberately does NOT check that a claim is true. Adding a version check is a real option; so is deciding that this is doctrine, not a test. Read .project/rules/nextgraph/no-divergence-from-nextgraph.md for the taxonomy before proposing anything, and remember announced-not-written already exists for "the target is stated but the tree carries nothing" - part of this gap may be the same shape.
Do NOT mass-rewrite 96 annotations unless you have established that the fact cannot be carried in one place. A 96-site sweep is a large, risky, low-information change, and this repo's doctrine is explicitly that a good repair usually leaves a leaf SHORTER.
Where a citation genuinely describes something that alpha.21 changed, that is a real finding: record it. But establish it from the published package's own shipped types (node_modules/@ng-org/orm), not by guessing - and say plainly when the shipped artifact cannot settle the question, which it often will not since it carries types, not behaviour.
Verification
Hard gate: bun test -> 0 fail; bunx tsc --noEmit -p packages/polyfill/tsconfig.json -> exit 0; bunx tsc --noEmit -p packages/polyfill/e2e/tsconfig.json -> exit 0; python3 ~/.claude/skills/concept/lint.py -> 0 ERROR. Anti-cheat: no any, no @ts-ignore, no deleted or skipped test, no weakened assertion.
An adversarial review is part of this task. Angles: a citation that still claims more than its anchor supports; a version statement that is itself already stale; and whether whatever is added would survive the checkout moving. A finding counts only with a concrete scenario.
Progress
Result
Status: done
1. Where the version now lives, and why not on each citation
In one place: the ANCHOR in packages/polyfill/test/provenance.test.ts, beside the resolver that opens the checkout. Annotations touched: 0 of 94. (The task file says 96; the same grep it prescribes returns 94 today, so the figure had drifted by 2 - VERIFIED, flagged here rather than silently reused.)
The economy holds, and it is stronger than "one fact stated 94 times". What a reader needs is not a version but the gap, and a gap has two ends. A per-citation version would record only the near end, would be wrong at all 94 sites at once the day the checkout moves, and would still leave the far end - the installed releases - unstated. The anchor records four rows, (package, cited, built), and three tests check them:
| check | scope | behaviour when it cannot ask |
|---|---|---|
| the checkout declares the cited versions | 4 rows | passes empty-handed, like deadCitations |
| every workspace manifest pins the built versions | discovered from packages/*, examples/* |
never absent |
packages/polyfill/node_modules resolves the built versions |
4 rows | never absent |
Each was mutation-tested: falsifying cited -> "@ng-org/orm - the checkout declares 0.1.2-alpha.18, the anchor says 0.1.2-alpha.19"; falsifying built -> two manifest lines plus the installed-tree line; renaming a row to a package nothing pins -> "the anchor names it, no workspace manifest pins it". With NEXTGRAPH_RS=/nonexistent-checkout the suite is 10 pass / 0 fail. So it survives the checkout moving, by going red with the repair named.
A source-side pointer sits in src/index.ts's provenance block (no numbers - numbers live in one place), and the doctrine sits in .project/rules/nextgraph/no-divergence-from-nextgraph.md.
2. What the mechanism enforces, and what it deliberately does not
It enforces that the gap statement is still true at both ends - the same class of check the file already made (a citation still resolves), never the class it refuses (a claim is true).
It is NOT a new kind. The taxonomy classifies what evidence ONE symbol has; how old ALL the evidence is belongs to the tree. announced-not-written is a different shape: there the tree carries nothing, here it carries an older something. A kind would have pushed a checkout-wide property onto 94 per-symbol labels.
It does not check the commit hash. 213338f6 is recorded as a git show pointer and explicitly labelled not the enforced identity: a checkout at another commit declaring the same releases describes the same code, and going red for a local commit is the red that teaches people to skip the suite.
3. where / orderBy / pageSize - what can honestly be said
The retraction is refuted, and the original claim was closer to right than the retraction. All VERIFIED, each from the artifact that can answer it:
- Level 3:
@ng-org/orm@0.1.2-alpha.21,dist/connector/RdfOrmSubscription.jscallsng.orm_start_graph(options.graphs, options.subjects, shapeType, session.session_id, options, this.onBackendMessage)- the config is sent, at index 4. - Level 2:
@ng-org/web@0.1.2-alpha.14,dist/index.d.tsdeclaresorm_start_graph(graph_scope, subject_scope, shapeType, session_id, config, callback)- six parameters, the config is accepted. The pinned tree'ssdk/js/lib-wasm/src/lib.rsdeclares five, no config slot, which proves by arity that the pinned tree is older than the binding in this build. A claim about alpha.21 cannot be refuted there. - Level 1, at
213338f6:OrmConfig(engine/net/src/orm.rs) declareswhere_,order_by,select,page_size,max_active_pages;from_jsonparses all five and refuses apageSize > 0without anorderBy; and every field is consumed -schema_shape_to_sparqlemitsFILTER(|lt/|gt),ORDER BY,LIMIT,OFFSET, andinitialize.rsdrives the paging window and page eviction. Thejson!({})is at the entry point only:start_ormtakes no config argument,request_processor.rscalls it with three, andfrom_json's own TODO names the missing hop - "Use json in libwasm context" - which is exactly the binding parameter the shipped binding now has.
So "the richness is expressible at level 3 and discarded at level 1" / "no caller can reach any of it" was false at the pinned commit too, and it is inference from an absent implementation, which this repo's own rule forbids. Not settled by anything reachable: whether the engine behind that binding feeds the JSON to from_json. The shipped wasm carries no source; only a live measurement answers it, and none has been made. (INFERRED corroboration, not proof: T01.h's live finding that the deployed orm_start_graph already took a config at index 4.)
Both leaves now say this. knowledge_what-a-read-scope-is-upstream.md owns the detail (+10 net lines, 78 lines total, still under the oversize threshold) and knowledge_what-the-orm-writes-and-deletes-upstream.md got shorter (-0 lines, the paragraph shortened and delegates).
4. Citations the installed releases actually invalidated: three of 94
Established from the shipped artifacts, never guessed. Unaffected and verified identical on both sides: the eleven level-2 citations (doc_subscribe, sparql_update, sparql_query, doc_create), plus ShapeType, Schema, DeepSignalSet.
Scope- the cited revision declaresgraphs?OPTIONAL;@ng-org/orm@0.1.2-alpha.21makes it required, andindex.tsre-exports the installed one. No version note, unlike its neighboursRdfOrmConfigandOrmSubscriptionHandle, which already carried one. Repaired in that same established form.BaseType- the cited revision keeps"@graph"commented out behind a TODO;@ng-org/shex-orm@0.1.2-alpha.9declares it. This one matters: the writes leaf documents that an insert must carry@graph, and a reader checking the citation would find the type does not declare it.NG- the member count. The annotation and eight other places said 88 members. The installed@ng-org/web@0.1.2-alpha.14declares 90 in itsNGModulenamespace (84 functions + 6 RDF classes), and two of the ninety -graph_orm_next_page,graph_orm_previous_page- appear 0 times in the cited checkout'slib-wasm/src/lib.rs. Worst instance:docs/api-contract.mdcarried the 88 under a VERIFIED label, with the stale line rangeindex.d.ts:136-231(the namespace is at 157 now), one paragraph after saying "MEASURED against@ng-org/web@0.1.2-alpha.14". Repaired by naming the count ONCE with its release (insurface/ng-proxy.ts, where the type lives) and deleting it from the other eight, where the sentence said "all N members" and N added nothing but an occasion to rot. That leaves the claims shorter. INFERRED, not asserted anywhere: that 88 was alpha.13's count - alpha.13 is not on disk, so the text says only that the recorded figure was two short.
No engine/ citation carries a quantitative claim of that kind (checked); engine/ has no published version at all, and the anchor now says so rather than letting a reader think it can refute a release by opening it.
5. The gate, verbatim
bun test->465 pass,0 fail,1316 expect() calls,Ran 465 tests across 40 files.Baseline before any change was462 pass / 0 failacross 40 files - exactly the figure this task's caller measured, so no discrepancy to flag there. +3 is the three anchor checks.pnpm exec tsc --noEmit -p packages/polyfill/tsconfig.json->exit=0pnpm exec tsc --noEmit -p packages/polyfill/e2e/tsconfig.json->exit=0python3 ~/.claude/skills/concept/lint.py-> 0 ERROR; warnings identical to baseline (3 oversized leaves, 2 open_debt.md, 1 unlistedusage_, 5 banned aliases), none added.
No any, no @ts-ignore, no test deleted, skipped or weakened. No citation was made to look right by changing what it claims.
6. Surprises
- VERIFIED - the gap is four packages wide, not one. The task frames it as orm alpha.18 vs alpha.21. In fact all four installed
@ng-orgpackages are ahead of the checkout: orm 18->21, web 13->14, shex-orm 8->9, alien-deepsignals 11->13. The anchor records all four; an anchor naming only orm would have been a true statement covering a quarter of the surface. - VERIFIED - the pinned tree is provably older than the binding in the build, by arity, not by version string. That single fact is what refutes the retraction, and it was available in two greps.
- VERIFIED -
sdk/js/lib-wasmhas nopackage.json. It is the Rust crate that builds the binding; twelve citations point into it and their published identity is@ng-org/web. The anchor says so explicitly. - VERIFIED - the published artifacts ship JS, not only types. The task expected the shipped artifact would usually fail to settle behaviour.
@ng-org/orm'sdist/carries the real call sites, which is what settled level 3 here. - VERIFIED, self-inflicted and caught by the gate - a literal
/*written inside a//annotation silently disabled the comment-stripping regex (.replace(/\/\*[\s\S]*?\*\//g, "")) inmoduleExports, swallowing sevenexport type { ... }lines and failingvocabulary.test.ts. Fixed by rewording. The parsers inprovenance.test.tsandvocabulary.test.tsare fragile this way: they strip block comments before line comments, so any/*inside a//comment eats the file to the next*/. Reported below.
Follow-ups, none fixed
provenance.test.ts/vocabulary.test.tsmoduleExports: strips/* ... */before// ..., so a/*inside a line comment silently swallows source. A one-line reorder would close it.- The
NGmember count is still hand-measured. It is now version-named in one place, but a test could count the installedNGModuleand pin it, turning doctrine into a gate. docs/api-contract.mdstill cites line ranges into installed.d.tsfiles elsewhere; line numbers rot, and the repo's own rule says a ref cites a symbol.- Whether the deployed engine honours
where/orderBy/pageSizeis open and only a live measurement closes it. It would be a real finding either way.