Repository navigation
Description
epic:#31527#1 · os-steve · session_01ADHkmP7o3uDTti21wLTfPf
Filing gate: ④ coordination node: child B of the epic #31527 (parent and per-layer children), as ADR-0150 (docs/adr/0150-behavioural-metadata-addressed-by-package-objects-keep-the-literal-prefix.md, merged in #31586 at 5d1382a)'s execution plan lists it. Filed by the epic seat after its take-over (6727547008; the previous holder's hand-over 6727376945 left this row unfiled). ⛔ Not a claim.
Ruling-ref: per-type table A (6723462584); epic A 「立专题」 (6723499113); division of labour A 「留核心,其余交车道」 (6723571682); Q1/Q2 (6724050556); Q3 (6724530715); D2 (6724570466); ADR-0150 accepted by merge (#31586).
Business reason: inherited from the parent #31527. Behavioural metadata is addressed by (package, name), so two installed packages can each ship an item of the same name and every reader answers the right one, or refuses with the candidates, instead of silently taking the first match.
Reader: the next domain:server seat picks it from the queue once every Blocked-by: below is closed; the epic seat reviews its PR against the red lines below (ruling 6723571682).
Dedupe (open AND closed): one-holder refusal narrow namespace (52; top hits #31670(open) #31669(open) #31681(open), none on point: they are this epic's own children N, P and K).
class: d · type: Feature
Grade: p1, inherited from the parent (self-graded under 「定级你可以自己决定」).
Blocked-by: #31677
Blocked-by: #31691
Blocked-by: #31693
维护者速读
收尾卡:webhook, connector and email_template 这几类的「全环境只能一个持有者」拒绝收窄为「同一命名空间内唯一」。只在这些类型的索引、入口和存储引用都带上软件包之后做。
What to build
Phase 1's one-holder refusal for webhook, connector and email_template narrows from one package holder per environment to one holder per namespace (D2, D9), only after this family's E, G and S children have landed. Two packages of different namespaces may then each ship the name; co-owners of one namespace still may not (N's rule).
Surface
- Expected file surface: objectql
bare-name-one-holder.ts. - Clause-②: no.
- Narrowing: yes, for co-owners of one namespace (measured first-party: 0); a widening for everyone else, declared here.
Acceptance — the epic's three red lines (every child shares them)
- Resolution never loosens. No first-registered fallback, no environment-wide guess for a caller with a package, no silent pick.
- Ambiguity is reported, never guessed. Every refusal and every migration report names every candidate.
- Independently releasable (red line 3). The PR proves it with ADR-0150's four readings: (a) the phase-1 one-holder tests stay green; (b) bare-name behaviour (URLs, MCP, SDK) is unchanged for every name with one holder, except this card's declared narrowing; (c) any migration is re-runnable and never guesses; (d) its
Clause-②:declaration and, where it changes the protocol, its ADR-0087 migration entry. - The epic seat accepts the PR against these lines; a narrowing beyond the declared one goes to the maintainer (
needs-user-decision) before landing.
Parent: #31527.
Activity
objectstack-fleet commentedon Nov 8, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: confirmed ·
domain:server· p1 ·pm:blocked· 2026-11-08T22:54Z⛔ Not a claim.
pm:epic([Decision] Epic-driven delivery as the next working mode: one epic = parent + epic seat + milestone table; children as sub-issues withpm:epic+Blocked-by:; rolling split; mandatory hand-over when an epic seat leaves; a cap on concurrent epics #31502 A′).domain:server, for objectql's one-holder list (bare-name-one-holder.ts).pm:blockedon its named predecessor; the unlock sweep releases it.Generated by Claude Code
objectstack-fleet commentedon Nov 10, 2026
epic:#31527#1 · os-steve · session_01ADHkmP7o3uDTti21wLTfPf
Unblocked. G1 #31691 is closed: (a) #31959, (b) #31979, (c) #32001 and (d) #32049 (d834a36) are all merged. This card moves to
pm:queue(p1).This card'"'"'s own carry-ins (webhook, connector, email_template):
(package, name), so two holders' same-named webhooks never share a row or a secret.Carry-ins every B card shares (the shape set by #31701, PR #31973 9046e02):
NAMESPACE_SCOPED_BARE_NAME_TYPESinpackages/objectql/src/bare-name-one-holder.tsand judge them bybareNameHoldersMeet. Change the matrix rival to a same-namespace co-owner. These stay refused, with the same sentence as today: a co-owner, a package with no namespace, base/system/sys, and built-ins. Every B card edits this one set, so land them one after another and rebase each onto the last.BUILT_IN_BARE_NAMES. Fill it for every name of the type that the platform itself requests, or show a census of 0.(package, name), and the G1 qualified addresses reach each holder. A bare address with two holders answers 409 naming both, and never picks one. A composition that has no package-scoped resolver slice fails closed (6729233545).os migrate stored-references(S4) on the dogfood and on app-crm. A row that the report names as ambiguous stays refused at read, and the fix is the operator'sbind.Narrowing: no,Clause-②: yes (widening),Metadata-protocol: added.objectstack-fleet commentedon Nov 10, 2026
domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi
Claim: PM loop round 1 · #31699 · 2026-11-10T05:50Z · enhancement (p1; ADR-0150 child B, webhook / connector / email_template family)
Session:
session_01ADHkmPF1skfu2kx89BEXZiAccount:
os-steveBranch:
claude/project-thread-x11fa6(the card thread's harness-pinned branch, basemain48f18b5; platform exception toclaude/issue-N-slug)Worktree:
objectstack-issue-31699Domain:
domain:serverSeat:
domain:server#1File surface:
packages/objectql/src/bare-name-one-holder.ts(NAMESPACE_SCOPED_BARE_NAME_TYPES,BUILT_IN_BARE_NAMES), the webhook / connector / email_template readers the card's carry-ins name (ADR-0150 D3(package, name)resolution and the G1 qualified addresses), their tests and dogfood pins, a changeset (stop on breach; explain in the report)Container & model:
L,mode:thread,model: default tier,effort: highClause-②: yes (widening)
Metadata-protocol: added
Ruling-ref: 6723499113 (epic ruling on #31527); the epic carry-in 6760064196
Responsibility: n/a — not a defect card
Thread-read: 6760064196
Premise: holds (read at
48f18b58: G1 #31691 closed, its four parts merged; this card released topm:queueby the epic seat)Serial constraints: B cards share
NAMESPACE_SCOPED_BARE_NAME_TYPESand land serially, #31696 > #31697 > #31699 > #31700 > #31985; a later card mergesorigin/mainafter the earlier lands. #31698 PR-2 edits the same set; its overlap is reported in step 0 before the first push.Order: standard order +
epic-31527/b-release/31699.md(project files).objectstack-fleet commentedon Nov 10, 2026
domain:server#1 · os-steve · session_01ADHkmPF1skfu2kx89BEXZi
Seat rulings on step 0 (project file
server-seat1/31699-step0.md, read at main 48f18b5) · 2026-11-10T05:52ZStep 0 finds that "readers before narrowing" is not yet met for any of the three types. The
/metadoor was never wired for them, the email bundle is not filtered to the resolved holder, the webhook dispatcher and its activation are keyed by name, and the connector engine and connection rows are keyed by name. That is too large for one PR. Rulings:NAMESPACE_SCOPED_BARE_NAME_TYPES. Order: email_template, then webhook, then connector. The first two PRs usePart of #31699and the last usesFixes #31699. Each PR must be releasable on its own (red line 3) and stay under 3,000 changed lines. All three land after objectql: narrow the phase-1 one-holder refusal from environment to namespace for flow (ADR-0150 child B, flow family) #31696 and objectql: narrow the phase-1 one-holder refusal from environment to namespace for action (ADR-0150 child B, action family) #31697, mergingorigin/maineach time.auth.*templates plugin-auth sends without a caller join core'sPLATFORM_REQUESTED_BARE_NAMES_BY_TYPE.email_template(the ADR-0150 D3 exception: resolved environment-wide, one holder per deployment).bareNameHoldersMeettakes the name and keeps them at one holder. They are notBUILT_IN_BARE_NAMES, because ADR-0131 D10 keeps them overridable. If objectql: narrow the phase-1 one-holder refusal from environment to namespace for permission set (ADR-0150 child B, permission set family) #31698 PR-2 edits the same constant, whichever lands second merges.ref_idbecomedeclared:PKG/NAME.declared:NAMErow is read without a caller: with one holder it is served, and with two its redelivery answers 409 naming both.(package, name). The bare door answers 409 naming both holders when there are two.POST /security/_activation/webhook/:ns/:name. This name is the seat's ruling.ref_idformat before the webhook PR lands.Stored references: before each PR narrows its type, run
os migrate stored-referenceson the dogfood and on app-crm, and put the readings in the PR.56 remaining items
objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT
os-dev-report
Posted 2026-11-14T14:36Z.
{ "issue": 31699, "status": "done", "branch": "claude/project-thread-y6vjs1", "pr": "https://github.com/objectstack-ai/objectstack/pull/33218", "session": "session_01L9qibzKCovWpJoMZD6U3NT", "premise_still_valid": true, "summary": "PR 3a-ii of this card (connector), Part of #31699: the card stays open for 3b (engine by (package, name); patch saved, see handover 6871869590) and the narrowing PR. The connection store, the connect door, the OAuth callback and the dispatch read and write one instance by (package, name). Store rule (answering): while the name has one holder, or no registry can judge, every row of the name answers its instance, as the read by name did; a connect adopts and restamps it (null included) and a revoke removes it, so a declaration that moves to another package or to the environment keeps its connection (contract review F1 on e72a2458, fixed at 6a982f72). Under two holders each package reads its own rows; a row naming none of the holders is no package's, and with no own row the read and revoke are refused 409 naming the bind. Two answering rows: 409 at the door, 503 at dispatch, never picked. The begin records the package in the pending authorization and the callback completes exactly that package (404 when it no longer declares the instance). Door: two holders, or two declared entries with no registry, 409. F1(b): the composition is a declared entry stamped P while the package-scoped registry resolves the name to Q (the door serves the one declared entry, design M6); under the one-holder rule a pre-column row there answers the served instance and a reconnect stamps it P, pinned at the booted door.", "tests": "connector-connection-package.test.ts 13 (store rule; F1 moved-to-package and moved-to-environment adoption, restamp and revoke; two holders with a stray row naming a non-holder refused and a holder's row kept); connector-connection-door.test.ts 50 (F1 moved declaration keeps read, dispatch and revoke; F1(b) pre-column row under the M6 fallback). Ablations: one-holder rule reverted to own-plus-unbound (4 red), to the pre-review rule (F1(b) pin red), the null restamp removed (1 red), plus the 11 from the red-line rounds. Full @objectstack/service-automation suite at 6a982f72: 281 files, 3875 tests passed.", "gates": "tsc --noEmit service-automation exit 0; eslint on touched files clean; pre-push check:commit-card-trailers OK. CI on e72a2458 all green (53 runs, 0 failed); CI on 0704ffc0 pending at posting.", "dogfood_battery": "not run: the title carries no breaking marker", "mcp_calls": "read-only: mcp__github__issue_read, mcp__github__pull_request_read, mcp__github__get_job_logs; no MCP write tool used", "api_writes": "relay (fleet-write) only: pr_create #33218 (assignee os-tesla), pr_draft #33218, comments on #33218 (review claim 6878679566, brief 6878905826, FAIL record 6878911246), handover 6871869590 and this report on #31699; plus git pushes to the thread branch", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }Deviations for the ACCEPT:
stored-reference-package-backfill.ts(three comment lines keeping the R11 note true) is outside claim amendment 6869821095's surface. The grant handle's package is fixed at creation in this PR (review N3) and read per read in 3b.objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx
Claim: resume after the 04:35Z sign-off, card thread · 2026-11-14T14:39Z · the seat is back on duty for review and landing only (「你现在可以自己契约复审了。」 2026-11-14T14:17Z; 「车道座位应该使用pm-dispatch 技能审核和落地pr」 2026-11-14T14:32Z); taken over under 「接手 31699」 (2026-11-13T15:34Z)
Session:
session_01L9qibzKCovWpJoMZD6U3NTAccount:
os-teslaBranch:
claude/project-thread-y6vjs1Worktree:
objectstack-issue-31699Domain:
domain:serverSeat:
domain:server#7File surface: unchanged — takeover claim 6857670747 with amendments 6869794919 (3a-i, landed #33199), 6869821095 (3a-ii, PR #33218) and 6870521528 (3b, narrowed by handover 6871869590). Stop on breach.
Container & model:
S,mode:thread,model: default (dispatch-gates --tier: no path-derived mandate; PM default),effort: mediumClause-②: yes (widening) for 3a-ii, as declared on PR #33218; the narrowing PR declares its own arm
Metadata-protocol: none
Responsibility: the connector connection store, door, OAuth callback and dispatch by (package, name), objectstack | every deployment with OAuth connectors | 18.4.0 onward
Thread-read: 6878937714
Premise: re-measured by the card thread on 0704ffc (report 6878937714)
Serial constraints cleared: 3b is not pushed until #33218 merges
objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT
os-dev-report
Posted 2026-11-14T15:38Z.
{ "issue": 31699, "status": "done", "branch": "claude/project-thread-y6vjs1", "pr": "https://github.com/objectstack-ai/objectstack/pull/33281", "session": "session_01L9qibzKCovWpJoMZD6U3NT", "premise_still_valid": true, "summary": "PR 3b of this card (connector), Part of #31699, within claim amendment 6870521528 as narrowed by handover 6871869590: the card stays open for the narrowing PR. The automation engine holds a connector instance by (package, name) (ConnectorInstances); a bare-name read answers the one instance, never one of two. connector_action resolves its connectorId for the calling flow's package and reads handler, effect and inputSchema from that instance. The reconcile registers every declarative instance with its package (connectorInstancePackage) and soleOfName, puts the package in the desired signature so a holder change re-registers it, and drops by name. The OAuth2 grant handle reads its package per read (#33218 review N3, resolved here), serves a cached token only for its own connection row, and refuses a refresh in flight for another row. Rebased on main after #33218 and adapted to its one-holder store rule: the one tightened answer is an unstamped entry whose name gains a second holder after boot (200 to 503), which the phase-1 refusal keeps a supported install out of. The store's two-holder refusal names the uninstall remedy for a row already naming a non-holder package (#33218 review N4).", "tests": "flow-package-scoped-resolution.test.ts 8 engine pins (two instances held and each dispatched, inputSchema per instance, no pick of two, refusal naming both, soleOfName, plugin/declarative conflict, unregister, fallback arm); connector-connection-door.test.ts (per-read package 200 then 503 on a second holder; holder replaced leaving one holder keeps 200; package drift re-registers; removed entry leaves no instance, degraded or live); grant-handle.test.ts (token bound to its row; in-flight refresh of another row refused). Ablations C1-C8, R1-R7 and the one-holder pin, each red. Full @objectstack/service-automation suite on main after #33218: 281 files, 3890 tests passed.", "gates": "tsc --noEmit service-automation exit 0; eslint on touched files clean; check-engine-double-contract, check-tenant-audit-census and check-system-context-census OK; pre-push check:commit-card-trailers OK. CI on 17ac7146 partly in at posting (0 failed).", "dogfood_battery": "not run: the title carries no breaking marker", "mcp_calls": "read-only: mcp__github__issue_read, mcp__github__pull_request_read; no MCP write tool used", "api_writes": "relay (fleet-write) only: pr_create #33281 (assignee os-tesla), pr_draft #33281, comments on #33281 (review claim 6879748975, brief 6879875447, PASS record 6879890115) and this report; plus a git push to the thread branch", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }Deviations for the ACCEPT, as the record lists them:
connector-instances.ts(new),index.ts(two barrel types),connector-connections.tsandconnector-connection-package.test.ts(the 409 remedy text). The amendment'sconnector-instance-by-package.test.tsdoes not exist; its pins are in three existing test files.Clause-②: yes (widening)where the amendment expectedno: the barrel exports two new types.grantHandleskeyed by instance, the pull's package resolution, and the fallback arm madenone.Record nits accepted, with no further round:
registerConnector(def, handlers, 'declarative')with no fourth argument no longer replaces an instance held under a package. Nothing in the tree calls it that way outside tests.Clause-②sentence should also say that the phase-1 refusal keeps a supported install out of the tightened state.objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT
handover
Posted 2026-11-14T15:40Z. This addendum to handover 6871869590 brings its "still owed" list up to date.
resolveConnectorInstanceFor. It answersnoneonce two instances can live (already listed; repeated so the list is in one place).objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzKCovWpJoMZD6U3NT
Fourth claim amendment to the takeover claim 6857670747 on #31699 · 2026-11-14T19:27Z: the file surface for the narrowing PR (the last PR of this card), as handover 6871869590 and its addendum 6879929803 list it. The seat asked for it after #33281 merged ("Start that PR from the latest main").
packages/core/src/package-scoped-resolution.ts,packages/objectql/src/package-scoped-read.ts,packages/objectql/src/bare-name-one-holder.ts(doc only),packages/metadata/src/package-slotted-store.ts.packages/services/service-automation/src/:plugin.ts(lift the backstop; the materializer's maps andgrantHandleskeyed by instance; the door readsrequest.package; the credential listing per instance),engine.ts(resolveConnectorInstanceFor: every caller asks the resolver; a resolved holder with no instance answersnoneexcept a plugin's code-registered connector; a name only disabled packages hold answers the same; descriptors carrypackageId),connector-pull.tsandpull-refusal.ts(the connector resolved from the mapping's package;connector_name_refused),connector-package-scope.ts(refusedConnectorNamesremoved),connector-instances.tsandplugin-extension-api.ts(doc only).packages/spec/src/contracts/automation-service.ts(ConnectorConnectionRequest.package?) andpackages/spec/src/integration/connector-descriptor.ts(ConnectorDescriptor.packageId?). Both are TypeScript interfaces with no zod schema, so no generated artefact moves.packages/runtime/src/domains/automation-address.tsandautomation.ts: the namespace connection door admits a connector name two packages hold to the addressed holder and passes its package.packages/metadata-protocol/src/no-package-scoped-reads.testkit.ts(the test double reads connector by package).packages/cloud-connection/src/marketplace-install-local-bare-name-conflict.test.ts(the refusal case becomes a same-namespace co-owner; a FROM → TO case added),packages/cli/src/commands/migrate/stored-references.integration.test.ts(no sealed clash left).content/docs/automation/connectors.mdx(a "Two packages, one connector name" section and two failure-mode rows) and one changeset,Clause-②: yes (narrowing),Metadata-protocol: added.Deviation, said here before the push: the handover named
?package=on the bare connection door and onGET /connectors. This PR uses the namespace address that already exists (/automation/connectors/:ns/:name/connection, child G1) instead of a second spelling, andGET /connectorsstays unfiltered with each descriptor carryingpackageId.objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx
待裁 · #31699 收窄 PR #33431 超出卡面申报的收窄 · 2026-11-14T21:29Z
一句话问题: 本卡申报的收窄只有「同一命名空间的共有者」,但最后一个 PR #33431 的 changeset 列了十条答复变化,其中三条在只有一个包持有该名字的部署里也会变;卡的验收条款写明「超出申报的收窄先交维护者裁」,所以落地前要你一个字母。
背景: #31699(ADR-0150 子卡 B)把 email_template、webhook、connector 的「一个名字一个包」放宽为「一个命名空间一个」。email_template(#32214)与 webhook(#32577)已合并;connector 分三段,3a-i #33199、3a-ii #33218、3b #33281 已合并,#33431 是最后的收窄 PR(head
1530146d,1758 行,非受管面,Fixes #31699)。契约复审:首轮 6884429121 PASS-WITH-CHANGES,三次 delta 6884435741 都 PASS;最后一次 delta 在e467615b,到 head 只多了 changeset 的两行措辞(本席已读)。Governing text: 卡正文「Clause-②: no」「Narrowing: yes, for co-owners of one namespace」与验收「a narrowing beyond the declared one goes to the maintainer (
needs-user-decision) before landing」;红线 3(b)「单持有者名字的裸名行为不变,本卡申报的收窄除外」。协议声明: PR 申报
Clause-②: yes (narrowing)、Metadata-protocol: added,十条 FROM → TO 全写在 changeset。前提(可复核):
git show 1530146d:.changeset/31699-connector-names-per-namespace.md的「One holder」一句:单持有者下只有 (6)、(7) 和「无包戳条目换持有者后到下次协调之间」三处变化。选项:
业务含义直译: A = 「找不到这个包自己的连接器就不发」,像快递只按收件人自己的地址投递,不再投给同名的邻居;B = 找不到时投给楼里唯一同名的那家;C = 先不改门牌制度。
四轴(业务立场):
os-decision-facets
Prior rulings read: 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 评论 6816295828、6820178514、6871869590、6882996364 → 4 条已读(未做全库检索); ADR-0150 D2, D9; 裁定 R4(objectql + metadata-protocol + runtime: by-name doors judge a name's holders over the served list, so a disabled package neither refuses nor is named (ADR-0150 D3; #32101 F4 class) #32183,经笔记 6820178514); thread: 1(webhook 先例:同卡 PR feat(plugin-webhooks)!: declared webhooks are held per namespace, each holder dispatched and switched as its own (ADR-0150 child B, webhook family 2/3) #32577 带八条变化由史诗席 ACCEPT 6844800975 落地,该 ACCEPT 中未见呈裁记录)
推荐:A。 只看①选 A;②③④ 是否翻转:否。置信缺口:(6)、(7) 的「受支持状态下无人经过」是作者与复审在工作区内的结论,工作区外的自建部署无法实测。B 不取:保留只给 connector 的特例,且两个包同名时有静默发错包的风险。C 不取:没有新信息可等。
裁后执行: A:本席把卡的状态标签换回
pm:dispatched,CI 绿后按常设落地令贴 ACCEPT 并落地,合并即关卡。B:本席把 (6)、(7) 交回卡线程改回 main 的答复,同一审读子代理做 delta,再落地。C:PR 保持草稿,卡留needs-user-decision。相关:#31699、PR #33431、#32577、#33281、#32183。
objectstack-fleet commentedon Nov 14, 2026
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx
Maintainer decision recorded · 2026-11-14T21:36Z: on the seat's decision card for anchor 6884489751, the maintainer chose 「A 按申报接受,CI 绿后落地」 (2026-11-14T21:35Z). The ten FROM → TO rows of PR #33431's changeset, including the three one-holder moves ((6), (7) and the unstamped-entry window), are accepted as declared. The seat lands #33431 once CI is green on its head.
needs-user-decision→pm:dispatched.