Skip to content

feat(service-automation, metadata-protocol, driver-mongodb, cli): a connector connection is unique per organization and instance (package, name) - #33199

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-y6vjs1
Nov 14, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-y6vjs1

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread
Part of #31699

Clause-②: yes (widening)
Metadata-protocol: none

维护者速读

What changes

  • Key. sys_connector_connection declares { fields: ['organization_id', 'connector_package', 'connector_name'], unique: 'global' }. Spelled 'global' with organization_id listed, as plugin-security + runtime: the grant, clone and activation doors take a permission set's package and report a two-holder name with its candidates (ADR-0150 D3/D8; before #31698 PR-2) #32164 spelled the grant's, because driver-sql's widening arm (widenedUniqueReplacements) does not fire for 'organization' (measured: that spelling plans a destructive orphan drop). The arm keeps the old key until a partial guard on exactly (organization_id, connector_name) stands, then plans one replace_unique_index, safe, create-before-drop.
  • Guard. uniq_sys_connector_connection_packageless, built at objectql:schema-synced on every kernel that runs the table's DDL (metadata-protocol plugin.ts): partial index on SQLite and PostgreSQL, functional digest on MySQL 8.0.13+, INVISIBLE generated column on MariaDB 10.3+, RUNTIME_OWNED_UNIQUES on MongoDB (keyed (connector_name), the key Mongo materialized for the old declaration). Listed in runtime-index-preflight.ts (so os migrate duplicates) and in the CLI's schema-sync-indexes.ts (so os migrate plan / apply). The module is a copy of user-permission-set-packageless-index.ts with the table's constants and wording.
  • Store. A first connect that counts a second row of its instance after its insert (the boot backfill stamped another connect's row between this one's read and insert, which the old key refused) deletes its own row and is refused. Everything else in the store is unchanged; carrying the package is the next PR.
  • Backfill (R11) and bind. A bind whose update is a unique violation, confirmed by a read of the row of that key already naming the holder, is left and reported (duplicated), and the walk goes on; the dry run agrees. os migrate stored-references bind refuses it as duplicate.
  • Docs. content/docs/deployment/cli.mdx (runtime-owned indexes, old-key retirement, MySQL limit, the bind refusal); content/docs/automation/connectors.mdx (one connection per organization and instance).

Why

ADR-0150 D4: a connector instance is identified by (package, name), and D8 row R11 gives the connection its package column. The maintainer ruled on #31699 that a connection is unique by package and name, so one organization can connect both packages' instances of one name once the backstop narrows (the last PR of #31699).

Verification

  • Booted kernel (service-automation connector-connection-guard-at-schema-sync.test.ts, real ObjectQLPlugin, SQLite, the shipped object): a second package-less connection written from a start() before kernel:ready is refused, two packages' connections of one name are admitted, a second of one package's is refused; with bootPhaseHooks: false too; a dropped guard is rebuilt by the next pass. Ablation (guard call removed from the hook): 3 of 5 red.
  • driver-sql sql-driver-widened-connection-key.test.ts: SQLite (no guard → old key kept; guard → one safe replace; re-plan empty) and live PostgreSQL 16 locally; the MySQL cell pins the declared limit (old key kept) and runs on main.
  • Guard module: 33 unit tests; live PostgreSQL test green locally; live MySQL suite runs on main. driver-mongodb 4 tests (live mongod not reachable here); driver-memory 3 (declared limit).
  • Store race: pin + control in connector-connections.test.ts (ablation red). Backfill: 3 new pins in stored-reference-package-column.test.ts (dry run agrees, unconfirmed violation and an R8 violation end the pass; each red under ablation).
  • Full suites: @objectstack/service-automation 3843 passed (before the review round; affected files re-run, 409 passed), @objectstack/metadata-protocol 339 files passed. CLI: schema-sync-indexes, duplicates.contract, stored-references, apply.schema-sync-indexes, schema-migrate.grant-guard green. Build with declarations, tsc --noEmit and check:test-typecheck green for every touched package.

Red-line read

Run in this thread by a separate review pass (maintainer's instruction: 「你自己有fable,自己审就可以了吧?」). Design round: PASS-WITH-CHANGES (M1–M7, S1–S9, taken). Code round 1: PASS-WITH-CHANGES, no must-fix, 7 should-fix (a racing first connect could leave two rows; dry run vs real run; backfill catch confirmation; docs and changeset wording), all taken. Round 2 (delta): PASS, one should-fix (foreign messages on the new count and delete) and two changeset notes, taken. Carried to the next PR: the store reads and counts by package.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT

…tor connection unique per organization and instance (package, name)

ADR-0150 D4 and D8 row R11, storage half. The maintainer's ruling: a
connection is unique by package and name.

- sys_connector_connection's key widens from (organization_id,
  connector_name) to (organization_id, connector_package, connector_name),
  spelled 'global' with organization_id listed, so driver-sql's widening
  arm replaces the old key (safe, create-before-drop) once the guard stands.
- uniq_sys_connector_connection_packageless keeps the connections that
  name no package to one per (organization_id, connector_name), built at
  objectql:schema-synced as the grant guard is, on SQLite, PG, MySQL
  8.0.13+, MariaDB 10.3+ and MongoDB; listed in the runtime-index
  preflight, os migrate duplicates and os migrate apply's steps.
- A first connect that raced the backfill takes its second row back and
  is refused, as the old key refused it.
- The R11 boot backfill leaves a row whose bind would be a second row of
  one key and reports it (duplicated) once a read confirms it; the dry run
  agrees; os migrate stored-references bind refuses it as 'duplicate'.
- Declared limits: upgraded MySQL 8 keeps the old key (driver-sql reads the
  functional key part as an expression, as for the grant); driver-memory
  builds no guard.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 14, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT

Posted 2026-11-14T01:53Z. Red-line read run in the card thread on the maintainer's instruction, by a separate review pass: design round, code round 1, code round 2 (delta).

Contract review

Served-tier: TIER_DEFAULT
Head-sha: 2dfdbbe5b9d93e239fc91b0117b04c82f3a2f1bf
Local-runs: none

① Derived judgments

  • No moment without a unique rule, on any dialect. widenedUniqueReplacements keeps the old (organization_id, connector_name) key while the gained nullable connector_package has no partial guard on exactly those columns, then plans one replace_unique_index, safe, create-before-drop. The old key's generated name is 60 characters, unhashed, and equals CONNECTOR_CONNECTION_OLD_KEY_INDEX_NAME. MySQL 8 keeps the old key (functional key part read as an expression); MySQL before 8.0.13 and MariaDB before 10.3 build or find the old key. On Mongo the old index is idx_connector_name_unique on (connector_name); the guard on (connector_name) filtered connector_package: null satisfies hasNullScopedGuard, is created before the retire, and a failed create keeps the old index.
  • The guard module is the grant module's copy. Normalised for table and type names, it differs only in constants, the two-column key, wording and docblocks.
  • Single-holder behaviour unchanged. The store still reads and writes by organization and name, and every row it inserts names no package. The one new state the wide key admits (a first connect racing the boot backfill leaves a packaged and a package-less row of one instance) is taken back: the connect that counts two rows after its insert deletes its own row and is refused, as the old key refused it. Both racing connects can be refused; nothing is guessed.
  • Backfill and bind never guess. R11 reports a bind's unique violation as duplicated only after a read confirms the row of that key already naming the holder; any other failure, and any violation on R8 or R9, ends the pass. The dry run counts the keys it bound in the pass, so it lists what the real run lists. The CLI bind refuses duplicate and rethrows anything else.
  • Pins discriminate. Booted-kernel guard pin (3 of 5 red with the hook call removed), store race pin, three backfill pins (each red under its ablation).

② Semver level

patch on @objectstack/metadata-protocol, @objectstack/service-automation, @objectstack/driver-mongodb and @objectstack/cli, Metadata-protocol: none, Clause-②: yes (widening): right. What widens is additive: a second runtime-owned index in os migrate plan and apply, a probe in os migrate duplicates, the bind refusal duplicate, and the exports and types the changeset lists. No authorable schema key moves, so the ADR-0087 not-required marker holds. Nothing the old key admitted is refused, so there is no narrowing.

③ Boundary flags

  • Declared limits. Upgraded MySQL 8 databases keep the old key (shared with the permission-set grant guard; a driver-sql recognition fix is owed as its own card). driver-memory builds no guard. MariaDB retirement is read from source, not measured; the MySQL, MariaDB and live-mongod pins first run on main.
  • Carried to the next PR of the card (3a-ii). The store reads, counts and revokes by package; the connect door and the OAuth callback carry the resolved package; a pair left by a process that died between insert and take-back is refused by an explicit two-row read.
  • Accepted nits. MySQL-family digest is byte-exact where the old key followed the collation; a SQLite rebuild leaves a boot-time window until the hook rebuilds the guard; an old-release replica rebuilds the retired key during a rolling deploy; driver pins use reduced schemas; connectors.mdx states the storage key before the store reads by it. The first three are shared with plugin-security + runtime: the grant, clone and activation doors take a permission set's package and report a two-holder name with its candidates (ADR-0150 D3/D8; before #31698 PR-2) #32164.

Findings by round: design PASS-WITH-CHANGES (M1 to M7, S1 to S9, taken). Code round 1 PASS-WITH-CHANGES, no must-fix, seven should-fix, all taken. Round 2 PASS, one should-fix (foreign messages on the new count and delete) and two changeset notes, taken. Open at this head: none.

Implemented-by: claude/project-thread-y6vjs1
Reviewed-by: session_01L9qibzKCovWpJoMZD6U3NT

VERDICT: PASS

@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, @objectstack/driver-mongodb, @objectstack/metadata-protocol, @objectstack/service-automation, touching 59 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/metadata-protocol/src/index.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/connectors.mdx (via sys_connector_connection (symbol, a field of const object RUNTIME_OWNED_UNIQUES), sys_connector_connection (literal, a string literal in CONNECTOR_CONNECTION_TABLE; a string literal in STORED_AUTOMATION_REFERENCES; a string literal in object))
  • content/docs/deployment/cli.mdx (via sys_connector_connection (symbol, a field of const object RUNTIME_OWNED_UNIQUES), connector_name (literal, a string literal in CONNECTOR_CONNECTION_PACKAGELESS_INDEX_COLUMNS; a string literal in STORED_AUTOMATION_REFERENCES; a string literal in a comment on a changed line; a string literal in indexes; a string literal in nameColumn), connector_package (literal, a string literal in STORED_AUTOMATION_REFERENCES; a string literal in indexes; a string literal in packageColumn), sys_connector_connection (literal, a string literal in CONNECTOR_CONNECTION_TABLE; a string literal in STORED_AUTOMATION_REFERENCES; a string literal in object))
  • content/docs/frontend/plugins/plugin-grid.mdx (via nameColumn (symbol, a field of const object STORED_AUTOMATION_REFERENCES))
  • content/docs/kernel/services-checklist.mdx (via assembleMetadataProtocol (symbol, a top-level function))
What this run could not see
  • 1 changed file(s) yielded no anchor (packages/metadata-protocol/src/index.ts) — pages documenting those are invisible to this run
  • 1 anchor(s) matched too much of the corpus to be a work list: organization_id (literal, 40 pages)
  • 5 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 65 of 247 client-bound route-ledger rows — the other 182 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 182: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 59 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 123 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 — 51 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 67274acad689d5be75d5bfc5007f4fb9396aa907 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 67274acad689d5be75d5bfc5007f4fb9396aa907

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

… asserts; tenant-audit census counts the take-back delete

The take-back delete in ConnectorConnectionStore#connect is one more write
call site (elevated, against sys_connector_connection): census regenerated
and the page's prose figures moved with it. The race pin's double opens its
update and delete with assertEngineUpdateDispatch / assertEngineDeleteDispatch,
and the engine-double ledger records it.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
…rrorText callers, pinned by its own sentinel test

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
…nector connection guard beside the grant's

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibzKCovWpJoMZD6U3NT
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

Delta review over record 6869740710 (head 2dfdbbe5, PASS). Scope: git diff 2dfdbbe5 pr33199 on the PR's own files, three commits (2f488ab, 6a74372, f5d2a9e) answering CI reds. Main not merged in. All 9 delta files are on the PR's file list.

Contract review

Served-tier: TIER_DEFAULT
Head-sha: f5d2a9e370b3bd8d92a4fb1b52f7830f394dd230
Local-runs: none

① Derived judgments

This is a delta over 6869740710 at 2dfdbbe. The red lanes at 2dfdbbe were the engine test-double contract gate (inside Lint · ESLint), the tenant-audit census gate (inside Lint · repo & tooling gates), and the umbrella Lint and TypeScript lanes that roll them up. Type Check · workspace was cancelled, not failed. The delta answers those gates and the three CLI count pins. No assertion is loosened.

  • Store race pin's engine double (connector-connections.test.ts). The racing double's update and delete now call assertEngineUpdateDispatch and assertEngineDeleteDispatch before forwarding, like the file's other two doubles. Both are already imported from @objectstack/metadata-core. The race test's expects are unchanged. This tightens the double. engine-double-contract.pinned.json goes from 2 to 3 for both verbs in that file, which matches the 3 asserting doubles per verb now in the file. The double is pinned, not baselined: engine-double-contract.baseline.json is untouched.
  • Tenant-audit census. The PR adds one write site, the take-back delete at connector-connections.ts:361: engine.delete(CONNECTOR_CONNECTION_OBJECT, { where: { id: insertedId }, context: SYSTEM_CONTEXT }). CONNECTOR_CONNECTION_OBJECT is an exported const, and SYSTEM_CONTEXT is a local const with isSystem: true. So the site is const-named, decidable, against a tenancy-enabled object, carries a context that is decidably elevated, and is reached through a typed receiver. Each enforced count moves by exactly +1: 311→312, decidable 216→217, enabled 209→210, threading context 240→241, elevated 174→175, readable engine receiver 249→250, const-named 85→86. Undecidable (95), provably-none (12/3), unreadable (59/32) and run-time elevation (125) do not move, which is right for this site. The site list gains exactly one row (delete · sys_connector_connection · enabled · elevated). The connector-connections.ts rows go from 3 at merge-base 16e34864 to 4. The prose figures in the .mdx (3 / 312, 175 of 312, 59 of the 312, 86 const) follow the table. The corpus-scale block (1157 / 138 / 296) is marked not enforced and is dated at 2dfdbbe5b. Between that commit and the new head, the only non-test source change is a docblock, so the measurement holds at the new head.
  • operatorFacingErrorText callers row. The row for connector-connection-packageless-index.ts says calls: 3. Source at head has 3 call sites (lines 397, 472 and 489), the same count as the grant module it copies. Its sentinelPin, connector-connection-packageless-index.test.ts, already existed at 2dfdbbe and binds SENTINEL-21418-BOUND-VALUE, which is what the row's sentinel check requires. The change only adds a row. Nothing is removed or relaxed.
  • CLI counts.
    • duplicates.integration.test.ts: toHaveLength(6) becomes toHaveLength(7), and a new toContain('ensureConnectorConnectionPackagelessIndex') is added beside the grant's. That is stricter.
    • duplicates.contract.test.ts: only the it title changes, six to seven. Its exact toEqual list already named the seventh entry at 2dfdbbe.
    • schema-sync-indexes.operator-text-21418.test.ts: both cases replace toHaveLength(1) plus checks on steps[0] with an exact, ordered toEqual on the two migration names, then run every per-step expect (status unreadable, diagnostic present, sentinel absent, composed text absent) on each step. Every original expect survives. The length is now implied by the exact list. statements.at(-1) still tests the last guard's catalog read. This matches SCHEMA_SYNC_INDEX_OWNERS at head, which has two entries, grant then connection.
  • The counts are right. runtimeIndexProbes at head lists six migrations. The overlay migration builds two indexes, so there are seven indexes. Schema sync builds two guards.

② Semver level

This is a delta over 6869740710 at 2dfdbbe. The only non-test source change is in packages/metadata-protocol/src/migrations/runtime-index-preflight.ts, and it sits entirely inside a /** */ docblock: "SIX, from five migrations" becomes "SEVEN, from six migrations (the grant's and the connector connection's at schema sync…)". Behaviour does not change. The prose is now accurate. No changeset, export, schema or authorable key moved. The prior judgment stands: patch on the four packages, Metadata-protocol: none, Clause-②: yes (widening).

③ Boundary flags

This is a delta over 6869740710 at 2dfdbbe. Nothing in the delta touches the declared limits, the carry-forward to 3a-ii, or the accepted nits in that record. Nothing here contradicts its PASS. The race pin is stronger, not weaker.

Check-runs on f5d2a9e3 (read 2026-11-14T03:36Z): 37 runs. 10 success, 9 skipped, 0 failure, 18 in progress. The in-progress runs are Build Core, Build Docs, Build UI Deps, Check Changeset, Lint · CI, release & engine gates, Lint · ESLint, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped (×3), Live E2E UI, Plan Test Core shards, Plan Test UI shards, and Type Check (consumer gates, debt ledger, source gates, workspace). The lanes that carry the gates this delta answers are among them, so this record judges the diff, not a green run.

Findings: none (must-fix 0, should-fix 0, nit 0).

Implemented-by: claude/project-thread-y6vjs1
Reviewed-by: session_01L9qibzuZJBQY4wUQFJbkfx

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx

维护者速读 · PR #33199 @ f5d2a9e3 · 2026-11-14T04:05Z

席位核对

  • 形态: draft → main。正文写 Part of #31699,合并后卡保持打开(3a-ii、3b 和收窄 PR 还在后面);正文其他地方没有挨着别的 open 卡号的闭合关键词。
    • 申报 Clause-②: yes (widening)、Metadata-protocol: none。
    • 文件面 = 接管认领 6857670747,加修订 6869794919(3a-i 的文件面)。
  • 前提实测: dev 报告 6869754560。真实启动的内核(SQLite、真 ObjectQLPlugin)上测过三件事:kernel ready 之前第二条无包连接被拒;两个包的同名连接都被接受;同一个包的第二条同名连接被拒。另有 driver-sql 的 SQLite 与本地 PostgreSQL 16 加宽计划钉;MySQL 的那一格钉住已声明的限制。
  • 门禁 check-runs @ f5d2a9e3: 58 success、10 skipped、0 失败、0 进行中。
  • 契约复审: TIER_DEFAULT(申报面)。
    • 全量记录 6869740710 在 2dfdbbe5 上 PASS。
    • delta 记录 6871104474 在 f5d2a9e3 上 PASS,没有发现。它覆盖三次提交(2f488ab8、6a743724、f5d2a9e3),都是为了 CI 红而补的测试计数,没有放松任何断言:
      • 竞态钉的引擎替身经过派发断言,钉表 2 → 3;
      • 租户审计普查对新增的一处删除精确地 +1;
      • operatorFacingErrorText 调用方表加一行,calls: 3 与源码一致;
      • CLI 的预检数 6 → 7,列表步骤 1 → 2,改为按迁移名精确比对;
      • runtime-index-preflight.ts 只改了文档注释。
    • objectql: narrow the phase-1 one-holder refusal from environment to namespace for webhook, connector and email_template (ADR-0150 child B, webhook family) #31699 线程另有 Tesla 指示的 Fable 红线审读(设计轮与代码两轮,正文已列)。
  • 接受的偏差:
    • 文件面修订 6869794919 是在 PR 开出之后补贴的,不是事先认领。
    • 为过门禁而动的文件不在原面里:tenant-audit-census.mdx 与普查计数文件、scripts/engine-double-contract.pinned.json、packages/types 的调用方测试、CLI 的四个测试文件。每一处都是对应门禁强制要求的。
  • 范围外去向: MySQL 8 升级库的旧键 → driver-sql: on an upgraded MySQL 8 database the widening arm never accepts a functional-digest package-less guard, so the old narrower unique is kept and a second package's row of one name is refused #33201;3a-ii(连接存储、连接门与 OAuth 回调带上包)在本 PR 合并后推送,文件面见第二次修订 6869821095;3b 见第三次修订 6870521528;ConnectorDescriptor.packageId、运行时 ?package= 门、核心类型集与一持有者兜底的收窄留给最后的收窄 PR。
  • 落地条款: 维护者常设落地令 「按 pm-dispatch 审过的pr你可以自主落地」 (2026-10-30T14:20Z);本卡按「接手 31699」 (2026-11-13T15:34Z) 由本席接手。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 14, 2026 04:06
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 14, 2026
Merged via the queue into main with commit 0b89b33 Nov 14, 2026
69 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-y6vjs1 branch November 14, 2026 04:33
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/xl tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants