Skip to content

feat(spec)!: retire the datasource driver spelling mongo — refused naming mongodb, its D2 conversion leaves the load path (F1 of #23543) - #23600

Merged
objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/issue-23543-retire-mongo-driver-alias
Oct 15, 2026
Merged

objectstack-fleet[bot] merged 8 commits into
mainfrom
claude/issue-23543-retire-mongo-driver-alias

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #23543

Clause-②: yes

This PR lands family F1 of ruling 6182001882 only. F5-jsx, F3, F2, F4 and F5-http stay on #23543 and follow one PR each, in the ruled order.

What

Ruling F1 A: 'mongo' retires as a datasource.driver value, refused with the prescription naming mongodb; stored rows are rewritten by the D3 chain; datasource-driver-mongo-to-mongodb sets retiredFromLoadPath.

  • Authoring refusal. DriverType (packages/spec/src/data/datasource.zod.ts) refuses mongo by name, case- and whitespace-insensitive. The message is the prescription: "Datasource driver: 'mongo' was removed in @objectstack/spec 18 (ADR-0087 D2) … Use driver: 'mongodb'." It ends with the house os migrate meta --from 16 sentence. At defineStack this is STACK_SCHEMA_INVALID / 422 with one issue at datasources.0.driver.
  • Where the spelling is declared. A new retiredAliases column on the driver vocabulary row (packages/spec/src/data/driver/config-registry.zod.ts): { id: 'mongodb', aliases: ['mongodb'], retiredAliases: { mongo: PRESCRIPTION } }. The refusal is derived from that column (exported as RETIRED_DRIVER_ID_GUIDANCE), so the table remains the one vocabulary.
  • Selection face. mongo is no longer a boot selection. Both hosts refuse OS_DATABASE_DRIVER=mongo alike, and their "Supported drivers" list names mongodb. The cross-host parity pin is flipped to say so.
  • The D2 entry. datasource-driver-mongo-to-mongodb gets retiredFromLoadPath: true and retiredAfter: '17.7.0' (the newest published stable release under the 18.0.0-next label, the same stamp PR feat(spec)!: retire seven overdue ADR-0087 D2 conversions from the load path at 18; record why eight stay #23523 used). It is already a member of step 17's conversionIds, so os migrate meta --from 16 and every includeRetired seam keep replaying it.
  • The D3 entry. 18.datasource-driver-mongo-alias-retired is the family's semantic entry, with conversionIds: ['datasource-driver-mongo-to-mongodb']. It names what the chain cannot reach: OS_DATABASE_DRIVER, a standalone stack's databaseDriver, and REST callers.
  • The verdict-list pin in conversions.test.ts moves the entry from the kept list to the retired list, and the entry's describe block is rewritten for the new semantics. The entry also has a row in the removal-version pin's JOIN.

Mechanism assumptions, measured

  1. "Retire = delete the alias" is false as stated. I deleted 'mongo' from the row outright, ran the suites, and probed. Measured on fa6a6085c:
    • Credential leak (security). The read-path credential redactor judges a stored body as written (redactStoredMetadataBody). It keys mongodb's passthrough-secret table by canonical id. With the alias gone, a raw stored legacy driver: 'mongo' row served all ten passthrough secrets in cleartext: options.proxyPassword, options.key, options.passphrase, options.tlsCertificateKeyFilePassword, AWS_SESSION_TOKEN and the five KMS secrets.
    • Four pins went red. These were stored.test.ts (a stored mongo row's uri/user were no longer renamed), the key-alias conversion's "row whose driver id is itself being renamed" case, refusedPassthroughSecretPaths('mongo'), and the "unconverted row keeps its contract" case.
    • What I did instead. The spelling leaves the selection face and the authoring surface, and it stays on the CONTRACT face only (resolveDriverId('mongo') still answers mongodb). This is the same posture the retired in-memory engine's spellings have.
    • Why the D2 order is untouched. The datasource-config-driver-key-aliases conversion still reaches a stored mongo row through the contract face, so the order of the step-17 list does not change.
  2. There was no existing value-retirement mechanism for this field. driver is an open namespace (z.string()), so enumWithRetiredValues cannot carry it. The refusal reuses that helper's prescription type (RetiredValueGuidance) and its writing conventions. It is spelled as a pattern (^(?!\s*[Mm][Oo][Nn][Gg][Oo]\s*$)), not a refinement. My first spelling was a refinement, and the build's dropped-refinement gate refused it. A pattern survives the JSON Schema projection, so a document validated against the published json-schema/** is refused too. config-registry.test.ts pins that projection.
  3. packages/cli/src/utils/config.ts:621 and :654. Both docblocks used driver: 'mongo' as the example of "a conversion the load still applies". They now say the defect was measured on that spelling, which has since retired.
  4. conversions.test.ts. Done as the assumption said. The verdict list now keeps 7 entries, and the retired list asserts this one with retiredAfter: '17.7.0'.

Pin sweep (whole repo, 'mongo' / "mongo" and the conversion id)

  • Flipped to the new semantics:
    • config-registry.test.ts: the selection face loses mongo. A new describe covers the authoring refusal (code invalid_format, path driver, message first sentence), the config gate still running behind it, selection withdrawn, contract kept, no false refusals (mongodb, com.vendor.mongolike, prototype words), the JSON Schema pattern, and the retired spelling being no live spelling.
    • conversions.test.ts, as above. Its new defineStack case asserts STACK_SCHEMA_INVALID / 422, the path, and the prescription's first sentence.
    • driver-vocabulary-parity.test.ts (cli): both hosts refuse mongo, each naming mongodb.
  • Re-pointed. These suites need a spelling the load still converts, which mongo no longer is:
    • stack-authored-input.test.ts (spec);
    • migrate-meta-load-conversions.test.ts, migrate-meta-composed-load-conversions.test.ts, and the load-path case of migrate-meta-composed.test.ts (cli).
    • They now carry a flow-level errorHandling.retryDelayMs. retry-policy-converged renames it at load, and it is a step-17 member, so --from 16 lists it.
  • Fixture spelling only: two datasource.test.ts fixtures now write mongodb. Their refusal assertions are unchanged.
  • Unchanged on purpose:
    • migrate-meta-write.test.ts and migrate-meta-protocol-range.test.ts still write driver: 'mongo' as a refused spelling the chain rewrites, which is still true.
    • The redaction, credential-refusal, pool-support, factory and admin-restore tests still pass mongo as a stored legacy row, which the contract face keeps judging as mongodb.
  • Docs and comments that became false:
    • content/docs/data-modeling/drivers.mdx, plus a short paragraph on the retirement;
    • packages/drivers/driver-mongodb/README.md, which is published, hence the patch changeset row;
    • the liveness/datasource.json note;
    • comments in driver-catalog.ts, mongo.zod.ts and mongo.test.ts.

Changeset

.changeset/23543-f1-retire-mongo-driver-alias.md: @objectstack/spec minor and @objectstack/driver-mongodb patch. It is BREAKING, carries Clause-②: yes (narrowing) as ruling item 7 spells it, gives the FROM → TO migration for all three places the spelling lives, and registers datasource-driver-mongo-alias-retired as its ADR-0087 disposition. check-adr-0087-registration --base origin/main exits 0 and reads it as BREAKING+bang+clause-②-narrowing, registered.

Verification (head acf0e6c1f, after merging origin/main 32e03d2fd)

  • @objectstack/spec:
    • test: 678 files / 20738 tests passed.
    • typecheck (tsc, scripts, test layer): exit 0.
    • test:repo: 61 / 1033 passed.
    • check:generated: all 14 artifacts up to date; api-surface/data.json and export-origins/data.json were regenerated for the one new export.
  • @objectstack/cli (unit tier), the six files the change touches or pins: 6 / 113 passed. The full unit tier and typecheck readings are in the report comment on the card.
  • Readings for @objectstack/runtime and @objectstack/service-datasource are in the report.
  • No packages/drivers/driver-* source reads a datasource.driver value (zero hits for the resolvers, DatasourceSchema or DriverType in src), so no driver suite is owed beyond CI.
  • Gate families: dispatch-gates.mjs --commands derived 117 commands, run one by one with exit codes captured before any pipe and reconciled with --ran. Verdicts are in the report.

Acceptance notes

  • The mongo refusal at the boot hosts. It is the hosts' existing "Supported drivers" refusal, which lists mongodb. It is not a dedicated prescription sentence like the retired in-memory engine's. RETIRED_DRIVER_ID_GUIDANCE is exported if a host should name it later.
  • Load-path suites (for F3 and F2). After this PR, the conversions that are still on the load path and that os migrate meta --from 16 replays are retry-policy-converged and F3's two config lifts. Once F3 and F2 land, the three cli load-path suites and stack-authored-input.test.ts have no real subject left. They will need a synthetic probe, or the suites retired, in whichever of those PRs lands last.

Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, @objectstack/driver-mongodb, @objectstack/service-datasource, @objectstack/spec, touching 14 documentable anchor(s). ⚠️ 5 changed file(s) yielded no anchor (packages/cli/src/utils/config.ts, packages/drivers/driver-mongodb/README.md, packages/spec/api-surface/data.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

⛔ 1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17/17-5.mdx (via retiredAfter (symbol, a field of const object datasourceDriverMongoToMongodb), retiredFromLoadPath (symbol, a field of const object datasourceDriverMongoToMongodb))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 5 changed file(s) yielded no anchor (packages/cli/src/utils/config.ts, packages/drivers/driver-mongodb/README.md, packages/spec/api-surface/data.json, …) — pages documenting those are invisible to this run
  • 3 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 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.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 148 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 16abea88450be3c453a9e769445af341a956bd17 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 98d738bd7237c0012dd50e49e81a249fe93be730 — the merge of head acf0e6c1faddeadab933358e5bedaa3fae075f2f into base 16abea88450be3c453a9e769445af341a956bd17, 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 98d738bd7237c0012dd50e49e81a249fe93be730 && git checkout 98d738bd7237c0012dd50e49e81a249fe93be730
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 16abea88450be3c453a9e769445af341a956bd17 acf0e6c1faddeadab933358e5bedaa3fae075f2f && git checkout -B drift-repro 16abea88450be3c453a9e769445af341a956bd17 && git merge --no-ff acf0e6c1faddeadab933358e5bedaa3fae075f2f

node scripts/docs-audit/affected-docs.mjs --json 16abea88450be3c453a9e769445af341a956bd17

⚠️ 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 16abea88450be3c453a9e769445af341a956bd17 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT · domain:spec seat 2 (#18549) · session session_01LFqdRsuM5nkqoJdHd5ztVk · 2026-10-15T04:32Z

This is the seat review of record for #23543 family F1 (claim 6182201116, ruling 6182001882) on head:

acf0e6c1faddeadab933358e5bedaa3fae075f2f

It is not the contract review. That review is owed at CONTRACT_REVIEW_TIER because packages/spec/src/data/datasource.zod.ts and the registry are published schema.

  1. Form.
    • Draft to main. The first line is Part of #23543, and the body carries no closing keyword.
    • Clause-②: yes sits at the start of a line.
    • No content/docs/releases/ change.
    • 23 files, +557/−162.
    • Not governed: check-governed-merges --pr 23600 hits 0 of 23 paths.
  2. Premises measured. Before this change, a driver: 'mongo' passed defineStack silently (the dev's dist probe). PM mechanism assumption 1 is partly falsified, and the dev's route stands:
    • Deleting the alias outright made a raw stored legacy mongo row serve its ten mongodb passthrough secrets in cleartext through the read-path redactor.
    • So the spelling leaves authoring (DriverType refuses it by name) and boot selection, and stays only on the contract face (resolveDriverId('mongo') still answers mongodb) for stored rows.
    • Whether that remnant is a "double spelling" against ruling item 7 is the contract review's ③ to judge.
  3. Gates.
    • Check-runs on this head: 41 in all, 36 success, 5 skipped, none red or pending. That includes Lint & Repo Gates, TypeScript Type Check, and Test Core 1–6.
    • Locally the dev ran 112 of the 117 derived families. The other 5 are NOT MEASURED, each with a reason.
    • check:platform-checklist's red is on main's tree, outside this diff.
  4. Accepted deviations.
    • The refusal is a regex pattern on the open z.string(), derived from a new retiredAliases column. That spelling survives the JSON Schema projection.
    • One new public export, RETIRED_DRIVER_ID_GUIDANCE.
    • The pin-sweep and false-text files beyond the claim's list are named in the report, and MAJOR_18_CONVERSIONS is untouched.
    • Declared narrowing: runtime's test:repo is left to CI per the seat's lock note.
    • This record amends the claim's surface to the PR's file list.
  5. Out-of-scope findings.
  6. Prose checked against the diff.
    • content/docs/data-modeling/drivers.mdx: the two table rows drop mongo. The new paragraph says "an authored driver: 'mongo' is refused with the prescription naming mongodb" (DriverType's guidance regex) and "stored datasource rows keep loading" (the rehydration seams replay the retired conversion, per DriverType's docblock).
    • The five secret-key rows now read mongodb only.
    • packages/drivers/driver-mongodb/README.md: "recognised value: mongodb; the old mongo spelling was retired in @objectstack/spec 18 and is refused".
    • The changeset: BREAKING, with the migration list and the stored-row paragraph.
    • The bump levels (spec minor, driver-mongodb patch) are the contract review's ②.
  7. The dev's open question (should the PR body line carry the arm?): B, it stays Clause-②: yes. The claim line's machine spelling is exactly yes or no. The (narrowing) arm lives in the changeset, where the ADR-0087 gate read it green.
  8. Landing terms. First a contract review PASS at CONTRACT_REVIEW_TIER on the head, then every check green, then the seat marks the PR ready and enables auto-merge. needs:contract-review stays on this PR until then. On merge, spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543 is released to pm:queue with F5-jsx, F3, F2, F4 and F5-http left.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: acf0e6c1faddeadab933358e5bedaa3fae075f2f
Local-runs: none

Family F1 of ruling 6182001882 on card #23543, PR #23600, read at 2026-10-15T04:49Z. Inputs: the card body and its nine comments, the PR body and its 23-file list, the net diff against main at merge-base 32e03d2fd (+557/−162, equal to the three-dot diff against origin/main), and the 45 check-runs on this head. Nothing was built, run or re-run; every tree reading below is git show / git grep against the fetched head.

Gate verdicts on this head: 45 check-runs, 37 success, 8 skipped, 0 failing or pending. The five required contexts — Lint & Repo Gates, TypeScript Type Check, Test Core (and 1–6/6), Build Core, Governed Surface Queue Guard — are all success; so are Check Changeset, Spec property liveness, Dogfood Regression Gate, the four Type Check · lanes, the nine Lint · lanes, and the card, claim and single-writer guards. The 8 skipped are the PR fast-set skips (Console Pin Gate, Temporal Conformance (live PG + MySQL), the dogfood shards and Dogfood Verify CLI, the opt-in packed-tarball smoke, and the re-fired Auto Label / Check PR Size duplicates); those families are main's full battery and are NOT MEASURED on the PR by design. Correction to the dev report (6184434243): it lists Console Pin Gate and Temporal Conformance among the successes; on this head both are skipped.

Governance: none of the 23 paths is in GOVERNED_SURFACES (register read on the head); head repo equals base repo; 719 changed lines; no content/docs/releases/ edit; Part of #23543 is the first line and no closing keyword follows; draft; the assignee mirrors the card's.

① Derived judgments

Accept-set changes (each narrows what an author or operator may write):

  1. DriverType refuses mongo by name (packages/spec/src/data/datasource.zod.ts): z.string() gains one .regex() per RETIRED_DRIVER_ID_GUIDANCE key — for mongo, a negative lookahead over the whitespace-trimmed, case-folded spelling, with the prescription as the message. Refused: mongo, Mongo, MONGO, a tab-and-newline-wrapped mongo; still accepted: mongodb, every other builtin, com.vendor.mongolike, xmongo, mongo.v2, __proto__, constructor, and the empty string (as before). Reported as zod invalid_format at path driver, and the config gate still runs behind it (driver and config both reported on a misspelled key), so the refusal hides nothing. At defineStack it is STACK_SCHEMA_INVALID / 422 with one issue at datasources.0.driver. RIGHT — this is ruling F1 A's "refused with the prescription naming mongodb", at every door that parses a datasource. The open namespace stays open (a z.string(); enumWithRetiredValues cannot carry it), and the regex spelling — not a refinement — is what lets the refusal survive the JSON Schema projection as a pattern (pinned in config-registry.test.ts), so a document validated against the published json-schema/** is refused too. The schema's input type is still string; tsc cannot carry a value refusal on an open string, so the parse-time prescription is the whole channel here, as ruling item 7 says.
  2. Selection face narrows (config-registry.zod.ts): the mongodb row's aliases drop mongo; DATABASE_DRIVER_SELECTION_ALIASES goes 14 → 13; resolveDatabaseDriverId('mongo') → undefined; DATABASE_DRIVER_SELECTION_IDS unchanged. Both boot hosts read that one table (packages/runtime/src/standalone-stack.ts DatabaseDriverSelectionSchema through resolveDatabaseDriverId; packages/cli resolveDriverType and database-driver-flag.ts through the selection faces), so OS_DATABASE_DRIVER=mongo, databaseDriver: 'mongo' and --database-driver mongo are all refused with the hosts' "Supported drivers" list, which names mongodb. RIGHT; the cross-host parity pin (driver-vocabulary-parity.test.ts) is flipped to assert exactly this. The dev's acceptance note holds: the host refusal is the generic list, not a dedicated prescription sentence; the list names the right spelling, and RETIRED_DRIVER_ID_GUIDANCE is exported for a host that wants to name it later.
  3. datasource-driver-mongo-to-mongodb leaves the load path (conversions/registry.ts): retiredFromLoadPath: true, retiredAfter: '17.7.0'. The authoring funnel no longer rewrites an authored mongo (the new test asserts the stack unchanged and zero notices), so the author meets judgment 1 instead of a silent rewrite with a notice. Data at rest keeps replaying it: applyConversionsToStoredItem (includeRetired pinned true), the artifact door, and os migrate meta --from 16 — the id is already a step-17 conversionIds member (migrations/registry.ts.template:1126), ordered after datasource-config-driver-key-aliases, which still reaches a stored mongo row's legacy keys because of judgment 5. RIGHT. '17.7.0' is the value conversions/types.ts's own retiredAfter docblock gives for an 18.0.0-next.N label (the package reads 18.0.0-next.1), it matches the seven spec(conversions): 15 ADR-0087 D2 conversions are still on the load path at 18 though their window closed (10 toMajor: 17, 5 older): retire each or record why it stays, one verdict per entry (family closing card after #23421) #23487 retirements, and retired-after.census.test.ts pins it against the published tarballs.
  4. Verdict-list pin (conversions.test.ts): the entry moves from the kept list (now 7 entries, the five remaining families) to the retired list with retiredAfter: '17.7.0'; the describe block now asserts the four facts that must hold together — a stored row still converges and then parses; the funnel no longer rewrites; an authored mongo meets the prescription at defineStack; an unconverted stored row keeps its contract. The removal-version pin (retired-key-removal-version.pin.test.ts) gains the entry's refusal row in its JOIN, so every retired entry still has a renderer. RIGHT — ruling item 7's "verdict-list pin updated", and the kept-without-ruling list shrinks by exactly one.
  5. Contract face kept — not an accept-set change; judged in ③ below: DRIVER_ID_ALIASES still maps mongo → mongodb (now through the new retiredAliases column instead of aliases), so resolveDriverId('mongo'), getDriverConfigSchema('mongo') and validateDriverConfig('mongo', …) answer exactly what they answered before. Pinned both ways in config-registry.test.ts: a retired spelling is no row's live id or alias (so the refusal can never fire on a legal value), and every retired spelling still resolves a contract; the anti-vacuity line asserts the table carries exactly ['mongo'].

Public-surface changes (widenings):

  1. New export RETIRED_DRIVER_ID_GUIDANCE — a frozen read-only record, retired spelling → prescription (api-surface/data.json +1, export-origins/data.json +1). RIGHT — DriverType reads it cross-module through an import datasource.zod.ts already had, so no new cycle; this is the one widening the body's Clause-②: yes declares.
  2. DriverVocabularyEntry.retiredAliases?: RetiredValueGuidance — an optional member added to an exported interface; additive for every reader; the as const satisfies row still type-checks. RIGHT. Reusing RetiredValueGuidance keeps one prescription vocabulary with enumWithRetiredValues instead of a second.
  3. Published JSON Schema data/Datasource gains pattern on driver. json-schema.manifest/data.json is a names-only list (data/Datasource), so no manifest regeneration is owed and none is missing; the projection itself is built, not tracked, and the pattern is pinned. RIGHT.
  4. D3 entry 18.datasource-driver-mongo-alias-retired.ts — a SemanticMigration in the sibling shape (375 18.* entries beside it), conversionIds: ['datasource-driver-mongo-to-mongodb'], naming what the chain cannot reach (OS_DATABASE_DRIVER, a standalone stack's databaseDriver, REST writers). gen:migration-registry writes the gitignored registry; check:spec-changes and check:upgrade-guide rode green. RIGHT — the family's one D3 entry, which the registry docblock records the 17 rename never had.
  5. Docs and comments: content/docs/data-modeling/drivers.mdx (two table rows drop mongo, one retirement paragraph), packages/drivers/driver-mongodb/README.md (published, hence the patch row), the liveness/datasource.json note, and comments in driver-catalog.ts, mongo.zod.ts, mongo.test.ts and cli/src/utils/config.ts. RIGHT. A head-tree sweep for residual mongo writers outside tests finds only these, one historical quotation already marked false (mongo.zod.ts:26 and its generated reflection), and datasource-credential-redaction.ts:203, whose "a stored legacy driver: 'mongo' row is scrubbed identically" stays true under judgment 5. content/docs/references/ is untouched (the mongo.zod.ts edit is a code comment, not a .describe()), and the release page the drift-check flagged read-only was correctly not edited.
  6. Four load-path suites re-pointed (stack-authored-input.test.ts; cli migrate-meta-load-conversions, migrate-meta-composed-load-conversions, and the load-path case of migrate-meta-composed) from driver: 'mongo' onto a flow-level errorHandling.retryDelayMs, renamed by retry-policy-converged (live, a step-17 member). RIGHT for F1: these suites test the authored-input shim, which needs a spelling the load still converts, and mongo no longer is one. Two fixtures in datasource.test.ts move to mongodb with unchanged assertions. The cost is named in ③.

② Semver level

  • .changeset/23543-f1-retire-mongo-driver-alias.md: @objectstack/spec: minor, @objectstack/driver-mongodb: patch; summary feat(spec)!:; **BREAKING (authoring):** banner; Clause-②: yes (narrowing); FROM → TO for all three places the spelling lives; the os migrate meta --from 16 sentence; the ADR-0087 disposition marker registered datasource-driver-mongo-alias-retired. RIGHT. The repo is in Changesets pre mode (.changeset/pre.json, tag next), where a BREAKING spec change grades minor; the two precedents on the head, 23421-retire-page-aliases-at-18.md and 23487-retire-overdue-conversions.md, carry the identical frontmatter, banner and arm shape. check-adr-0087-registration reads it as BREAKING+bang+clause-②-narrowing, registered; Check Changeset is success. The patch for driver-mongodb matches a published README text change. cli and service-datasource moved only comments and need no row; the hosts' refusal change is the spec row's and is described there.
  • The Clause-②: line. The changeset's yes (narrowing) is the right arm: the diff widens one surface (judgment 6) and narrows others (judgments 1–3). The PR body's line reads bare Clause-②: yes, which scripts/pm/clause2-line.mjs defines as "a widening" with no arm. That is true of the diff but not the whole of it, and ruling item 7 spells the arm. It is not a false declaration and no gate's verdict turns on it (check-changeset-no-major reads the body's yes and finds @objectstack/spec at minor; the breaking-signal reader takes the arm from the changeset), so it does not fail this record — but the body line is the PR-scoped carrier and should read Clause-②: yes (narrowing) before the PR is armed. See ③ item 1.

③ Boundary flags

Dev open_questions (6184434243):

  1. Should the PR body's Clause-②: yes gain the arm? Answered: A. The owning seat amends the body line to Clause-②: yes (narrowing) — one line, the body read back after the write, no second footer (AGENTS.md's PR-body rule). Where the gap came from: the claim comment 6182201116 itself wrote Clause-②: yes, and the dev copied it as instructed, so the dispatch's line is what is short, not the dev's copy. Not a verdict condition, for the reasons in ②.

Dev deviations:

  1. Mechanism assumption 1 changed route — the alias left selection and authoring but kept the contract face, instead of being deleted. Accepted as the right call, and the seat review's open question — is the remnant a "double spelling" under ruling item 7 — is answered NO. Item 7's "no staged window and no double spelling" governs what the doors accept from an author or operator; after this PR nothing an author or operator writes is accepted as mongo: the parse refuses it, both hosts refuse it, the published JSON Schema refuses it. What remains is the data-at-rest resolver, the same posture the retired in-memory engine's spellings already hold (contractOnlyAliases), and it is load-bearing: datasource-credential-redaction.ts keys its mongodb passthrough-secret table by canonical id through resolveDriverId (:231, :245, :378), and datasource-credential-redaction.test.ts:341 and :481 pin a stored legacy mongo row's scrub. The dev's measurement — with the alias deleted, a raw stored legacy row served all ten mongodb passthrough secrets in cleartext — is the failure those pins exist to catch. Ruling F1's "stored rows are rewritten once by the D3 chain" describes the row after the chain reaches it; the kept face protects the raw read path before then, and ADR-0087's addendum already has every data-at-rest seam replaying retired entries. The guard against this face ever becoming a second accepted spelling is pinned: a retiredAliases key may be no row's id or alias.
  2. The refusal is a regex pattern, not enumWithRetiredValues; a first superRefine was refused by the dropped-refinement gate. Accepted — driver is an open z.string(); a refinement would not project; pattern does and is pinned; the prescription type and its writing conventions are the helper's.
  3. New public export RETIRED_DRIVER_ID_GUIDANCE. Accepted (judgment 6); declared in the changeset and by the body's yes.
  4. Files outside the claim's literal list. Accepted — each is a pin-sweep or false-text hit named in the report; the diff's only registry.ts hunk is the datasource-driver-mongo-to-mongodb docblock and its two new fields; MAJOR_18_CONVERSIONS and every other entry are untouched, as the claim required.
  5. Declared narrowing: runtime test:repo left to CI after the PM's lock note. Accepted — Test Core 1–6 and the aggregate are success on this head.
  6. A locked closure build killed by timeout 590 and re-run clean; the harness's model-named trailer not used. Accepted — process notes; check:commit-card-trailers rode green on every push.

Dev out_of_scope_findings:

  1. check:platform-checklist red on origin/main's tree, zero overlap with this diff. Kept out of per-PR CI by decision; the seat review names the watchdog's card (check:platform-checklist is red on main #23593) as the owner. Not this PR's.
  2. After this PR the load-path conversions os migrate meta --from 16 replays are retry-policy-converged and F3's two lifts; the four re-pointed suites lose their last real subject when F2 and F3 land. Escalated to the F3 and F2 dispatch orders on spec(conversions): eight ADR-0087 D2 conversions stay on the 18 load path after #23487 — five families each need a ruling before they can retire #23543, as the seat review already carried it: whichever of those PRs lands last must give the authored-input shim a synthetic probe or retire the suites. The fixtures state maxRetries: 3, so F2's loud form does not touch them; it is the retirement of the retryDelayMs rename that removes their subject.

Report corrections, not flags: the dev report counts 41 check-runs with Console Pin Gate and Temporal Conformance among the successes; on this head there are 45 (re-fired label and size runs), and those two are skipped on the PR, measured by main's full battery. No gate verdict changes.

Premise re-read on the head: no examples/** or packages/apps/** source authors driver: 'mongo'; the Setup catalog's id is mongodb. F1 names no objectui follow-up and this PR owes none.

Implemented-by: claude/issue-23543-retire-mongo-driver-alias
Reviewed-by: session_01LFqdRsuM5nkqoJdHd5ztVk

VERDICT: PASS

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 38683849777 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test Core (6/6) — 失败步骤: Run this shard's tests

    @objectstack/runtime:test:  FAIL   local  src/package-uninstall-shared-object.integration.test.ts > [#23473] DELETE /packages/:id of a package whose object another stored row also holds > without keep
      ↳ 失败原因: @objectstack/runtime:test: Error: Cannot layer object 'probe_ticket': the overlay is bound to package 'com.probe.q', but the object is owned by package 'com.probe.p'. An object has exactly one registr
    @objectstack/runtime:test:  FAIL   local  src/package-uninstall-shared-object.integration.test.ts > [#23473] DELETE /packages/:id of a package whose object another stored row also holds > the way out,
      ↳ 失败原因: @objectstack/runtime:test: Error: Cannot layer object 'probe_ticket': the overlay is bound to package 'com.probe.q', but the object is owned by package 'com.probe.p'. An object has exactly one registr
    @objectstack/runtime:test:  FAIL   local  src/package-uninstall-shared-object.integration.test.ts > [#23473] DELETE /packages/:id of a package whose object another stored row also holds > the way out,
      ↳ 失败原因: @objectstack/runtime:test: Error: Cannot layer object 'probe_ticket': the overlay is bound to package 'com.probe.q', but the object is owned by package 'com.probe.p'. An object has exactly one registr
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 8 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Merged via the queue into main with commit bc0538a Oct 15, 2026
49 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-23543-retire-mongo-driver-alias branch October 15, 2026 05:30
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 protocol:data size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants