Files
ng-eventually/.tasks/done/T01.h-refresh-the-nextgraph-packages.md

96 lines
10 KiB
Markdown

---
id: T01.h
title: Refresh the NextGraph packages to their latest published versions
parent: T01
depends_on: [T01.f]
created: 2026-09-21
claimed_by: T01.h-worker
claimed_at: 2026-09-21T14:17:00+02:00
blocked: false
---
## Description
Once the surface work is done, bring `@ng-org/web`, `@ng-org/orm`, `@ng-org/shex-orm` and `@ng-org/alien-deepsignals` to their latest published versions, in BOTH workspace packages, and reconcile whatever the update surfaces.
**Why this is its own task and not a chore.** The 2026-09-21 update from `alpha.13/19/8/11` to `alpha.14/21/9/13` was expected to be routine and was not: it revealed that `orm_start_graph` had gained a sixth parameter (`config`, before the callback), which is exactly what a live measurement had observed against the deployed broker and attributed to the deployment being ahead. It also renamed `OrmSubscription` to `RdfOrmSubscription`, made `Scope.graphs` required, and — through a clean reinstall — exposed that six e2e files imported `ng-e2e-helpers` without the polyfill declaring it. An update against this SDK is a source of findings, so it gets a task and a gate.
**What to do.** Check the published version of each of the four packages. Bump them in `packages/polyfill/package.json` and `packages/ng-e2e-helpers/package.json` together, so no two versions of a package with module-level state coexist in the tree — that duplication is the single-instance hazard the polyfill's own contract names. Reinstall with pnpm (`CI=true pnpm install --no-frozen-lockfile` when the lockfile has drifted), then read what the typechecks and the suites say rather than assuming the update was invisible.
**Then verify against the real broker**, not only by typecheck: run `packages/polyfill/e2e/orm-live-read.ts` and the polyfill e2e suite. A signature that matches at compile time can still disagree with the deployment.
**Record what the update revealed.** If it changes a fact already written in a doctrine leaf — an arity, a symbol name, a type's optionality — fix the leaf in the same pass. A stale fact in doctrine is worse than an absent one.
## Progress
## Result
Status: done
### The four version moves: NONE. All four were already at their latest published version.
| package | declared before | latest published | moved |
|---|---|---|---|
| `@ng-org/web` | `0.1.2-alpha.14` | `0.1.2-alpha.14` | no |
| `@ng-org/orm` | `0.1.2-alpha.21` | `0.1.2-alpha.21` | no |
| `@ng-org/shex-orm` | `0.1.2-alpha.9` | `0.1.2-alpha.9` | no |
| `@ng-org/alien-deepsignals` | `0.1.2-alpha.13` | `0.1.2-alpha.13` | no |
VERIFIED three ways: the `latest` dist-tag from a direct uncached `registry.npmjs.org` fetch, the full version list, and `pnpm outdated` (reports nothing for `@ng-org/*` in either workspace package). No `package.json` was touched, and nothing was pinned back - there was simply nothing newer to move to. The refresh this task was written for had already happened, earlier the same day, inside T01.d.
**The `0.1.2` trap.** Three of the four (`web`, `shex-orm`, `alien-deepsignals`) also publish a bare `0.1.2`, which semver ranks ABOVE every `0.1.2-alpha.N`. It is a legacy release from 2025-10/2025-12; the alphas are from 2026. "Upgrading" to it would go back roughly a year. The exact pins in the `devDependencies` are what keep it out. `ng-e2e-helpers` declares the peer range `"@ng-org/web": ">=0.1.2-alpha.13"`, which DOES admit `0.1.2` - latent, since a peer is not auto-installed, but it is the one declaration in the tree that would accept the regression.
### Breaking changes surfaced, and how each was reconciled
The version bump surfaced none, because there was none. The install DID surface one thing, and the doctrine audit surfaced the rest.
1. **The tree was bun-installed, not pnpm-installed.** Every `@ng-org` symlink under both workspace packages pointed into `node_modules/.bun/`, and that store still held `web@alpha.13`, `shex-orm@alpha.8` and `alien-deepsignals@alpha.11` beside the current ones. The resolved versions were correct, so the single-instance hazard was latent rather than active. Reconciled by `CI=true pnpm install --no-frozen-lockfile`, which re-pointed every symlink into `.pnpm/`. The lockfile did not move ("Lockfile is up to date"). The dead `.bun` store was left in place - it is an untracked artifact, and removing it was not asked for.
2. **The doctrine's citation anchor is three orm releases behind the installed package.** This is the finding of the task. The pinned `nextgraph-rs` checkout `213338f6` declares orm `alpha.18` / web `alpha.13` / shex-orm `alpha.8` / alien-deepsignals `alpha.11`, while `packages/polyfill` compiles against `alpha.21/14/9/13`. Every leaf citing `sdk/js/orm/src/...` therefore describes a version this repo no longer uses. Reconciled by naming BOTH anchors wherever they disagree, rather than rewriting citations that would then be false for the commit they point at.
### The four gates, verbatim
- `bun test` -> `424 pass`, `0 fail`, `1162 expect() calls`, `Ran 424 tests across 39 files.` Baseline before any change was identical (`424 pass / 0 fail`), matching the figure recorded on this task.
- `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` (warnings only; the `broken [[...]] links - 1` warning present at baseline is now GONE)
### The live measurements, against the real broker
- `packages/polyfill/e2e/orm-live-read.ts` -> `ORM live-read summary: 5 passed, 0 failed, 5 declared - run 0.6 min`. The read is ready in 13ms and the delete reached the document. `5 declared` and not the `6` in the parent digest because the characterisation row was retired with the question it answered - the runner's own header records that, so this is not a lost row.
- `packages/polyfill/e2e/run.ts` -> `Polyfill e2e summary: 43 passed, 0 failed, 43 total - batch 3.2 min, slowest cold sync 26s`.
### Doctrine leaves corrected, and the false fact each carried
`app-contract/knowledge_what-the-orm-writes-and-deletes-upstream.md`
- announced `orm@alpha.19 / web@alpha.13 / alien-deepsignals@alpha.11` as installed - all three wrong
- "`core.ts` exports exactly `initNg, ngSession, OrmSubscription, DiscreteOrmSubscription, insertObject, getObjects`" - alpha.21 renames `OrmSubscription` to `RdfOrmSubscription` AND adds `removeObject`, so "exactly" was false
- `getOrCreate(shapeType, scope)` - alpha.21 takes an `RdfOrmConfig` (`Scope & {where?, orderBy?, pageSize?, maxActivePages?}`), and the instance gained `mode`, `isReady`, `addChangeListener`, `removeChangeListener`, `nextPage`, `previousPage`
- "a live ORM read still does not start against the deployment" - false, measured 5/5 today
- `[[bug_useshape-live-read-needs-a-newer-broker]]` - dangling, the leaf was deleted by the previous refresh
`app-contract/knowledge_what-a-read-scope-is-upstream.md`
- "`Scope = { graphs?: ... }`" - `graphs` is REQUIRED in alpha.21; a caller that omitted it no longer compiles
- "`[]` or `undefined` returns no objects at all", stated of the type as a whole - true of `graphs`, FALSE of `subjects`, where `[]` means no filtering. Now a two-row table, because this is the trap the repo has already paid for once
- `OrmSubscription` / `connector/GraphOrmSubscription.ts` - both symbol and file renamed in alpha.21
`e2e-harness/knowledge_what-each-suite-judges.md`
- "It is EXPECTED to exit non-zero while the deployed broker and the published client packages disagree" plus a pointer to the deleted bug leaf - the runner is green now, and a red run means they have drifted apart again
`contract_polyfill-surface.md` was checked and needed nothing: it already records `removeObject` at alpha.21 and the 2026-09-21 catch-up correctly.
### The three out-of-scope follow-ups: none got worse
- (a) `useShapeQuery` opens nothing named in `scope.graphs` - unchanged, scope still passed through untouched
- (b) `ensureReposOpen` dead - unchanged, still called only from its own test file
- (c) `examples/notebook/tsconfig.json` - still exactly `1 error TS2345`, the same `ShapeType` structural mismatch. Not worse
### Surprises
- **The task's premise did not hold: there was nothing to update.** VERIFIED. The work turned out to be the reconciliation half - the previous refresh moved the packages and left the doctrine behind.
- **The pinned source checkout is behind the installed packages.** VERIFIED (`nextgraph-rs` at `213338f6` declares orm `alpha.18`). This weakens every source citation in the concept leaves, and it is the structural version of the trap this task names: a fact read at the cited source can disagree with the package the code actually compiles against, exactly as a compile-time signature can disagree with the deployment.
- **`removeObject`'s own documentation contradicts itself.** VERIFIED from `connector/removeObject.d.ts`: it declares `DELETE WHERE { GRAPH <g> { <s> ?p ?o } }` - every predicate of the subject - while claiming in the same comment to have "the same effect" as a `delete()` on a subscription's object, which removes only the SHAPE's predicates. Nothing in the cited source settles which holds. Recorded in the leaf; it stays unpublished, per T01.e.
- **I nearly wrote a new false fact while fixing false facts.** I first wrote that alpha.21's `where`/`orderBy`/`pageSize` "became reachable from level 3". INFERRED from the JS surface alone, and the pinned engine refutes it: `Verifier::start_orm` still builds `OrmConfig::from_json(&json!({}))` behind a `// TODO`. Corrected before committing to say the richness is expressible at level 3 and discarded at level 1, and that measuring it is not done here.
- `playwright` is outdated in `ng-e2e-helpers` (`1.61.1` -> `1.63.0`). Out of scope - not one of the four packages. Reported, not touched.
- `pnpm-workspace.yaml` lists only `packages/*` while the root `package.json` `workspaces` also lists `examples/*`, so `examples/notebook` is outside pnpm's scope entirely. VERIFIED (`pnpm install` reports "all 3 workspace projects"). Plausibly related to follow-up (c); not investigated, not touched.