Skip to content

feat(metadata-core,metadata-protocol,objectql,plugin-security): the sys_metadata family goes tenant-less; the per-organization overlay axis retires; managed content is sealed (ADR-0131 D6/D7/D13) #15206

Closed

Description

@hotlong

⛔ BLOCKED — the v18 development line is not open.

Blocked-by: #15193
Blocked-by: #15195
Blocked-by: #22835

History: this line read Blocked-by: #15193, #15195 until 2026-09-27, inside backticks, so no unlock scan could read it (the triage census counted it as a blocked card with no machine target). The same targets now sit one per line, undecorated; nothing else changed (triage seat, session_01W89enF2dYV7K4N2Fbfj33f).

Part of #15194 (ADR-0131 execution tree). ⛔ Do not claim, assign or dispatch this card while #15193 is open, whatever its other labels say.


In one sentence. Environment metadata written by Studio, by the cloud build agent, or by a template-mode install belongs to the whole deployment, so its ledger loses the organization column; the per-organization overlay of views, dashboards and the other three presentational types is suspended (an organization-level metadata write is refused); and a managed package's content is sealed — not editable, not disable-able, not clonable-with-linkage, flows included.

Maintainer, 2026-09-04: 「你这么说还不如先完全封死。flow 也先不让改。」

Scope. (1) sys_metadata, sys_metadata_audit, sys_metadata_commit, sys_metadata_history declare systemFields.tenant: false; existing NULL rows keep their place (the column is dropped); existing org-scoped rows of the five tier-A types are reported per the overlay-axis ruling — migrated to environment scope or dropped. (1b) Retire sys_view_definition as inert (D13, verified 2026-09-04: no framework writer or reader of its rows, and objectui never referenced it — its createView / updateView / listViews write the ADR-0005 view overlay through client.meta.saveItem): drop the object, the two runtime index migrations (view-definition-active-index.ts and its runtime-index-preflight row), the CLI migration allowlist entry, the platform-object-names.ts entry, the overlay-views-to-sys-view-definition.md runbook, and the #8725 kernel:ready pre-flight; ADR-0087 entry; ADR-0017 already carries the amendment note. Positive control before any deletion: git grep sys_view_definition over packages/**/src shows only the files named here. (2) meta-write-org-scope.ts / protocol.ts: an org-scoped metadata write is refused with a message naming the posture; the layered read becomes environment → code; the identity pin (protocol.org-scoped-write-refused.test.ts) flips to "none accepted". (3) Managed content sealed: the permission-set clone-with-linkage path and any overlay of a managed item refuse at the door with a message naming the install mode (D6). (4) The ADR-0005 amendment note lands in the same PR.

Acceptance. Environment-level Studio edits work in every posture for capability holders; an organization admin's metadata write is refused; a managed flow can be neither disabled nor cloned-with-linkage — positive control: creating a new flow in Studio still works; single deployments observe no change except the refused org-scoped door.

⛔ Stop and report: changing who holds manage_metadata / studio.access.

Refs: ADR-0131 D6, D7, D13 · ADR-0005 (per-organization overlay axis retired) · ADR-0017 · ADR-0094 · ADR-0126 (amended, not superseded) · #11665 · #6190 · objectui#7205.

Activity

  1. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    Contributor

    v18 pre-opening re-verification (C5): DRIFTED badly. It is now XL and needs three maintainer rulings before it can be cut again

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T14:39Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstack main 6befe19c6e. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.

    Corrections:

    • The four sys_metadata tables do not "declare systemFields.tenant: false".
      • Each declares its own organization_id: metadata-core/src/objects/sys-metadata.object.ts:132, sys-metadata-audit.object.ts:113, sys-metadata-commit.object.ts:129, sys-metadata-history.object.ts:148.
      • Indexes key on it: sys-metadata :226-231; history :183-188, with event_seq per-organization; commit :146-148; and the runtime OVERLAY_INDEX_COLUMNS (overlay-index.ts:137).
      • So the fields, the indexes and the runtime index all need re-keying.
      • The physical column drop is C7's (D10: drops are the manual ceremony, last). It is not this card's.
    • The sys_view_definition positive control ("only the named files reference it") was already false at the cut, and still is: 35 files then, 37 now.
      • The non-test mentions are comments only, so "no reader or writer of its rows" holds.
      • The "CLI migration allowlist entry" does not exist as a list entry. No ADR-0087 entry exists yet.
    • Already done: the ADR-0005 and ADR-0017 amendment notes landed with the ADR merge.
    • The managed-flow acceptance contradicts D6 as amended (Regime C). Flow disable has shipped (flow-activation-store.ts, domains/activation-gate.ts). The permission-set clone has no linkage to refuse; its organization-owned copy is C3's.

    New surface since the cut, which this card's retirement now has to remove (about 31 commits; protocol.ts grew from 21,613 to 27,853 lines, and organizationIdForMetaRead calls from 14 to 30):

    Needs the maintainer before it is cut again:

    1. Split allowOrgOverride. The same flag also decides whether an environment overlay of a packaged item is allowed (isOverlayAllowed :15886 → refusePackagedBaseOverride :17067 / refusePackagedBaseRemoval :17176). Turning off the five flags would also close the environment overlays D6 keeps.
    2. What becomes of the shipped 17.x org-layer public-form withdrawal semantics (a security behaviour).
    3. The single Default-Organization rows. fix(plugin-email): a metadata-door email template edit survives the next boot #21818 measured that under single every Studio save of a view, dashboard, report, translation or email template is stored org-scoped, and new code relies on it (the email bootstrap, the anonymous form doors). "single observes no change" is false. Their migration to environment scope can collide by name: multi-organization single deployments are reported at boot, not refused.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 6, 2026

    @objectstack-fleet
    Contributor

    Ruling pointers: batch #282 items 3 and 4 (decision cards #22008 and #22011) · both A · maintainer 「同意」 2026-10-06T16:01Z

    Director seat, summon #35, session_01VYToj6PQehTEKNrjGM9akg (via the relay). Records: 6020151485 on #22008 and 6020163868 on #22011, both closed. This card stays pm:blocked on #15193 and #15195. Thread-read: none newer than the body's blocked notice.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    Ruling pointer: batch #283 item 5 (decision card #22007) · C · maintainer 「其他同意」 2026-10-07T01:25Z

    Director seat, summon #35, session_01VYToj6PQehTEKNrjGM9akg (via the relay). The record is 6028809298 on #22007, which is closed. This card stays pm:blocked on target:v18. Thread-read: 6020252365.

    • allowOrgOverride is renamed, not split and not re-meant. When the per-organization axis retires (ADR-0131 D6), the key at packages/spec/src/kernel/metadata-plugin.zod.ts:267 takes a name that says "may an environment overlay this packaged item", with an ADR-0087 D2 load-time conversion (an existing manifest naming the old key loads unchanged), and the per-organization path behind isOverlayAllowed (protocol.ts:15886) is deleted. The new name is fixed by the contract review of this card's change.
    • Not taken: A (a second key with the organization one frozen at false, a permanently dead key) and B (the old name governing environments).
    • Scope of this card gains: rename, D2 conversion, deletion of the per-organization path; generated baselines and docs follow. The five types that enable the key today keep their environment overlays through the rename. Together with the batch 🔗 Broken links detected in documentation #282 pointers above (withdrawal promotion A, Default Organization promotion A), C5's three rulings are now all on record.

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    Contributor

    Scope amended by #22007 (ruled C, 6028809298): rename allowOrgOverride to an environment-overlay key, with a load-time conversion, and delete the per-organization path

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T12:31Z. ⛔ Not a claim, ⛔ not a dispatch. The v18 line opened in this act (#15193 closed on the maintainer's word, 6037915987).

    What C5 now carries:

    • The rename. allowOrgOverride (packages/spec/src/kernel/metadata-plugin.zod.ts:267, today "Allow per-org overlay writes via runtime metadata API") is renamed to a key that says what it will then mean: may an environment overlay this packaged item. ⛔ The new name is fixed by the contract review of the C5 change, not here.
    • The conversion. An ADR-0087 D2 load-time conversion, so that an existing manifest naming the old key still loads unchanged.
    • The deletion. The per-organization path behind isOverlayAllowed (packages/metadata-protocol/src/protocol.ts:15933 on main) is deleted. Generated baselines and docs follow.
    • No overlay is lost. The five types that enable the key today (view, dashboard, report, translation, email template) keep their environment overlays through the rename.

    ⛔ Not taken: a second key with the organization one frozen at false (A), or the old name with a new meaning (B).

    This card stays pm:blocked behind C1 (#15195), per its Blocked-by: line. Its file surface is re-verified at claim.

  5. 88 remaining items

  6. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 3 (#15206, the S5 carry-overs: one closing PR) · 2026-10-11T10:47Z
    Session: session_01JfJfBUC3cQ6hhgm9MQK76T
    Account: os-project-manager (the seat's linked user, as GET /user answers it; the card's assignee)
    Branch: claude/issue-15206-s5-carry-overs
    Worktree: objectstack-issue-15206
    Domain: domain:engine
    Seat: domain:engine#1 (seat post #6367)
    File surface (read on origin/main b7cd1af9df; stop on a breach and explain it in the report):


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 15206,
      "status": "done",
      "branch": "claude/issue-15206-s5-carry-overs",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/22833",
      "session": "session_01JfJfBUC3cQ6hhgm9MQK76T — subagent of the PM session; identity = the branch named in claim 6108222334 (newest Claim: on the card, verified)",
      "premise_still_valid": true,
      "summary": "All four S5 carry-overs plus the optional real-engine reading, in draft PR #22833 (base origin/main b7cd1af9df, head 1fec8e5dd0; main had not moved, #22777 not landed, no merge needed). (1) reportUnhydratableOrgScopedRows (packages/metadata-protocol/src/protocol.ts): the projected sys_metadata read and each of the three ledger counts is its own term; a term whose read fails for any reason but a missing table is printed NOT MEASURED with its reason beside the measured terms, never a zero and never a silent line; boot verdict untouched. (2) Datasource double naming: READ ON A REAL BOOT FIRST (showcase via bootShowcase, sqlite-wasm, database file, tree baaa75e036): an environment row under the showcase code datasource name was named by [metadata_sealed_overlay_unserved] AND by the datasource restore warning, with different remedies. loadMetaFromDb now leaves rows whose name the host code-datasource set holds to the restore warning (new private isHostCodeDatasource, which isDeclaredCodeDatasource now reads through); manifest-only datasource names stay listed; every read still declines both. After (tree 1fec8e5dd0): named once, by the restore warning. (3) TSDoc of reportSealedOverlayRows, declinesStoredRow, refusePackagedBaseRemoval state the seal reach as the code does (isArtifactBacked && !registryAllowsOverlay, permission excepted) and that removing a merge-at-read row changes what is served for permission alone; the isUnservedSealedOverlay paragraph #22776 rewrote is untouched. (4) .changeset/15206-reads-environment-only.md: two FROM → TO rows inserted (projectPermissionMutation evt.organizationId; SysMetadataRepository.listDrafts row organizationId), each read by symbol at c8b062f011^ (FROM) and b7cd1af9df (TO); no existing row changed. (5) Real-engine [metadata_org_scoped_unserved] reading taken on both trees: the planted legacy organization row named per type, the three engine.count ledger reads answered (no NOT MEASURED term) — closes 6097501912 item 7 NOT MEASURED. Clause-②: no — no accept set or public surface moves; boot log content only, measured. New patch changeset .changeset/15206-boot-report-carry-overs.md (@objectstack/metadata-protocol) for (1) and (2). DEVIATIONS: (a) sys_metadata read isolated as a term too (hypothesis named the three ledgers; same failure shape); (b) isSealedManagedItem TSDoc carried the same \"restores the managed definition\" wording and is corrected in place (same file, comments only, named in PR body); (c) content/docs/concepts/metadata-lifecycle.mdx +1 sentence because (2) made its \"boot names each such row\" false for a host code datasource (file-surface addition); (d) new patch changeset; (e) check-empty-changeset is red by design (deliberate correction of a pending note; no skip-changeset), stated in the PR body; (f) zero label writes (none named in the dispatch, skip-changeset not applicable). FILES_CHANGED: .changeset/15206-boot-report-carry-overs.md (+10); .changeset/15206-reads-environment-only.md (+2); content/docs/concepts/metadata-lifecycle.mdx (+1/-1); packages/metadata-protocol/src/protocol.ts (+83/-31: code +40/-18, comments +41/-13; most code -18/+17 is the re-indent of the two reads wrapped by the per-term helper); packages/metadata-protocol/src/protocol.org-scoped-cold-boot-audit.test.ts (+33/-1); packages/metadata-protocol/src/protocol.reads-environment-only.test.ts (+23). LINE_BUDGET: 185 changed lines (+152/-33) vs the 200 advisory; source code +40/-18 vs the 40 advisory (over on the code half by the re-indent; net new code lines ~22). Worktree /home/user/objectstack-issue-15206 kept for a possible patch round (dist built); no background process left running.",
      "tests": "BUILD (os-verify-lock, slot issue-15206): pnpm --workspace-concurrency=2 --filter @objectstack/metadata-protocol^... build → VERDICT command-exit 0; pnpm turbo run build --filter=@objectstack/dogfood^... --concurrency=2 at baaa75e036 → exit 0 (63 tasks, 9 cached); pnpm --filter @objectstack/metadata-protocol build at 1fec8e5dd0 → exit 0 (dist carries isHostCodeDatasource x4). UNIT (packages/metadata-protocol, vitest --maxWorkers=2): protocol.org-scoped-cold-boot-audit.test.ts + protocol.reads-environment-only.test.ts → 28/28 at baaa75e036, 29/29 at 1fec8e5dd0. New pins: \"[#15206] a read that fails costs its own term only\" (history count throws; sys_metadata detail and commit/audit counts reported; history NOT MEASURED with reason); failing-probe case now asserts sys_metadata NOT MEASURED instead of silence; \"[#15206] a row under a datasource name the host defines in code is left to the datasource restore warning; a package-declared one is still listed\". ABLATION (committed state baaa75e036, node scripts/ablation-replace.mjs WRAP mode, subject ./protocol.js from src so no build in the path): anchor unmeasured.push(...) in the per-term catch → \"throw error; // ABLATION-15206\" (pre-fix behaviour); anchor x1 → x0, replacement x0 → x1, blob e09bc9f2578c → c9b85129dc0b, on-disk grep 1/0; vitest: 2 failed / 5 passed (both isolation cases red: no [metadata_org_scoped_unserved] line at all); restore: blob after restore == HEAD e09bc9f2578c, git diff HEAD empty. Direction observed: red, as expected. FULL PACKAGE at 1fec8e5dd0: pnpm --filter @objectstack/metadata-protocol test → 225 files passed / 3 skipped, 28131 tests passed / 19 skipped (VERDICT command-exit 0); typecheck (tsc --noEmit) → exit 0; tsc --listFiles contains both edited test files (count 2). CONSUMERS (every test file outside the package calling loadMetaFromDb/restoreMetadataFromDb, against rebuilt dist, 1fec8e5dd0): objectql 15 files/302 tests pass; runtime 3/36; plugin-email 1/40; plugin-security 1/30; service-automation 1/14; metadata 1/9; dogfood 4 files/22 tests (datasource-restore-code-wins, meta-door-code-datasource, permission-set-clone-boot-unowned-warning, showcase-object-extension-scalar-divergence) — all exit 0. Observation: 32 NOT MEASURED lines in the objectql run from engine doubles without count (all green). REAL BOOT (temporary uncommitted dogfood file, deleted; bootShowcase over a database file, rows planted with system context between two boots, lines read from the second boot): before (baaa75e036) sealed line \"datasource x1 (showcase_external)\" AND \"datasource restore: sys_metadata holds a stored row for showcase_external\"; after (1fec8e5dd0) only the restore warning; [metadata_org_scoped_unserved] named the planted legacy view row per type on both trees with no NOT MEASURED term. LINT: eslint --no-inline-config --format json on the 3 edited TS files → 3 files, 0 errors, 0 warnings; eslint.config.mjs enables no type-aware linting (no parserOptions.project), so untouched files cannot move; repo-wide lint is CI. GATES at 1fec8e5dd0: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 95 (dispatch-time 59 + docs/test-file families); all run sequentially, exit captured before any pipe; --ran reconciliation: 95 derived / 95 run / 0 NOT-MEASURED (derived zero). check:skill-examples and check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: unrelated unbuilt packages), re-run after turbo build of those packages → exit 0 (recorded as 0 below). check-empty-changeset exit 1 is the deliberate-correction verdict on the pending changeset, explained in the PR body. Per command: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 | node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 | node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 | node scripts/check-changeset-no-major.mjs --self-test :: exit 0 | node scripts/check-ci-filter-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 | node scripts/check-comment-mask-adoption.mjs :: exit 0 | node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0 | node scripts/check-comment-mask-corpus.mjs :: exit 0 | node scripts/check-doc-frontmatter.mjs :: exit 0 | node scripts/check-doc-frontmatter.mjs --self-test :: exit 0 | node scripts/check-doc-route-spelling.mjs --advisory :: exit 0 | node scripts/check-doc-route-spelling.mjs --self-test :: exit 0 | node scripts/check-docs-section-name.mjs :: exit 0 | node scripts/check-docs-section-name.mjs --self-test :: exit 0 | node scripts/check-dts-emitted.mjs --self-test :: exit 0 | node scripts/check-empty-changeset.mjs --base origin/main :: exit 1 | node scripts/check-empty-changeset.mjs --self-test :: exit 0 | node scripts/check-issue-citations.mjs :: exit 0 | node scripts/check-keyed-text-bounds.mjs :: exit 0 | node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0 | node scripts/check-platform-object-tenancy-census.mjs :: exit 0 | node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0 | node scripts/check-plugin-teardown-shape.mjs :: exit 0 | node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0 | node scripts/check-registry-log-declared.mjs :: exit 0 | node scripts/check-registry-log-declared.mjs --self-test :: exit 0 | node scripts/check-rest-log-spy-declared.mjs :: exit 0 | node scripts/check-rest-log-spy-declared.mjs --self-test :: exit 0 | node scripts/check-section-landing-index.mjs :: exit 0 | node scripts/check-section-landing-index.mjs --self-test :: exit 0 | node scripts/check-system-context-census.mjs :: exit 0 | node scripts/check-system-context-census.mjs --self-test :: exit 0 | node scripts/check-undeclared-dep-imports.mjs :: exit 0 | node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0 | node scripts/docs-audit/check-affected-docs.mjs :: exit 0 | node scripts/docs-audit/check-drift-comment.mjs :: exit 0 | node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 | node scripts/release-pending-publish.mjs --self-test :: exit 0 | pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 | pnpm --filter @objectstack/lint run check:doc-security-posture :: exit 0 | pnpm --filter @objectstack/spec run check:docs :: exit 0 | pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 | pnpm --filter @objectstack/spec run check:empty-state :: exit 0 | pnpm --filter @objectstack/spec run check:liveness :: exit 0 | pnpm --filter @objectstack/spec run check:skill-examples :: exit 0 | pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0 | pnpm --filter @objectstack/spec run check:variant-docs :: exit 0 | pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0 | pnpm check:changeset-gate-self-tests :: exit 0 | pnpm check:corpus-claim-drift :: exit 0 | pnpm check:cross-package-test-inputs :: exit 0 | pnpm check:dispatcher-error-vocabulary :: exit 0 | pnpm check:doc-anchors :: exit 0 | pnpm check:doc-authoring :: exit 0 | pnpm check:docs-audit-scope :: exit 0 | pnpm check:docs-redirects :: exit 0 | pnpm check:docs-single-h1 :: exit 0 | pnpm check:docs-spec-enumerations :: exit 0 | pnpm check:docs-transcript-drift :: exit 0 | pnpm check:driver-memory-census :: exit 0 | pnpm check:dts-closure :: exit 0 | pnpm check:dual-build-cjs-loads :: exit 0 | pnpm check:durability-log-level :: exit 0 | pnpm check:engine-double-contract :: exit 0 | pnpm check:error-status-conformance :: exit 0 | pnpm check:filter-alias-parity :: exit 0 | pnpm check:gitlink-declared :: exit 0 | pnpm check:issue-citations :: exit 0 | pnpm check:lean-entry-closure :: exit 0 | pnpm check:logger-receiver-detach :: exit 0 | pnpm check:nul-bytes :: exit 0 | pnpm check:objectql-double-limit :: exit 0 | pnpm check:objectui-changeset :: exit 0 | pnpm check:org-identifier :: exit 0 | pnpm check:overlay-whitelist-table :: exit 0 | pnpm check:page-declaration-shape :: exit 0 | pnpm check:pm-changeset-deadline-census :: exit 0 | pnpm check:published-files :: exit 0 | pnpm check:published-readme-links :: exit 0 | pnpm check:query-options-erasure :: exit 0 | pnpm check:react-page-adapter-contract :: exit 0 | pnpm check:refd-timer-probe :: exit 0 | pnpm check:role-word :: exit 0 | pnpm check:skill-identifier-liveness :: exit 0 | pnpm check:slot-lookup :: exit 0 | pnpm check:sourcemap-no-sources-content :: exit 0 | pnpm check:test-source-alias :: exit 0 | pnpm check:tier-file-adoption :: exit 0 | pnpm check:type-check-coverage :: exit 0 | pnpm check:type-check-debt :: exit 0 | pnpm check:vendor-version-stamps :: exit 0 | pnpm check:watch-hint-literal :: exit 0 | pnpm check:where-matcher :: exit 0",
      "mcp_calls": "0 — no MCP GitHub tool used (reads via gh api GET; writes via the fleet-write relay)",
      "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, fleet-write, executed as objectstack-fleet[bot]) carrying 3 endpoint writes: POST /repos/objectstack-ai/objectstack/pulls (draft #22833), POST /repos/objectstack-ai/objectstack/issues/22833/assignees (os-project-manager), POST /repos/objectstack-ai/objectstack/issues/15206/comments (this os-dev-report). Plus git push (not REST). 0 label writes.",
      "open_questions": [
        {
          "question": "Which boot line owns a stored environment row under a datasource name the host defines in code?",
          "options": [
            "A (this PR): the datasource restore warning (restoreRuntimeDatasources); [metadata_sealed_overlay_unserved] leaves exactly the host code-datasource set to it. Cost: a host composing no datasource-admin plugin names such a row nowhere at boot (the pre-S5 state); every read still declines it.",
            "B: the sealed token keeps it and the restore warning is dropped. Cost: a cross-package edit in @objectstack/service-datasource, four pinned assertions there and a changeset, reversing the #21922 design; the sealed line would keep describing the host default datasource as an item a managed package ships."
          ],
          "recommendation": "A, because the restore is the actor that skips the row and names its exact door, declinesStoredRow already designates it as the reporter, and B reverses a pinned design for a cosmetic item. Not a blocker; the seat can overturn."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door, measured on tree 1fec8e5dd0 — the datasource-admin and metadata read doors answer 200 with a legacy organization-scoped datasource row that the boot restore registered, while [metadata_org_scoped_unserved] names the same row as served by no read and loaded by no boot · evidence: restoreRuntimeDatasources → loadDatasourceRows (packages/services/service-datasource/src/datasource-admin-plugin.ts) read datasource rows by type and state with no organization predicate; the pending .changeset/15206-reads-environment-only.md states such a row is served by no read and loaded by no boot · Seam: spec:sys_metadata organization_id (ADR-0131 D6) → runtime:DatasourceAdminServicePlugin.restoreRuntimeDatasources · family: ADR-0131 D6 read narrowing (#15194 tree; #15206 closes with #22833) · disclosure: security card, class/location/function only · dedupe words: loadDatasourceRows organization_id; datasource restore legacy organization row; restoreRuntimeDatasources environment predicate; datasource-admin tenant-less read",
        "class: b · reach: exception: release-text — .changeset/15206-reads-environment-only.md (pending v18 note) says a stored fork of a code-declared permission set keeps its own ruling \"(detection reading and Discard Overlay)\" and is still served; #22776 retired the Discard Overlay action in the same pending line and a cold boot refuses such a fork (ADR-0048) · not edited here: the dispatch fenced this PR to the two table rows · carrier: the seat, a one-clause edit of that bullet before v18 · dedupe words: Discard Overlay 15206 changeset; permission-set fork release note; reads-environment-only changeset stale clause",
        "carrier: none · noted in PR Acceptance notes, not filed: engine test doubles without count now print a [metadata_org_scoped_unserved] line naming the ledgers NOT MEASURED (32 lines in the objectql targeted run), every test green; a real engine has count."
      ]
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 15206,
      "round": 2,
      "status": "done",
      "branch": "claude/issue-15206-s5-carry-overs",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/22833",
      "session": "session_01JfJfBUC3cQ6hhgm9MQK76T — subagent of the PM session; identity = the branch named in claim 6108222334",
      "premise_still_valid": true,
      "summary": "Round 2 on the seat rulings: open question → A, finding 1 → #22835 (not fixed here, so this PR no longer closes #15206), finding 2 → folded in, finding 3 → recorded only. (1) .changeset/15206-reads-environment-only.md: only the last sentence of the [Triage ruling Q1 → C] bullet changed. It was \"keeps its own ruling (detection reading and Discard Overlay) and is still served\". It now reads \"keeps its own ruling instead: the reads do not decline it, a cold boot refuses a deployment that holds one (ADR-0048), and the offline os migrate security-catalog-overlays removes it\". The new wording follows main: the isUnservedSealedOverlay TSDoc as #22776 left it, and the cold-boot refusal in ObjectQLPlugin.refuseEnvironmentHeldSecurityCatalogNames. Commit 75b4c850fa, pushed fast-forward from 1fec8e5dd0. Two sentences that #22835 contradicts were left as they stand and named in the PR body as pending #22835: the first bullet's \"served by no read and loaded by no boot\", and the boot line's \"no read serves them, boot does not load them\". (2) PR #22833 body: one issue_patch, read back identical (11460 bytes). Line 1 is now \"Part of #15206\" and line 2 \"Clause-②: no\". No closing keyword remains (body scanned; GraphQL closingIssuesReferences is unavailable here, so that read is NOT MEASURED). The body names #22835 as the carrier of the remaining gap. It has a DELIBERATE CORRECTION section: the one file the gate names, and a 3-row table giving each edit's location, the was/now text and why it must ride this PR — two inserted FROM → TO rows ordered by triage 6107774330 and checked by symbol, plus the Discard Overlay sentence retired by #22776. It also records that the S5 sentences awaiting #22835 are left as they stand. Branch: main moved 3 commits (#22777 among them). git merge-tree of efcbac73cc with 1fec8e5dd0 is clean and the PR answers mergeable:true, so there was no merge and the push was fast-forward only, per the seat. The worktree was recreated from the local branch (pnpm install --frozen-lockfile, exit 0) and is kept for any later round. LINE_BUDGET: 187 changed lines (+153/-34) over 6 files. Round 2 added +1/-1 in .changeset/15206-reads-environment-only.md; no source changed.",
      "tests": "No source changed in round 2, so the round-1 tests (on 1fec8e5dd0, comment 6108953446) still describe the code. BUILD: turbo build (dogfood^... closure plus the 8 packages two gates read) → 71/71 tasks, all cached. dist checked current: metadata-protocol/dist/index.js contains isHostCodeDatasource 4 times and unmeasured 4 times. GATES at 75b4c850fa: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack re-derived 95 families, identical to round 1. All ran sequentially, each exit code captured before any pipe. --ran reconciliation: 95 derived / 95 run / 0 NOT-MEASURED (derived zero, no exit 3). 94 exit 0; check-empty-changeset exits 1 with ::error on .changeset/15206-reads-environment-only.md, the expected DELIBERATE CORRECTION verdict. The derivation warned STALE TREE: 3 commits behind origin/main, and scripts/sdui-manifest.record.json changed there. No gate in the list reads that file's content: check-changeset-no-major only names the path, to assert the console build does not copy it. CI judges the merge ref with main. Per command: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 | node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 | node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 | node scripts/check-changeset-no-major.mjs --self-test :: exit 0 | node scripts/check-ci-filter-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 | node scripts/check-comment-mask-adoption.mjs :: exit 0 | node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0 | node scripts/check-comment-mask-corpus.mjs :: exit 0 | node scripts/check-doc-frontmatter.mjs :: exit 0 | node scripts/check-doc-frontmatter.mjs --self-test :: exit 0 | node scripts/check-doc-route-spelling.mjs --advisory :: exit 0 | node scripts/check-doc-route-spelling.mjs --self-test :: exit 0 | node scripts/check-docs-section-name.mjs :: exit 0 | node scripts/check-docs-section-name.mjs --self-test :: exit 0 | node scripts/check-dts-emitted.mjs --self-test :: exit 0 | node scripts/check-empty-changeset.mjs --base origin/main :: exit 1 | node scripts/check-empty-changeset.mjs --self-test :: exit 0 | node scripts/check-issue-citations.mjs :: exit 0 | node scripts/check-keyed-text-bounds.mjs :: exit 0 | node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0 | node scripts/check-platform-object-tenancy-census.mjs :: exit 0 | node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0 | node scripts/check-plugin-teardown-shape.mjs :: exit 0 | node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0 | node scripts/check-registry-log-declared.mjs :: exit 0 | node scripts/check-registry-log-declared.mjs --self-test :: exit 0 | node scripts/check-rest-log-spy-declared.mjs :: exit 0 | node scripts/check-rest-log-spy-declared.mjs --self-test :: exit 0 | node scripts/check-section-landing-index.mjs :: exit 0 | node scripts/check-section-landing-index.mjs --self-test :: exit 0 | node scripts/check-system-context-census.mjs :: exit 0 | node scripts/check-system-context-census.mjs --self-test :: exit 0 | node scripts/check-undeclared-dep-imports.mjs :: exit 0 | node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0 | node scripts/docs-audit/check-affected-docs.mjs :: exit 0 | node scripts/docs-audit/check-drift-comment.mjs :: exit 0 | node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 | node scripts/release-pending-publish.mjs --self-test :: exit 0 | pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 | pnpm --filter @objectstack/lint run check:doc-security-posture :: exit 0 | pnpm --filter @objectstack/spec run check:docs :: exit 0 | pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 | pnpm --filter @objectstack/spec run check:empty-state :: exit 0 | pnpm --filter @objectstack/spec run check:liveness :: exit 0 | pnpm --filter @objectstack/spec run check:skill-examples :: exit 0 | pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0 | pnpm --filter @objectstack/spec run check:variant-docs :: exit 0 | pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0 | pnpm check:changeset-gate-self-tests :: exit 0 | pnpm check:corpus-claim-drift :: exit 0 | pnpm check:cross-package-test-inputs :: exit 0 | pnpm check:dispatcher-error-vocabulary :: exit 0 | pnpm check:doc-anchors :: exit 0 | pnpm check:doc-authoring :: exit 0 | pnpm check:docs-audit-scope :: exit 0 | pnpm check:docs-redirects :: exit 0 | pnpm check:docs-single-h1 :: exit 0 | pnpm check:docs-spec-enumerations :: exit 0 | pnpm check:docs-transcript-drift :: exit 0 | pnpm check:driver-memory-census :: exit 0 | pnpm check:dts-closure :: exit 0 | pnpm check:dual-build-cjs-loads :: exit 0 | pnpm check:durability-log-level :: exit 0 | pnpm check:engine-double-contract :: exit 0 | pnpm check:error-status-conformance :: exit 0 | pnpm check:filter-alias-parity :: exit 0 | pnpm check:gitlink-declared :: exit 0 | pnpm check:issue-citations :: exit 0 | pnpm check:lean-entry-closure :: exit 0 | pnpm check:logger-receiver-detach :: exit 0 | pnpm check:nul-bytes :: exit 0 | pnpm check:objectql-double-limit :: exit 0 | pnpm check:objectui-changeset :: exit 0 | pnpm check:org-identifier :: exit 0 | pnpm check:overlay-whitelist-table :: exit 0 | pnpm check:page-declaration-shape :: exit 0 | pnpm check:pm-changeset-deadline-census :: exit 0 | pnpm check:published-files :: exit 0 | pnpm check:published-readme-links :: exit 0 | pnpm check:query-options-erasure :: exit 0 | pnpm check:react-page-adapter-contract :: exit 0 | pnpm check:refd-timer-probe :: exit 0 | pnpm check:role-word :: exit 0 | pnpm check:skill-identifier-liveness :: exit 0 | pnpm check:slot-lookup :: exit 0 | pnpm check:sourcemap-no-sources-content :: exit 0 | pnpm check:test-source-alias :: exit 0 | pnpm check:tier-file-adoption :: exit 0 | pnpm check:type-check-coverage :: exit 0 | pnpm check:type-check-debt :: exit 0 | pnpm check:vendor-version-stamps :: exit 0 | pnpm check:watch-hint-literal :: exit 0 | pnpm check:where-matcher :: exit 0",
      "mcp_calls": "0",
      "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, fleet-write, as objectstack-fleet[bot]): PATCH /repos/objectstack-ai/objectstack/issues/22833 (PR body, issue_patch, read back identical), and POST /repos/objectstack-ai/objectstack/issues/15206/comments (this round-2 os-dev-report). Plus git push (fast-forward 1fec8e5dd0..75b4c850fa). 0 label writes.",
      "open_questions": [],
      "out_of_scope_findings": [
        "none new in round 2. Round 1 findings as ruled by the seat: finding 1 is filed as #22835 and not touched here; finding 2 is folded into this PR; finding 3 is recorded, not filed."
      ]
    }

    Generated by Claude Code

  9. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    ACCEPT (seat review): PR #22833 at head 75b4c850fa (the S5 carry-overs)

    domain:engine seat 1 (#6367) · session_01JfJfBUC3cQ6hhgm9MQK76T · 2026-10-11T13:27Z. Claim 6108222334. Dev reports 6108953446 (round 1) and 6109357048 (round 2). Contract review PASS 6109504501 (CONTRACT_REVIEW_TIER, same head), which is also the DELIBERATE CORRECTION confirmation. Read against GitHub and origin/main. ⛔ Classes, positions and functions only.

    Shape.

    • Ready to queue: base main, assigned os-project-manager, mergeable: true.
    • Line 1 is Part of #15206, and the body carries no closing keyword.
    • Line 2 is Clause-②: no.
    • Six files, 187 lines. NOT governed.

    What it does (each item carried by S5's records):

    • [metadata_org_scoped_unserved] isolates each term: the sys_metadata detail and each of the three ledger counts. A failing read prints NOT MEASURED with its reason, never a zero. The boot verdict is unchanged. Pinned, and ablation-verified (2 red).
    • The host's code-declared datasource rows are named once, by the datasource restore warning, which was read on a real boot first. Manifest-only names stay listed, and every read still declines both.
    • The TSDoc of reportSealedOverlayRows, declinesStoredRow, refusePackagedBaseRemoval and isSealedManagedItem states the seal's reach as the code computes it.
    • .changeset/15206-reads-environment-only.md:
    • The optional real-engine reading of [metadata_org_scoped_unserved] was taken on both trees, which closes S5's last NOT MEASURED.

    Ruled by this seat:

    CI on this head: 42 check-runs, all concluded (36 success, 4 rostered skips, 2 red). Every required context is green. The red is Check Changeset ×2, the foreign changeset rule's DELIBERATE CORRECTION class, confirmed by 6109504501 and recorded on the PR.

    Landing.


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    Landed (stage): PR #22833 → 8c105e3d67, the S5 carry-overs · domain:engine seat 1 (#6367) · session_01JfJfBUC3cQ6hhgm9MQK76T · 2026-10-11T13:53Z

    ⛔ Classes, positions and functions only.


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    Contributor

    Closed: the last gap landed · domain:engine seat 1 (#6367) · session_01JfJfBUC3cQ6hhgm9MQK76T · 2026-10-11T16:38Z

    ⛔ Classes, positions and functions only.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions