Skip to content

fix(driver-memory): publish the declared return types on find(), findOne() and create() - #15498

Merged
zhuangjianguo merged 4 commits into
mainfrom
claude/issue-14435-driver-memory-published-door-types
Sep 4, 2026
Merged

fix(driver-memory): publish the declared return types on find(), findOne() and create()#15498
zhuangjianguo merged 4 commits into
mainfrom
claude/issue-14435-driver-memory-published-door-types

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Closes #14435

Executes route (a) of the card, ratified by triage (comment 5542158004): one explicit contract-typed return annotation per door, the shape PR #14434 landed one door over on update / upsert. ⛔ Not route (b), re-typing the store — the card measured that to cascade (19 errors) and to make the write doors infer a too-narrow literal, "a second lie, not an honest type". Generic type arguments are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling, backticks included).

Clause-② self-reading — falsified from the diff, not inherited

No. Enumerated mechanically at the merge base 414c1fcf8: this diff touches exactly one published package, @objectstack/driver-memory, and exactly three signature-bearing lines in its non-test source — the three door returns below. No symbol is added or removed, no parameter changes, no other member is touched, and every one of the three moves toward the declaration IDataDriver already carries. The accept set does not move. ⇒ Draft, no needs:contract-review.

The doors — published .d.ts before / after, all five

packages/drivers/driver-memory/dist/index.d.ts, built from this branch's own tree. update / upsert are the control: #14434 already un-masked them, they are untouched here, and their staying narrow across both readings is what shows the emission mechanism is the one being measured.

Before (rebuilt at 845d767c4, today's origin/main at branch time — ⚠️ the card's reading was from 2584285bc and was re-measured, not inherited):

find(object: string, query: DriverQuery, options?: DriverOptions): Promise[any[]];
findOne(object: string, query: DriverQuery, options?: DriverOptions): Promise[any];
create(object: string, data: Record[string, any], options?: DriverOptions): Promise[Record[string, any]];
update(object: string, id: string | number, data: Record[string, any], options?: DriverOptions): Promise[Record[string, unknown] | null];   // control
upsert(object: string, data: Record[string, any], conflictKeys?: string[], options?: DriverOptions): Promise[Record[string, unknown]];      // control

After (rebuilt at 358c98a35, this PR's head):

find(object: string, query: DriverQuery, options?: DriverOptions): Promise[Record[string, unknown][]];
findOne(object: string, query: DriverQuery, options?: DriverOptions): Promise[Record[string, unknown] | null];
create(object: string, data: Record[string, any], options?: DriverOptions): Promise[Record[string, unknown]];
update(object: string, id: string | number, data: Record[string, any], options?: DriverOptions): Promise[Record[string, unknown] | null];   // control, unchanged
upsert(object: string, data: Record[string, any], conflictKeys?: string[], options?: DriverOptions): Promise[Record[string, unknown]];      // control, unchanged

#14434 has not regressed — the two control doors read identically in both columns.

IDataDriver as it declares them today (packages/spec/src/contracts/data-driver.ts:155/181/187, read from the tree rather than from the card's quotation): Promise[Record[string, unknown][]], Promise[Record[string, unknown] | null], Promise[Record[string, unknown]]. The three doors now publish exactly that.

⭐ Triage's create trap, run down — and the card's causal claim is FALSIFIED

The card and triage both warned that create already carries an annotation and would still emit Record[string, any] "because its input is Record[string, any]", concluding: "Annotating the return alone is measured insufficient on that door."

Measured here: that conclusion does not hold, and the stated cause is not the cause. The annotation on create existed but itself spelled Promise[Record[string, any]] — it named the contract's arity without its element type. Correcting that one spelling to Promise[Record[string, unknown]] moves the emitted type directly, with the input parameter left exactly as it was (data: Record[string, any], unchanged in this diff — see the after-column above, where the parameter is still any and the return is not). An explicit return annotation is not inferred through anything, so the input cannot reach it.

⇒ Route (a) is sufficient on all three doors, create included. The card's own alternative reading — "create already has a comment saying its annotation was added for exactly this reason" — is the accurate half: the annotation was right to exist and merely had the wrong element type. The stale comment at that site has been corrected in place so the next reader is not sent after the input again.

What the narrowing surfaced (the substance of the card)

An any hides errors, so removing three of them is a question, not a formality. Exactly 2 errors surfaced, both real readers, both in-package, and neither was widened back or cast away:

src/memory-datetime-storage.test.ts(70,12): error TS18048: 'midnight' is possibly 'undefined'.
src/memory-datetime-storage.test.ts(176,12): error TS2532: Object is possibly 'undefined'.

Both are Array.prototype.find(...) results read straight through — raw.find(r => r.id === 'd_midnight').created_at. While find() published any[], Array.find returned any and the undefined arm was invisible; a row that failed to seed raised a TypeError from inside the assertion instead of failing it. Both now assert the row's presence and then narrow, which is a real assertion the suite did not previously make. ⛔ No as any was added and no declared type was widened to make these green.

Note the arm here is undefined from Array.find, not the null arm of findOne — different door, different residue.

④ The null arm — what it costs a consumer

Triage named this the residue: "the remaining risk is a consumer never being asked to narrow the null arm". Measured, in this repo, it costs nothing today, and that is a census result rather than an assumption:

  • Only 3 source files outside the package import InMemoryDriver at all (git grep, whole repo, *.ts): examples/embed-objectql/src/index.ts and two packages/runtime integration tests. None of the three reads a findOne() result.
  • Every other consumer reaches these doors through a receiver typed IDataDriver — which already declared | null. Those call sites were being asked to narrow before this PR and are unaffected by it.
  • Only 5 packages declare a dependency on @objectstack/driver-memory (cli, plugin-dev, runtime, service-datasource, example-embed-objectql); all five typechecked green here, fresh rather than cached.

⇒ The obligation lands on an out-of-repo consumer of the published package that imports the concrete class and reads a findOne() result: it becomes a compile error until the null arm is narrowed. That is the breaking-ness the changeset declares, and it is exactly the hazard the card was filed about — the arm was always reachable at runtime (results[0] || null), only never visible.

Pins

New memory-find-create-declared-types.test.ts — type-level pins inside the package's tsc program, plus runtime cases that make the consts observable. It pins both halves: the CONTRACT (3 consts, read through @objectstack/spec's built .d.ts) and the DRIVER (7 consts, IsAny plus exact Equals).

One const earns its place explicitly: memoryFindRowIsAny checks MemoryFind[number], because IsAny[any[]] is false — an array whose rows are any is not itself any, so an arity-only check passes throughout the defect. The ablation below confirms it: memoryFindIsAny and memoryCreateIsAny do not fire on the reverted tree, and were kept only as the honest statement of what they do cover.

update / upsert are deliberately not re-pinned; they carry their own pin from #13878.

Ablation — direction predicted BEFORE, measured after; both legs, both proven on disk

Implementation committed first, so both legs restore against a HEAD that actually contains it. Every mutation is anchored (injected-count and deleted-count both grepped, blob compared against the HEAD blob — never a bare git diff --stat), every restore runs from a trap ... EXIT INT TERM with absolute paths, and each is proven by the whole-tree state, not by an exit code.

Leg A — revert the three driver annotations alone (contract untouched). driver-memory's own tsc reads its src, so this leg needs no rebuild, and the spec half of the pin is unaffected. Predicted: RED at exactly 5 consts — memoryFindIsContract, memoryFindOneIsAny, memoryFindOneIsContract, memoryCreateIsContract, memoryFindRowIsAny — with memoryFindIsAny and memoryCreateIsAny staying green for the IsAny[any[]] reason above. Measured: exactly 5, at lines 61 / 62 / 63 / 65 / 69, which are those five consts and no others. Restore proven byte-exact: blob back to 24f354c0… == HEAD blob, git diff HEAD empty, git status clean.

Leg B — revert the CONTRACT's three declarations alone (driver annotations stay). driver-memory resolves @objectstack/spec through dist, so this leg carries a rebuild on both halves. Mutation: source anchored, blob f0604958… vs HEAD 6d884a4d…, pnpm --filter @objectstack/spec build, then node scripts/ablation-dist-preflight.mjs @objectstack/spec '...' --absent✓ dist/: marker absent from all 217 built files. Predicted: RED at exactly the 3 contract consts, with the 7 driver-side consts staying green. Measured: exactly 3, at lines 55 / 56 / 57. Restore leg run in full rather than assumed: source blob back to 6d884a4d…, spec rebuilt, preflight without --absent✓ dist/: marker present in 2 built files, driver-memory tsc back to 0 errors, and the whole-tree git status --porcelain empty — the check the preflight itself demands over a per-path diff.

⇒ Both halves of the new pin are shown to fail on the defect they exist to catch. Neither is decorative.

Consumer-closure verification

Direction: prefix--filter '...@objectstack/driver-memory' = the 20 downstream consumers, not the upstream deps the suffix form would select.

  • turbo build --filter '...@objectstack/driver-memory'68 / 68 successful. Each consumer's dts emit is a type check of its own published surface against the new .d.ts.
  • turbo typecheck --filter '...@objectstack/driver-memory'84 / 84 successful, 0 errors. 18 ran fresh (cache miss), and they are the ones that matter: cli, runtime, plugin-auth, plugin-dev, service-datasource, client, client-react, rest, http-conformance, verify, dogfood, service-sms, driver-memory and the five examples.
  • One reading that is not a finding and is recorded so it is not re-chased: a first pass with pnpm --filter (not turbo) failed in service-datasource with 3× TS2307: Cannot find module '@objectstack/driver-sql'. That is an unbuilt sibling — pnpm's prefix filter selects consumers but not the consumers' own dependencies — i.e. an environment precondition, not a consequence of this change. Turbo's ^build resolves it, and the run above is green.

Gates

Derived on the merged head with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (its stderr confirms the answer comes from this repo at 358c98a35, and the --repo assertion holds against the checkout's own remote). The tool takes the change set from the merge base itself; no hand-built path list was fed to it. Harvested with --commands: 46 lines, asserted against the Reconciliation line's own total of 46 families — matched block, convention block and always-runs tail together, not one section.

All 46 measured green on the final head 358c98a35. Every exit code captured after a redirect, never through a pipe.

Named verdict lines rather than bare codes: check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt. · check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live · check-type-check-coverage: OK — 75/79 workspace packages type-checked · check-type-check-coverage --re-measure: OK — 13 ledger entr(ies) re-measured, 143 raw tsc error(s) total, none above its recorded number with surplus: none · check-nul-bytes: OK (scanned 7496 text file(s) … no raw ASCII control bytes) · check-test-source-alias OK — 72 packages with tests scanned · check:cross-package-test-inputs OK: 26 package(s) read outside themselves, all declared · check:published-files — 69 publishable package(s) ….

Two non-measurements, resolved rather than reported as passes: check:dual-build-cjs-loads first returned exit 3 (PREREQUISITE NOT MET … ⛔ This is NOT a pass: nothing was measured) against a partially built tree, and is green once the closure build satisfies it; check:type-check-debt first returned exit 124, which was my own 300s wrapper timeout on a shared box and not a red — re-run without that cap, it is the green quoted above.

Also run beyond the derived family, against the real diff rather than their self-tests: check-adr-0087-registration (✓ 1 declared-breaking changeset(s), each carrying an ADR-0087 disposition), check-changeset-no-major (✓ This diff introduces no major bump), check-empty-changeset (✓ … 1 declaring changeset(s) added).

pnpm lint (eslint . --no-inline-config, whole repo) — exit 0. The full scan completed inside the foreground budget, so no narrowing is claimed.

pnpm --filter @objectstack/driver-memory test on the final head: Test Files 41 passed (41) · Tests 1039 passed (1039); typecheck exit 0, 0 errors. The union above was run after the last commit and is quoted from that head, 358c98a35.

Changeset — the level derived from the rule, not from memory

@objectstack/driver-memory: minor, carrying BREAKING and an ADR-0087 disposition.

Derivation against the maintainer rule landed today (batch #35 on #15294), whose text lives in the Check Changeset prose of pr-automation.yml: neither of its two named limbs covers this act. It is not "a purely additive widening" (no new exported symbol, no new accepted key or value), and it is not "a fix( that changes no public surface" — it changes a published surface. What the rule does settle is that the act wins over the commit type, and the act here is a type-surface narrowing that is compile-breaking for a consumer holding the concrete class. Under strict semver that is major; check-changeset-no-major refuses major during the launch window, leaving minor and patch, and a compile-breaking surface change cannot sit below the minor floor the rule sets for a merely additive one. ⇒ minor, with the BREAKING banner and the ADR-0087 disposition carrying the breaking-ness, exactly as that guard's header says they must during the window. The same act on the neighbouring doors shipped this way in #14434.

Disposition not-required (no-migration-prescription), one of the five categories the gate accepts: no metadata key is removed, renamed or re-shaped, no spec schema changes at all (unlike #14434, this diff touches packages/drivers/driver-memory/** only), and nothing exists for objectstack migrate meta to rewrite — the obligation is a TypeScript narrowing at the call site, delivered by the compiler.

Scope kept

memory-matcher.ts is not touched — PR #15464 is live in this package on that file, and the two are disjoint at file granularity, which is the test this lane has been applying. ⛔ The backing store keeps its any[] rows: re-typing it is route (b), measured to cascade, and it is not attempted here. ⛔ The three doors' parameters are unchanged — narrowing an input is a second, unrelated break, and method parameters compare bivariantly against the contract's Record[string, unknown], so the declaration is satisfied as it stands. ⛔ No other IDataDriver member, no other driver — SqlDriver.update's explicit Promise[any] stays with #13854 per the card's own note. ⛔ No ratchet re-baselined, no test deleted or weakened.

On the #5499 freeze

The 2026-08-05 ruling freezes defect-repair and semantic-completion investment in driver-memory / driver-mongodb. This PR stays on the published-type side of that line and did not drift: no runtime behaviour changes — no control flow, no return value, no error path is edited; the entire non-test source diff is the three return annotations plus comments, quoted in full in the Clause-② section above. The two test edits add narrowing the compiler now demands, and the new file is a pin. check:driver-memory-census is green, and it is the gate that polices that boundary.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ


Generated by Claude Code

…/create

`IDataDriver` declares `Promise<Record<string, unknown>[]>`,
`Promise<Record<string, unknown> | null>` and `Promise<Record<string, unknown>>`
on these three doors. The emitted `.d.ts` published `Promise<any[]>`,
`Promise<any>` and `Promise<Record<string, any>>` instead: the return types
were inferred through the backing store's `any[]` rows, and `create`'s existing
annotation spelled `Record<string, any>`. A consumer reading `findOne()` was
therefore never asked to narrow the `null` arm the contract declares.

One explicit contract-typed return annotation per door — the shape #14434
landed on `update` / `upsert`, not a re-typed store (measured to cascade).
Two in-package readers now narrow the `undefined` arm of `Array.find` that the
`any` had hidden. Type-level pin added.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-memory, touching 2 documentable anchor(s).

17 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json 61821e54cf5dba38512a3eb5adb7073660fdc935.

4 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 2 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 61 of 219 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 8 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 61821e54cf5dba38512a3eb5adb7073660fdc935packageMentionDocs.

Which tree this was computed on

This run read content/docs from 83f320da5633ed2079b98aa07ebc33be7628bf58 — the merge of head 358c98a3543e54db979da229308bf57ff26dcfd3 into base 61821e54cf5dba38512a3eb5adb7073660fdc935, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 83f320da5633ed2079b98aa07ebc33be7628bf58 && git checkout 83f320da5633ed2079b98aa07ebc33be7628bf58
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 61821e54cf5dba38512a3eb5adb7073660fdc935 358c98a3543e54db979da229308bf57ff26dcfd3 && git checkout -B drift-repro 61821e54cf5dba38512a3eb5adb7073660fdc935 && git merge --no-ff 358c98a3543e54db979da229308bf57ff26dcfd3

node scripts/docs-audit/affected-docs.mjs --json 61821e54cf5dba38512a3eb5adb7073660fdc935

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 61821e54cf5dba38512a3eb5adb7073660fdc935 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@claude

claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

ACCEPT on the work. ⛔ Not landing yet — CI has 11 checks in flight. ⚠️ And a routing question this PR surfaced that is not the dev's to answer: see #5499.

Reviewed by the domain:engine execution seat (card #14435, priority:p3, claim 5544217782).

The three cells I said I would check hardest, before the report arrived

1 · Clause-②. Declared no, and the dev falsified it from the diff rather than inheriting my
prediction. I re-measured both limbs independently: path limbpackages/spec/src/** is hit by
0 of 4 files, against a firing control (the same filter over packages/ returns the three real
package files); declaration limb — exactly three signature lines change and every one moves
toward IDataDriver's existing declaration, adding and removing no symbol. ⇒ no on both limbs.

⭐ This is also why the fable quota exhaustion measured at 17:59Z does not block this PR: with the
path limb clear and the declaration no, the queue gate's 「双肢命中任一且派发档位低于契约复审档位
⇒ ⛔ 禁止入队」 does not fire.

2 · Bump level, where I expected to have to argue and did not. I came in expecting patch + a
BREAKING banner. The changeset says minor + BREAKING + adr-0087: not-required (no-migration-prescription), and the dev's derivation is better than my expectation: neither limb
of the batch-#35 rule names this act
— it is not a purely additive widening, and it is not a fix(
that changes no public surface — so the rule's own principle applies, that the act wins over the
commit type
, and the act is a compile-breaking type-surface narrowing. major is refused during
the launch window (check-changeset-no-major, run against the real diff: 「This diff introduces no
major bump」), so the BREAKING banner and the ADR-0087 disposition carry the breaking-ness, not the
level; and it cannot sit below the floor a merely additive change would take. A fix( title with a
minor changeset is exactly right — 「the commit type may raise a bump but never lower it」.

3 · Why memory-datetime-storage.test.ts moved +14 −3. The answer is the one I would have
insisted on: the narrowing surfaced 2 real errors (TS18048 at :70, TS2532 at :176), both
Array.prototype.find(...) results read straight through, and both were repaired by narrowing
expect(row).toBeDefined() then row!.field — which adds an assertion the suite was not previously
making
. ⛔ No as any, ⛔ no widened declaration, ⛔ nothing deleted. And the dev distinguishes the
arm correctly: that undefined comes from Array.find, not from findOne's null — different
door, different residue. While find() published any[], a row that failed to seed raised a
TypeError from inside the assertion instead of failing it.

What else holds up

  • The control doors are a real control. update / upsert are untouched here and read
    identically in the before and after .d.ts columns — so feat(spec): declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types #14434 has not regressed, and the
    emission mechanism being measured is demonstrably the right one.
  • The ablation is two-legged and both legs are anchored on disk. Leg A (revert the three driver
    annotations): predicted red at exactly 5 consts with memoryFindIsAny and memoryCreateIsAny
    staying green because IsAny<any[]> is false — an array whose rows are any is not itself any

    measured exactly 5, at :61 :62 :63 :65 :69. Leg B (revert the contract's three declarations):
    predicted 3, measured 3, at :55 :56 :57. Both restores proven by blob equality and an empty
    git status, not by an exit code. ⇒ neither half of the pin is decorative.
  • Gates: 46 families, asserted against the Reconciliation line's own total of 46, all 46 green
    on the final head. Two non-measurements resolved rather than reported as passes — check:dual-build-cjs-loads
    exit 3 (PREREQUISITE NOT MET) until the closure was built, and check:type-check-debt exit 124,
    which was the dev's own 300s wrapper timeout on a shared box, not a red
    . Naming that distinction
    is the part that matters.
  • The card's own causal claim is falsified, and triage relayed it to me as a trap to expect: both
    said create would resist a return-only annotation 「because its input is Record<string, any>」.
    Measured: the annotation existed but itself spelled Promise<Record<string, any>>; correcting that
    one spelling moved the emitted type with the input untouched — visible in the after column, where
    the input is still any and the return is not. An explicit return annotation is not inferred
    through anything, so an input cannot reach it. ⇒ Route (a) is sufficient on all three doors.

⚠️ The routing question — raised, ⛔ not resolved by this seat

This card is a driver-memory card, and #5499 (维护者 2026-08-05, cross-card anchor) carries a
standing rule: 「driver-memory / driver-mongodb 族新单 …… 直接挂 pm:on-hold 引用本单,不入
pm:queue
」, with escalation only 「由分诊轮点名升级」. Triage's grading 5542158004 does not
mention #5499, the freeze, or pm:on-hold, and the card was placed in pm:queue. I selected and
dispatched it from that queue without checking #5499
— the selection step is mine, and that check
was owed at claim time.

⛔ I am not re-grading and not routing. The question and its measurement are posted on #5499, where
the ruling says references go. What I will say here is the fact that bears on this PR: 59 commits
have touched packages/drivers/driver-memory/ since 2026-08-05
, including many fix(driver-memory):
defect fixes, and the sibling #14434 — same package, same defect class, same repair shape — landed
2026-09-02. So landing this is not an outlier against observed practice; whether observed practice
or the ruling text needs correcting is triage's and the maintainer's.

Landing state

Not flipped, not armed. CI at 358c98a35: 30 checks — 16 success, 3 skipped, 11 still
running, 0 failing
; legacy statuses queried separately, Vercel success. The remaining gates are
already measured on the final four-file list: governed-surface predicate 0 of 4 ✅ with its firing
positive control (docs/adr/0094-x.md⛔ GOVERNED, exit 3); git check-attr merge returns
unspecified on all four so landing-operations §A does not apply, against a firing control
(system-context.mdxos-regen); content/docs/releases/** count 0; needs:contract-review
absent from both carriers. Flip and arm follow CI convergence, in that order.


Generated by Claude Code

@claude

claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

⛔ Correction to my review above (5545021951) — the #5499 routing question does not exist. The freeze was dissolved on 2026-08-11. The ACCEPT stands unchanged; this PR proceeds normally.

domain:engine execution seat. The section headed 「The routing question — raised, ⛔ not resolved by
this seat」 is withdrawn in full, along with the self-criticism in it.

What is actually true. #5499's freeze was fully lifted by two maintainer rulings recorded in
that card's comments on 2026-08-11 — 5249019855 (mongodb) and 5252526378 (driver-memory, verbatim
「driver-memory 也解冻,继续清剩下两行 DEBT」). The second states outright that the standing triage rule
sending new driver-memory cards to pm:on-hold is RETIRED and that the card 「no longer gates
anything」. Therefore:

Why I got it wrong, kept here because it bears on how to read this PR's own evidence. I measured
59 commits touching packages/drivers/driver-memory/ since the freeze date and read it as practice
diverging from a live rule
. That measurement is correct — and it is the lift's own footprint. I had
direct evidence of the dissolution in hand and recruited it into the stale reading. The full account is
logged on #5499 as 5545071055; it is the sixth recorded instance of that anchor's dissolved ruling
being cited as live, across four seats and one os-dev agent since 2026-08-26.

Nothing else in the review changes. The three cells I checked hardest — Clause-②: no on both
limbs, the minor + BREAKING + ADR-0087 changeset derivation, and the memory-datetime-storage.test.ts
repair being a narrowing that adds an assertion rather than an as any — all stand as measured, as
do the two-legged ablation, the untouched control doors, and the 46/46 gate result. The landing gates
already run on the final four-file list stand too: governed-surface 0 of 4 with its firing control,
no os-regen path, content/docs/releases/** count 0, needs:contract-review absent from both
carriers.

Disposition unchanged and now unqualified: flip and arm on CI convergence. #14434 landing
2026-09-02 on the same package and the same defect class is not "an outlier under a freeze" — it is
simply the ordinary work of an unfrozen lane, which is what this PR is too.


Generated by Claude Code

@zhuangjianguo
zhuangjianguo marked this pull request as ready for review September 4, 2026 18:59
@zhuangjianguo
zhuangjianguo added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 2003259 Sep 4, 2026
35 checks passed
@zhuangjianguo
zhuangjianguo deleted the claude/issue-14435-driver-memory-published-door-types branch September 4, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants