Skip to content

Bare-name phase 1: refuse a second package holding a non-object name whose consumers resolve without package context (ruling C on #30798) #30803

Open

Description

@objectstack-fleet

epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

Filing-gate category: ② execution of a maintainer ruling. Decision #30798 ruled C, maintainer verbatim (Claude Code session, 2026-11-06): 「同意 c」: every package-authored metadata name carries its namespace, phased. Routing, verbatim: 「能交给车队开发的你不要自己开发」.

Phase 1 of 3. Siblings: phase 2 lint and templates, phase 2 authoring skills, phase 3 rule and migration (filed together).

Problem (customer-visible)

When two installed packages ship a non-object item with the same bare name, many runtime consumers serve only one of them, usually silently and in install order. Measured per type in the audit table on #30798: the kernel metadata service, object-less action dispatch, AI tool names, function handlers behind hooks, picklists, mappings, datasets/cubes, email templates, webhooks, declared connectors, and flows (one armed, with a warning).

Ask

  1. Measure first. Boot one environment with two packages sharing one bare name for each type in that table, and record which resolve wrongly. The table is a code reading, not a booted measurement.
  2. Extend the one-name-one-holder registration refusal (the security catalog's rule, packages/objectql/src/security-catalog-namespace.ts; precedent feat(objectql)!: positions, permission sets and capabilities hold one name per deployment — a second holder is refused at registration, naming both #22197 +1080/−103 and feat(objectql)!: a cold boot refuses a package-held position or permission-set name the environment catalog already holds, as a hot install does (ADR-0048 N.3) #22365 +705/−43) to every type the measurement shows resolving without package context. The refusal applies at managed install, at package registration and at cold boot (as [decision] cold boot admits a package whose permission set or position name the environment catalog already holds (package registration runs before sys_metadata hydration), while a hot install of the same package is refused #22307 did), names both holders, and carries the rename in the message.
  3. Keep what already works: same-name actions on different objects (keyed objectName:name), job scheduling under appId:jobName, and the unmanaged import's all-type refusal.
  4. Record the narrowing on ADR-0048 §3.4. This refusal stays after phase 3 only as the backstop for packages without a namespace, the shared base/system/sys namespaces, and third-party packages in the deprecation window.

Out of scope: the types a separate security item covers. The security seat routes those; do not add them here unless that seat says so.

Reader: the domain:engine lane seat, from pm:queue.


Generated by Claude Code

Activity

  1. added
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Nov 6, 2026
  2. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · domain:engine → domain:server · p1 kept · 2026-11-06T04:55Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. added
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    pm:queueReady for the PM dispatch loop
    on Nov 6, 2026
  4. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

    Claim: PM loop round 1 · 2026-11-06T05:21Z · seat 3's pick in the live server split
    Session: session_016WV4cytQjG9X1CrCgytUM5
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-crfe5o
    Worktree: the card thread's own checkout of claude/project-thread-crfe5o
    Domain: domain:server
    Seat: domain:server#3
    File surface: packages/objectql/src/ (the one-name-one-holder module security-catalog-namespace.ts, or a sibling generalising it, + the registry / managed-install / cold-boot call sites it already uses, + tests); the per-type registrars the stage-1 measurement implicates, each reported to the seat before it is touched; pin files under packages/qa/dogfood/test/; docs/adr/0048-* §3.4 + its scripts/adr-anchors/ anchor (Tier H); the ledgers Metadata-protocol: narrowed requires (regenerated with repo tooling); root .changeset/ files. ⛔ lint / templates / examples (#30804), skills (#30805), the save door / defineStack (#30806), spec schema, ui, and any type the security seat's item covers (stop on breach; explain in the report)
    Container & model: L, mode:thread, model: default, effort: xhigh
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed (provisional: confirmed or revised by the stage-1 measurement)
    Responsibility: n/a — ADR-0048 §3.4's coexistence predates the programme; this card executes ruling C on #30798 (6676670839), phase 1
    Thread-read: 6677272063
    Premise: holds on the code reading of #30798's audit table; stage 1 measures it on a booted two-package environment before any refusal code, and the seat confirms the type list before stage 2
    Serial constraints cleared: none at claim time. packages/objectql/src/protocol.ts / engine.ts are held by the facade programme (#30020, PR #30716): touched only if unavoidable, after telling the seat

    Staged: measurement first, then the seat's go. Contract review at CONTRACT_REVIEW_TIER owed before the queue (narrowing); docs/adr is Tier H.

  5. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4d1EuHiCqvh8VEz81QD
    os-dev-report

    {
      "issue": 30803,
      "status": "done",
      "branch": "claude/project-thread-crfe5o",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30836",
      "session": "session_016WV4d1EuHiCqvh8VEz81QD",
      "premise_still_valid": true,
      "summary": "PR 1 of 4 (Refs #30803): a picklist, mapping or dataset name holds one package. New module packages/objectql/src/bare-name-one-holder.ts (covered types, declared names incl. nested plugins, rename = namespace prefix, BARE_NAME_COLD_BOOT_MODE = 'warn'); SchemaRegistry.installPackage and registerItem refuse a second package holder with the ADR-0112 envelope (NAMESPACE_CONFLICT, 422), every conflict in one refusal, naming both holders and the rename; the engine plugin seals the registry at kernel:bootstrapped, and a boot that already holds a clash warns once (or refuses under 'refuse'). The environment catalog is never a holder (ADR-0005 overlay). ADR-0048 §3.4 narrowed + 2026-11-06 addendum (Tier H). One file outside the dispatch's file surface: packages/cli/test/package-install-local-jobs-pull.integration.test.ts — its five fixture packages, installed into one kernel, all declared the mapping orders_pull, so CI Test Core (4/8) went red at 75d1339f; each package now names <namespace>_orders_pull (test-only, d154c622). Open for the maintainer, already routed by the seat (not a new question): whether the cold boot of an existing clash should refuse instead of warn — PR1 ships 'warn' and the flip is one constant (BARE_NAME_COLD_BOOT_MODE).",
      "tests": "pnpm --filter @objectstack/objectql exec vitest run src/registry-bare-name-one-holder.test.ts → 40 passed; @objectstack/objectql full suite → 556 files / 11108 tests passed; pnpm --filter @objectstack/objectql typecheck (incl. test-typecheck ratchet) exit 0. Dogfood pin bare-name-one-holder.dogfood.test.ts → 4 passed. cli fixture fix: package-install-local-jobs-pull.integration.test.ts → 8 passed (was 4/8-shard red in CI); pnpm --filter @objectstack/cli typecheck: tsc --noEmit exit 0, check:test-typecheck OK (3 files / 28 errors / 6 pinned signatures held, unchanged; first attempt OOMed at the 2 GB default heap, rerun with --max-old-space-size=8192). Ablation (src): the plugin's seal call removed → 19 of 40 unit cells red (every door refusal + the cold-boot warning), 21 control cells green; restored. Ablation (dist): dogfood pin against the pre-change objectql dist → 3 of 4 red, the fresh-names CONTROL green; green after rebuilding dist.",
      "gates": "dispatch-gates --commands at d154c622: 82 derived (81 at 75d1339f + pnpm check:cli-test-child-env for the cli test path), all run, every exit 0; --ran reconciliation: '82 derived famil(ies) accounted for — 82 run, 0 NOT-MEASURED'. Two needed a rerun: node scripts/check-plugin-teardown-shape.mjs --self-test exit 3 on the shallow clone (pinned fixture commit 621a4876 unreachable) → fetched that one commit, exit 0; pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (no dist for 7 packages) → built them, exit 0 (116 entry points / 71 packages load). 5 extra families run beyond the derivation (error-code-provenance, changeset-fixed, error-code-casing, facade-delegation-only, published-readme-exports), all exit 0. CI at d154c622 (the PR's check-runs, not re-run locally): 50 check-runs, 37 success, 13 skipped, 0 failure — Test Core (1/8…8/8) success and the Test Core aggregate success (4/8 was red at 75d1339f, the cli fixture above), Build Core success, Type Check · workspace / consumer gates / source gates / debt ledger success, TypeScript Type Check success, Lint & Repo Gates success (ESLint, repo & tooling, docs & code guards, PM dispatch-gates, CI release & engine, scoped ×3); Lint UI / Type Check UI skipped (no ui path).",
      "dogfood_battery": "75d1339f · os-verify-lock: VERDICT command-exit 0 · Test Files 424 passed | 3 skipped (427) · Tests 3537 passed | 41 skipped (3578) · no failures. d154c622 changes only packages/cli/test/package-install-local-jobs-pull.integration.test.ts, which is not in the dogfood battery.",
      "mcp_calls": "5 — mcp__github__issue_read ×4, mcp__github__get_job_logs ×1; no write tool. Other reads were REST GETs through gh api (check-runs, PR, card).",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (relay pr_create, PR #30836); POST /repos/objectstack-ai/objectstack/issues/30803/comments (relay comment, this report). git push to the PR branch is not a REST write.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: cloud · noted, not filed — AI runtime consumers of agent/skill/tool names (service-ai agents, skills, action_NAME tool names, ToolRegistry) live in objectstack-ai/cloud; NOT MEASURED here (PR body Series section)",
        "carrier: seat · noted, not filed — analytics_cube: a non-host package's cube never reaches the analytics service (404 CUBE_NOT_FOUND in both orders), a reach gap, not a holder conflict; dedupe words: analytics cube non-host package CUBE_NOT_FOUND",
        "carrier: seat · noted, not filed — docs candidate: content/docs import-mappings page could state one package per mapping name (docs-drift bot found no contradicting doc); dedupe words: import mapping name one package"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

    Progress · 2026-11-06T11:48Z · PR 1 of 4 landed: PR #30836 merged through the queue as 2a6a28db96 (Refs #30803; the card stays open and dispatched).

    Reading Value
    Landed the one-holder module, the package door + item seam refusal, the kernel:bootstrapped seal (BARE_NAME_COLD_BOOT_MODE = 'warn'), ADR-0048 §3.4 narrowing + 2026-11-06 addendum; types picklist, mapping, dataset
    Reviews contract review 6679538573 PASS, delta 6679688246 PASS; seat ACCEPT 6679952314 + addendum 6683678834; Tier H, armed by os-zhuang
    Next PR2–PR4 (api, object-less action, function registry, webhook, connector, flow, email_template, agent, skill) wait for the maintainer's answer on which of them the separately-held security subset of #30798 covers
    Open ruling cold-boot refuse vs warn (maintainer card in the seat thread); 'warn' ships, a refuse ruling is a one-constant follow-up
  7. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 6, 2026
  8. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

    Ruling recorded · 2026-11-06T14:58Z · cold boot of an existing bare-name clash: the maintainer chose B, warn at boot and refuse new installs (decision card, 2026-11-06T14:57Z).

  9. 7 remaining items

  10. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    Claim: PM loop round 1 · take-over of PR 2 of 4 (#31006) on domain:server#3's request 6690572980 on mailbox #30985 · 2026-11-06T17:05Z
    Session: session_01L9qibyvxbrLP4jm4PargoH
    Account: os-tesla (the card's assignee)
    Branch: claude/project-thread-crfe5o (PR #31006 as left by the domain:server#3 card thread, which has stood down; no new push is made by this seat)
    Worktree: none for the review; a card thread is opened on the same branch only if the review owes a change
    Domain: domain:server
    Seat: domain:server#2
    File surface: exactly PR #31006's eight files (docs/adr/0048-cross-package-metadata-collision.md, packages/objectql/src/{bare-name-one-holder.ts,hook-binder.ts,plugin.ts,registry.ts,registry-bare-name-one-holder-request-family.test.ts}, packages/qa/dogfood/test/bare-name-one-holder-request-family.dogfood.test.ts, one changeset). PR 3 and PR 4 are not in this claim.
    Container & model: M, review take-over, model: CONTRACT_REVIEW_TIER (dispatch-gates --tier: MANDATORY from docs/adr/**, no one-line exemption), effort: xhigh (the docs/adr/** floor)
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Responsibility: as on the card and PR 1 #30836 (merged 2a6a28db); unchanged by this take-over.
    Thread-read: 6690280341
    Premise: holds. PR #31006 is open, draft, head bb786448, mergeable clean, 37 success / 13 skipped / 0 failed; os-dev report 6690087672.
    Serial constraints cleared: none new; the card's own PR 3 and PR 4 follow PR 2.
    Resume-from: claude/project-thread-crfe5o@bb786448

    Next: the contract review at CONTRACT_REVIEW_TIER (the two open questions in 6690280341 included), then ACCEPT, pm:awaiting-merge, and the Tier H hand-off to os-zhuang.

  11. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    Claim amendment · 2026-11-06T17:20Z · amends the PR 2 of 4 take-over claim 6690638720 on this card

    Worktree: the review owed a change (record 6690893976, should-fix 1 and 3), so a card thread now works on the same branch claude/project-thread-crfe5o: session session_01L9qibxXA6Z1QEsocQJhugE, pushing by merge only, no new PR.
    File surface (added): scripts/adr-anchors/packages__objectql__src__bare-name-one-holder.ts.json (the invariant sentence, already named in the claim) and .changeset/30803-bare-name-one-package-holder.md (PR 1's unconsumed changeset: the cold-boot "open call" sentence becomes ruling B, 6687840782). Optional: the ADR-0048 P1.1 heading (nit 1). Should-fix 2 (the runtime's silent bind refusal) is not in this PR; the seat files it as its own card. Everything else in the claim stands.

  12. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibxXA6Z1QEsocQJhugE
    os-dev-report

    {
      "issue": 30803,
      "status": "done",
      "branch": "claude/project-thread-crfe5o",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31006",
      "session": "session_01L9qibxXA6Z1QEsocQJhugE",
      "premise_still_valid": true,
      "summary": "Delta on PR 2 of 4 for contract review 6690893976 (VERDICT PASS): should-fix 1 and should-fix 3, plus nit 1, at head 247853de (one commit on bb786448, pushed by merge-free fast-forward; no rebase, no force). Three prose files, +3/-3, no code: (1) scripts/adr-anchors/packages__objectql__src__bare-name-one-holder.ts.json invariant now names both families with their served holder (data family first-registered; request family = the endpoint matcher's API, an object-less action's handler, the engine function registry's function, last-registered) and three doors: package door, item seam, and the hook binder's bind (bindHooksToEngine in hook-binder.ts, through SchemaRegistry.claimBareNameFunctions); same ADR citations ADR-0048 and ADR-0005. (3) .changeset/30803-bare-name-one-package-holder.md (PR 1's, pending): 'Whether that boot should be refused instead is the maintainer's open call;' became 'The maintainer ruled this on 2026-11-06: the boot warns, and only a new holder is refused;' with the rest of the sentence and the 'first-registered holder keeps being served' sentence untouched. This is a DELIBERATE CORRECTION: check-empty-changeset (Check Changeset) reds by design and the seat's record confirms it. (nit 1) ADR-0048 P1.1 heading now ends 'for the data family: picklist, mapping, dataset' (code spans in the file). Two standard-text points: the PR body was NOT patched by this thread, because os-dev rule 3 has the dev write a PR body once, at pr_create, and the seat write later changes, which overrides the order's line asking for it; the refreshed body (verification line for 247853de, the DELIBERATE CORRECTION section, two What-changes bullets, footer stripped, signed trailer as last line) is ready as a relay actions file whose dispatch.mjs --dry-run exits 0: /mnt/project-files/server-seat-2/r2026-11-06/out/31006-delta-body-patch.json. And origin/main was not merged: AGENTS.md multi-agent section 10 merges main into an open PR only on a GitHub conflict, a main-caused red or a queue removal, the PR read mergeable clean, so os-dev rule 1's merge-first on resume yields to AGENTS.md; main is 15 commits ahead of the merge base (one touches ADR-0048 section 5, no overlap with this PR's hunks).",
      "tests": "No code changed, so no suite was run. The anchor file parses as JSON; the control-byte scan of the three files is empty; the pre-push hook check:commit-card-trailers passed on the commit.",
      "gates": "At 247853de, dispatch-gates --commands derives 82 families for the whole PR. Run: the 39 that read the three changed files (31 matched by these paths, 8 declared whole-tree), each command with stdin closed and its exit code recorded before any pipe. 38 exit 0, including check:adr-anchors (OK, 111 anchored files), check-adr-links (991 links resolve), check:adr-index, check:adr-symbol-anchors, check:doc-authoring, check:closed-ceremony-text, check-closing-keyword-parity (sweep and self-test), check-comment-mask-corpus (21197 files, 0 disagree), check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check:changeset-gate-self-tests, and check:doc-formula-expressions (first exit 3 PREREQUISITE NOT MET, then exit 0 after building the lint closure under os-verify-lock, VERDICT command-exit 0, 99 s). One exit 1: check-empty-changeset --base origin/main, the DELIBERATE CORRECTION refusal on PR 1's changeset, expected. Reconciliation: '82 derived, 39 run, 0 NOT-MEASURED, 43 UNRUN'. The 43 unrun read only the code and test paths this delta leaves untouched; they ran at 0990e5dd (74 of 74 exit 0, report 6690087672) and CI was green at bb786448. The derivation flagged its tree as 15 commits behind origin/main (release.yml and five scripts changed); not re-derived on main, see the merge note in summary. CI at 247853de, read once right after the push: 47 check-runs, 12 success, 13 skipped, 22 in progress (Check Changeset among them; expected to red as above), 0 failed. Not waited on.",
      "dogfood_battery": "NOT RERUN at 247853de: the delta changes three prose files the battery does not read, and the order scoped reruns to the derived gates. Last battery: 0990e5dd, VERDICT command-exit 0, Test Files 428 passed and 3 skipped (431), Tests 3560 passed and 41 skipped (3601) (report 6690087672).",
      "mcp_calls": "4 reads, 0 writes: mcp__github__issue_read x2 (card body, card comments), mcp__github__pull_request_read x2 (PR, PR comments). Other reads were unauthenticated REST GETs (the PR body, the check-runs).",
      "api_writes": "1: POST /repos/objectstack-ai/objectstack/issues/30803/comments (relay comment, this report). git push to the PR branch is not a REST write. The PR body patch was dry-run only and is handed to the seat.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }
  13. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    ACCEPT → PR #31006 comment 6691516559 (head 247853de) · 2026-11-06T17:49Z · contract review 6690893976 + delta 6691463846 PASS; the Check Changeset red is a confirmed DELIBERATE CORRECTION of PR 1's pending note. Tier H: pm:awaiting-merge, review requested from the governed approvers; the PR stays draft until approved, then the seat lands it. Should-fix 2 (the runtime's swallowed post-seal bind refusal) becomes its own card.

  14. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    Landing · 2026-11-07T04:02Z · PR #31006 MERGED 2026-11-07T03:33Z as 902f162c (Refs #30803, PR 2 of 4, the request family): an API, an object-less action and an engine function now hold one name per package. It was enqueued by the maintainer through os-zhuang. The card stays open. PR 3 and PR 4 go back to the queue in the series order, and the last PR carries Fixes. The seat moves pm:dispatched → pm:queue and unassigns, so the next server seat with a free slot picks up PR 3 from the series plan on this card.

  15. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Nov 7, 2026
  16. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 7, 2026
  17. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    Claim: PM loop round 1 · PR 3 of 4 (flow, webhook, connector, email_template) on seat 2's release 6701997408 · 2026-11-07T04:49Z
    Session: session_017xRBcTJTE7kSbcMoJQ4Txf
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-30803-bare-name-pr3-flow-family
    Worktree: objectstack-issue-30803
    Domain: domain:server
    Seat: domain:server#1
    File surface: packages/objectql/src/ (bare-name-one-holder.ts and the registry / package-door / item-seam / cold-boot call sites PR 1 and PR 2 use, plus a new registry-bare-name-one-holder-*.test.ts); the registrars of flow, webhook, connector and email_template that the dev's measurement shows serving a bare name without package context, wherever they live (each named in the report with the reason); packages/qa/dogfood/test/ (one dogfood pin, as PR 2); docs/adr/0048-cross-package-metadata-collision.md (the §3.4 note and the phase-1 addendum rows for these four types); scripts/adr-anchors/packages__objectql__src__bare-name-one-holder.ts.json; one changeset. ⛔ packages/spec/**, ⛔ skills/**, ⛔ agent and skill (PR 4). Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: CONTRACT_REVIEW_TIER (dispatch-gates --tier: MANDATORY from docs/adr/**, no one-line exemption), effort: xhigh (the docs/adr/** floor)
    Clause-②: no (narrowing)
    Metadata-protocol: narrowed
    Responsibility: n/a — not a defect card; this card executes ruling C on #30798, phase 1
    Thread-read: 6701997408
    Premise: holds (read on origin/main 24bc2593 at 2026-11-07T04:49Z: BARE_NAME_ONE_HOLDER_TYPES is picklist, mapping, dataset, api, action, function; none of the four PR 3 types is covered)
    Serial constraints cleared: PR 1 (#30836, 2a6a28db) and PR 2 (#31006, 902f162c) have merged; the dev works on the merged code. #29594 (seat 2, pm:dispatched) claims packages/objectql/src/registry.ts and service-automation/src/flow-precedence.ts: its only open PR is #31027 (docs/adr/0146 only) and its PR 3 has not started, so there is no live code overlap now. Whichever lands second merges main. #30806 and #30808 stay pm:blocked on this card.

    Rulings carried (binding, from this card's thread): cold boot B, warn at boot and refuse new installs (6687840782); all nine types stay in this card, in the series PR3 = flow + webhook + connector + email_template, PR4 = agent + skill with Fixes #30803 (6688041914). This PR carries Refs #30803 (PR 3 of 4), never Fixes. Tier H (ADR-0048): a human merges.

  18. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    os-dev-report

    {
      "issue": 30803,
      "status": "done",
      "branch": "claude/issue-30803-bare-name-pr3-flow-family",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31093",
      "session": "session_017xRBcTJTE7kSbcMoJQ4Txf",
      "premise_still_valid": true,
      "summary": "PR 3 of 4 (Refs #30803), the flow family, on PR 1's mechanism (#30836) as PR 2 extended it (#31006): a flow, a webhook, a connector and an email template hold one package. Measured first (card ask 1) on a booted showcase with two AppPlugin packages sharing one name per type, both orders: the automation engine arms ONE flow per name (the lexicographically-first package, alpha in both orders, with its precedence warning) while GET /meta/flow/NAME serves the first-registered declaration; the webhook dispatcher's declared reader keeps the first-registered webhook and never subscribes the other, silently; GET /meta/connector/NAME (the picker's read) serves the first-registered descriptor, silently, and two provider-bound instances already refuse the boot (ADR-0097 duplicate); a send's template resolves the first-registered email template, silently. A third package installed after the boot under any held name answered 200 and was shadowed. All four resolve without package context, so all four join BARE_NAME_REGISTRY_TYPES (bare-name-one-holder.ts, now the one ordered list of ten with BARE_NAME_REGISTRY_TYPES derived); SchemaRegistry.installPackage and registerItem refuse a second holder after the seal with PR 1's envelope (NAMESPACE_CONFLICT, 422, both holders, the rename), install-local answering 422 PLUGIN_REGISTER_FAILED. Two particulars: email_template is a bundled type (registry key pkg:name@locale), so the holder reading and the cold-boot seal strip the member through bundleBaseKey and the NAME holds the bundle; and the email service's built-in templates (com.objectstack.service.email) are an OVERRIDABLE BASELINE (new OVERRIDABLE_BASELINE_PACKAGES / isOverridableBaseline, exported) because plugin-email's loader serves any other package's same-named member over them by contract (ADR-0131 D6) — that package neither holds a template name nor is refused one, the first other package holds it and a second is refused naming the first. No registrar outside packages/objectql was touched: all four register through registerMetadataCollections → registerItem(..., ownerId), and their consumers (service-automation flow-precedence, plugin-webhooks declared reader, the /meta by-name door, plugin-email's loader) were read, not changed. Cold boot stays ruling B ('warn', BARE_NAME_COLD_BOOT_MODE untouched). ADR-0048: header, §3.4 note, P1.5, P1.6, new P1.8 (Tier H); anchor invariant updated; one changeset (objectql minor). PR4 (agent, skill, the closing line) not started, per the series.",
      "tests": "Measurement (card ask 1, temporary dogfood file, deleted): booted showcase + alpha/beta AppPlugins sharing qa_shared_flow / qa_shared_hook / qa_shared_conn / qa_shared_tpl, both orders — flow: getFlow().label = 'alpha flow' in BOTH orders with the precedence warning naming both; GET /meta/flow/NAME = alpha in alpha>beta, beta in beta>alpha; webhook: declaredWebhookNamed().packageId = first-registered, no warning; connector: GET /meta/connector/NAME = first-registered, listItems returns both; provider-bound instance under one name: boot REFUSED 'duplicate declarative connector instance name ... (ADR-0097)'; email_template: renderTemplate().subject = first-registered; GET /meta/email_template/NAME the same; install-local gamma declaring all four held names: 200 in both orders, every consumer unchanged. registry-bare-name-one-holder-flow-family.test.ts (new) → 54 passed; with the data- and request-family pins and hook-binder.test.ts → 4 files / 154 passed (152 before the two member-key cells). @objectstack/objectql full suite → 565 files / 11476 passed (VERDICT command-exit 0); @objectstack/runtime full suite → 553 files / 8882 passed, 19 skipped (VERDICT command-exit 0). pnpm --filter @objectstack/objectql typecheck exit 0 incl. check:test-typecheck (39 files / 233 errors / 64 pinned signatures held, unchanged); @objectstack/dogfood tsc --noEmit exit 0. Dogfood pin bare-name-one-holder-flow-family.dogfood.test.ts → 4 passed; the data and request families' dogfood files → 8 passed; email-template-materialization.dogfood.test.ts (a fixture app shipping auth.password_reset beside the built-in) → 4 passed. Ablations (src, each via ablation-replace.mjs, restored with blob == HEAD and git diff HEAD empty): the four types removed from BARE_NAME_ONE_HOLDER_TYPES → 39 of 54 red; the baseline exclusion removed from bareNamePackageHolders → 3 red (an app's override refused naming the baseline; the cold boot warns about it; two apps' warning names the baseline); bundleBaseKey no longer applied to the member key → 2 red (the member-key holder cell and the seal's bundled-clash cell). Ablation (dist): objectql built from the merge base's three sources (preflight --absent: marker absent from all 14 built files) → the dogfood pin 4 of 4 red (no bare-name warning line; gamma and delta install-local answered 200 and installed; the CONTROL's import undefined); rebuilt from HEAD (marker present in 8 built files, tree clean) → 4 of 4 green.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at e01df46c: 82 derived, all run with exit codes captured before any pipe; --ran reconciliation '82 derived famil(ies) accounted for — 82 run, 0 NOT-MEASURED' (exit 0). Two reruns after a prerequisite: pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (seven packages had no dist on the fresh worktree) → built them under the lock, rerun exit 0 (116 entry points / 71 packages load); pnpm check:type-check-debt exit 3 PREREQUISITE NOT MET (its closure build timed out on the verify lock behind the dogfood battery, exit 99) → rerun under the lock with the same slot, exit 0 (--re-measure OK, 0 raw tsc errors). pnpm lint at e01df46c: exit 0. CI on the PR: not yet read at report time (in_progress) — the PR's check-runs are the gates' CI reading.",
      "dogfood_battery": "e01df46c · os-verify-lock: VERDICT command-exit 0 · Test Files 435 passed | 3 skipped (438) · Tests 3600 passed | 41 skipped (3641) · no failures (held the lock 1189s on a shared box). Ran because the PR title carries `!` and Clause-② carries the (narrowing) arm.",
      "mcp_calls": "0 — no MCP GitHub tool was called; every GitHub read was a REST GET through `gh api` (the card, its comments, #30798, PR #31006) and every write went through the relay.",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/pulls (relay pr_create, PR #31093, read back identical: 15138 bytes sent, 15138 stored); POST /repos/objectstack-ai/objectstack/issues/30803/comments (relay comment via post-stamped, this report). No labels, assignees or reviewers written (none named by the order; the diff publishes objectql, so no skip-changeset). git push to the branch (2 pushes + the empty-branch probe) is not a REST write.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: seat · noted, not filed — `GET /connectors` answered 404 on the showcase composition during the measurement (the connector catalog route is not mounted on that composition; `/meta/connector/NAME` and the registry list were used instead). Observation only, no reach measured beyond the dogfood boot; dedupe words: GET /connectors 404 showcase composition route",
        "carrier: seat · noted, not filed — a first app's override of a built-in email template is served silently by design (plugin-email's loader contract, ADR-0131 D6); this PR refuses only a SECOND app's override. Whether the first override should be reported at boot is the email plugin's own question; dedupe words: email template built-in override silent boot report",
        "carrier: seat · noted, not filed — `pnpm check:type-check-debt` and `check:dual-build-cjs-loads` exit 3 (PREREQUISITE NOT MET) on a fresh worktree: the first needs the verify lock for its closure build (it timed out behind the dogfood battery and was rerun under the lock), the second needs seven dists a dogfood-closure build does not produce (built, rerun exit 0). Both are harness facts PR 1 also met, not findings; dedupe words: dual-build-cjs-loads prerequisite dist type-check-debt verify lock"
      ]
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:serverDomain lane — seat card indexed by label:pm:seatpm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-setpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions