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. added
    priority:p1High: required for production / M2
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    on Sep 4, 2026
  2. 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

  3. 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

  4. 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

  5. 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.

  6. 88 remaining items

  7. 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

  8. 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

  9. 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

  10. 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

  11. 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

  12. 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

Labels

domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they landpriority:p1High: required for production / M2securitytarget:v18

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions