Skip to content

seed loader: a declared seed row a person deleted comes back under a new id at the next seed replay — record landed keys per organization and skip the ones now absent #31021

Closed

Description

@objectstack-fleet

repo:cloud#3 · hotlong · session_01Q4EjjRhUZjdy8VXs6Kkur2

Filing gate: (b) a defect with a named consumer, measured by the objectstack-ai/cloud#3657 dev (report on that card; PR objectstack-ai/cloud#3685). Platform defects go to the platform: 「平台的问题应该在平台处理」 (objectstack#30765).

维护者速读

用户删掉的示例数据,下次装包或升级、种子数据有变化时,平台会按新 id 重新插回来。cloud 实测 3 次,结果都一样。自托管的 objectstack serve 每次启动都会重跑种子,按代码看也是同样的问题。需要平台记住每个组织哪些种子行已经落过地,之后被删掉的就不再插回。

Measured (cloud tenant-kernel rig: real ArtifactKernelFactory on SQLite with the framework seed-replayer; pin c50e0dfa; 3 runs, default and upsert modes)

  • Per-row delete, then an upgrade that changes the seed union: the deleted row returns under a NEW id. Run 1: Globex k6Gf2KcO40siHUPg came back as YkNS7s5N5l9jFMbn.
  • The sanctioned cleanup with one edited row kept: deleted=4, then the upgrade put all 4 back.
  • A full cleanup while data[] is still served (an environment's own app): everything returned.
  • Re-inserting code: the framework SeedLoaderService inserts any declared row it does not find (create-only rule, [Decision] A restart puts seeded records back: a customer's edit to a seeded row is overwritten by the next boot #30081). runtime/src/app-plugin.ts builds the SeedLoaderRequestSchema with no exclusion; SeedLoaderConfigSchema has no skip or tombstone option. objectstack serve re-runs its inline seed create-only on every boot (read, not measured).

Expected (shape A, chosen under the standing rule)

  • The framework keeps a durable per-organization record of which seed rows landed (object + externalId value). The seed loader skips a key recorded as landed that is now absent. One fix covers objectstack serve and hosted; cloud adds nothing, or only passes the organization.
  • A deliberate re-seed (a reset or "restore sample data" action) can clear the record. The lane names the door.

Acceptance

  • Tests: delete a seeded row → a union change or reboot does not bring it back; an edited row is untouched; a new seed row added by an upgrade still lands; a reset re-seeds.

Consumer: objectstack-ai/cloud#3657 item 2, which stays open on this card.

Suggested-grade: p1.

Dedupe (2026-11-06): seed loader tombstone → 53 hits, seed replay deleted row → 188, create-only seed deleted → 225; the top hits are QA runs and closed lint cards. None covers this.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)
    domain:serverDomain lane — seat card indexed by label:pm:seat
    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 · p1 kept · domain:server · 2026-11-06T18:58Z

    ⛔ Not a claim.

    • A seed row a person deleted comes back under a new id on the next seed replay (an install, an upgrade, or serve's boot replay), because the create-only loader inserts any declared row it does not find. Measured 3 times on cloud's tenant-kernel rig.
    • p1 kept: deleted customer data reappears, on both cloud and self-host. Lane domain:server (SeedLoaderService, runtime/app-plugin.ts). pm:queue.
    • The fix adds a durable per-organization record of landed seed keys, which is new platform state. The PR's contract review checks its shape. A spec-visible key brings the spec lane's review.

    Generated by Claude Code

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

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    Claim: PM loop round 1 · 2026-11-07T02:54Z
    Session: session_017xRBcTJTE7kSbcMoJQ4Txf
    Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-31021-seed-landed-keys
    Worktree: objectstack-issue-31021
    Domain: domain:server
    Seat: domain:server#1
    File surface: packages/metadata-protocol/src/seed-loader.ts and its tests (the per-organization record of landed seed keys; skip a recorded key that is now absent), packages/runtime/src/app-plugin.ts where it builds the seed load request and the serve boot replay (and packages/cli only if serve's inline seed has its own call site), the store the record lives in (an existing system store, or a new platform object, wherever the code puts it; the dev names it and says why), one changeset; amended in review of PR #31083: the new platform object sys_seed_landed_key in packages/platform-objects/src/system/ with its registration and the regenerated scripts/platform-object-tenancy-census.json, plus three lines outside the server package trees that the object forces: ONE roster line 'sys_seed_landed_key' in packages/spec/src/system/constants/platform-object-names.ts PLATFORM_OBJECTS_BY_PACKAGE['platform-objects'] (in the same commit as the object, since the roster test checks both ways, per the sys_lifecycle_state precedent on #30751), its ORGANIZATION_OWNERSHIP_INVENTORY row in packages/cli/src/utils/organization-ownership-inventory.ts, and 'sys_seed_landed_key' in plugin-audit's SKIP_OBJECTS. ⛔ Nothing else under packages/spec/**; the spec line owes a CONTRACT_REVIEW_TIER review, requested from domain:spec#1. ⛔ skills/**. Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: xhigh (p1, new durable platform state)
    Clause-②: yes
    Metadata-protocol: semantic
    Responsibility: the code that produces the risk is SeedLoaderService in packages/metadata-protocol/src/seed-loader.ts in objectstack (the create-only rule inserts any declared row it does not find), driven by packages/runtime/src/app-plugin.ts | no platform path covers it: SeedLoaderConfigSchema has no skip or tombstone option | it is reached on every package install or upgrade that changes the seed union, and on every objectstack serve boot; used today by objectstack-ai/cloud#3657
    Thread-read: 6692929632
    Premise: holds (read on origin/main 3f61e4f8 at 2026-11-07T02:54Z: no landed-key record in seed-loader.ts, runtime/src or the spec system objects; a grep for tombstone|landedKeys|landed_keys|seed_landed finds nothing in the loader, and the control externalId has 127 hits in the same file)
    Serial constraints cleared: none. No in-flight domain:server claim declares seed-loader.ts or app-plugin.ts (#31048, #30922, #30892, #30803 and #29594 read; #29594 declares metadata-protocol/src/protocol-*.ts only). Same-day merges on these paths: 90523379 (#31018), d9f8f7fb (#31008). The dev works on the merged code.

    On Clause-② and Metadata-protocol (corrected in review of PR #31083, from the dev's measurement on the built declarations): yes, because SysSeedLandedKey is a new export of @objectstack/platform-objects and SeedLoaderServiceOptions gains landedKeys; and semantic, because an authored seed mode ignore or upsert no longer re-inserts a removed row whose key landed.

  5. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf
    os-dev-report

    {
      "issue": 31021,
      "status": "blocked",
      "branch": "claude/issue-31021-seed-landed-keys",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31083",
      "session": "session_017xRBcTJTE7kSbcMoJQ4Txf",
      "premise_still_valid": true,
      "summary": "Shape A is implemented and pushed as draft #31083. It leaves 3 lines, outside the claimed surface, unwritten; the one that blocks is a packages/spec edit. SeedLoaderService gains a constructor option landedKeys: 'honour' | 'reseed'. With it, the loader records the key of every row an upsert or ignore dataset lands (inserted, updated or matched) in a new platform object, sys_seed_landed_key, scoped to the organization the load seeds (config.organizationId, or the sole Default Organization on a serve boot). The key is the externalId fields and values, JSON-encoded; an id key is recorded under its authored id. The loader does not insert again a recorded key whose row is gone. A reference to such a row is left as it is, and a row keyed on one is withdrawn with it, so nothing is reported unresolved. AppPlugin's three loads honour the record: the inline boot seed that serve runs, the per-organization seed-replayer that hosts run, and the dev hot-reload seeder. The door for a deliberate re-seed is seed-replayer(orgId, { reseed: true }). BLOCKED: no existing platform state fits (sys_setting refuses internal state; sys_migration and sys_lifecycle_state are tenant-less; sys_recycle_bin is reaped). A new platform object needs one line in packages/spec/src/system/constants/platform-object-names.ts, which the claim's ban on packages/spec/** forbids. Until it lands, spec's platform-object-names.test.ts is red: measured 1 failed, 13 passed, naming sys_seed_landed_key. Two more lines are owed outside the surface. First, a row in packages/cli/src/utils/organization-ownership-inventory.ts: its pin enumerates the spec registry, so it reds once the spec line lands, and os migrate organization-ownership refuses the table without it. Second, recommended: 'sys_seed_landed_key' in plugin-audit SKIP_OBJECTS, on the sys_lifecycle_state precedent. Zone 2 measurements: seed-loader-landed-ids.test.ts reports per-load landed row ids, not keys. Those ids are not durable and carry no organization of their own, so they cannot be the record; the record reuses the same noteLanded signal. serve has no seed call site in packages/cli and seeds through AppPlugin. The hosted ArtifactKernelFactory call site is NOT MEASURED: add_repo for objectstack-ai/cloud was refused for lack of access.",
      "tests": "Head d1abef04. metadata-protocol full suite: Test Files 321 passed, 4 skipped (325); Tests 22525 passed, 26 skipped. The new describe in seed-loader-landed-ids.test.ts runs 13 cases ('-t 31021' gives 13 passed, 14 skipped of 27). runtime src/app-plugin.seed-landed.test.ts: Tests 6 passed (6), 2 of them new. runtime full suite on the merged tree f72ceee6: Test Files 553 passed (553); Tests 8878 passed, 19 skipped. Between f72ceee6 and the final head, runtime differs only by one test-file import, and that file was re-run at d1abef04. platform-objects: Test Files 117 passed; Tests 1638 passed. typecheck of metadata-protocol, runtime and platform-objects: Done for each. Ablations went through scripts/ablation-replace.mjs at 7a89f01d; every mutation landed, every restore read blob == HEAD with git diff HEAD empty, and the ablated lines are byte-identical at d1abef04. No dist build was involved: metadata-protocol tests import ./seed-loader.js and the runtime tests import ./app-plugin from src. A1, isWithdrawnRow answers false: 8 failed, 19 passed ('expected [ Acme, Globex ] to deeply equal [ Acme ]'). A2, withdrawn reference branch deleted: 4 failed, 23 passed (success false, the pass-2 unresolved errors return). A3, recordLandedKeys never called: 10 failed, 17 passed. A4, AppPlugin passes no landedKeys: 2 failed, 4 passed ('expected [ CASE-1, CASE-2 ] to deeply equal [ CASE-2 ]'). A5, replayer ignores reseed: 1 failed, 5 passed ('expected { inserted: +0 } to match object { inserted: 1 }'). A6, record on by default: 1 failed, 26 passed. Named-gap measurement: spec src/system/constants/platform-object-names.test.ts gives 1 failed, 13 passed ('registry group platform-objects is out of date ... sys_seed_landed_key'). cli src/utils/organization-ownership-inventory.test.ts gives 26 passed, green only because it enumerates the spec registry.",
      "gates": "Derived at d1abef04 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, change set from merge base cb8f52000 (10 paths): 72 commands. All 72 were run sequentially, each exit code written to disk before any read. --ran gives 72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. Every command exited 0 at d1abef04. The first pass at f72ceee6 (63 derived, before the changeset existed) had 5 non-zero, and each now exits 0. check:query-options-erasure exited 1 on a real finding: seed-loader.ts erasure count 3 to 4. Fixed by typing the record read as EngineQueryOptions. check:test-source-alias exited 1 on a real finding: the edited test reached @objectstack/metadata lazily. Fixed with a module-top import. check-plugin-teardown-shape --self-test exited 3 because its fixture commit 621a4876 was missing from the shallow clone; fetched. check:dual-build-cjs-loads and check:i18n exited 3 because the build was missing; after turbo run build (119/119, VERDICT 0) they report 116 entries across 71 packages load, and 10 packages in sync. Outside the derivation, pnpm lint exits 0 (VERDICT command-exit 0). PR check-runs at d1abef04, read once and not awaited: 19 completed (PR-body guards, Governed Surface Queue Guard, Check PR Size and Test UI success; the rest skipped), 18 in_progress. Expected red on CI: Test Core runs packages/spec, and platform-object-names.test.ts stays red until the spec line lands (named gap).",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "line_budget": "1057 changed lines (+1043 / -14) in 10 files at d1abef04, against the 3000 human-merge threshold: under. No skills/** file is touched, so no skill line ratchet applies. The owed lines add about 3 lines across 3 files.",
      "files_changed": [
        "packages/metadata-protocol/src/seed-loader.ts",
        "packages/metadata-protocol/src/seed-loader-landed-ids.test.ts",
        "packages/runtime/src/app-plugin.ts",
        "packages/runtime/src/app-plugin.seed-landed.test.ts",
        "packages/platform-objects/src/system/sys-seed-landed-key.object.ts",
        "packages/platform-objects/src/system/index.ts",
        "packages/platform-objects/src/plugin.ts",
        "packages/platform-objects/src/plugin.test.ts",
        "scripts/platform-object-tenancy-census.json",
        ".changeset/seed-landed-keys-31021.md"
      ],
      "deviations": [
        "The PR was opened with NO assignee, against the dispatch's 'assigned to sunhaolin' and repo .claude/agents/os-dev.md rule 2. AGENTS.md wins: in its Claim paragraph, the executor never writes the PR's assignee, and pr_create carries none; the seat sets it at hand-over. scripts/pm/fleet-write/ops.mjs says the same. The seat should assign sunhaolin at hand-over.",
        "Clause-②: yes (widening), not the claimed no, per the dispatch's measurement rule. Measured on built declarations: SysSeedLandedKey is a new export of @objectstack/platform-objects (dist/index.d.ts), and SeedLoaderServiceOptions gains landedKeys (metadata-protocol dist/index.d.ts). There is no new schema option and no new error code, and the branch diff touches packages/spec 0 times.",
        "Metadata-protocol: semantic, not the claimed none. Under the AGENTS.md definition this is a changed meaning: an authored mode 'ignore' or 'upsert' no longer re-inserts a removed row whose key landed. No key is added. With the owed spec line it would also be 'added', and semantic outranks added. The changeset is minor for metadata-protocol, runtime and platform-objects.",
        "The gates were derived WITHOUT passing changed paths: os-dev.md tells the dev to let the script take the change set from the merge base. The dispatch's spelling passes paths, so the two conflict, and os-dev.md wins over the dispatch.",
        "scripts/platform-object-tenancy-census.json was regenerated with 'node scripts/platform-object-tenancy-census.mjs --write'. It is a generated artifact of the new store, required by check:platform-object-tenancy-census. It sits outside the literal surface list, though inside 'the store the record lives in'.",
        "The new pins went into the existing harness files as top-level describes, per ruling record 6583487846, and not into new test files.",
        "pnpm lint was run because the dispatch asked. os-dev.md calls it CI-owned. It exited 0.",
        "Ablations were taken at 7a89f01d, before the main merge. The lines they mutate are byte-identical at d1abef04.",
        "content/docs/data-modeling/seed-data.mdx is not edited because it is outside the surface. The PR body owes it as 'Skills-docs: follow-up owed'.",
        "STOP ON BREACH: 3 lines outside the claimed surface were left unwritten (spec registry, CLI ownership inventory, plugin-audit SKIP_OBJECTS). They are the reason for status blocked."
      ],
      "mcp_calls": "1 — mcp__claude-code-remote__add_repo for objectstack-ai/cloud, read access, refused for lack of access. 0 GitHub MCP calls, so 0 GitHub MCP writes.",
      "api_writes": "2 — both are POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay (scripts/pm/): (1) the pr_create stroke, run 42339137885 success, which opened #31083 as a draft, read back identical at 13883 bytes, no assignees, no labels; (2) this os-dev-report comment on #31021 through post-stamped.mjs. git push is not a REST write and was used several times on the branch.",
      "open_questions": [
        {
          "question": "The record of landed seed rows needs a new platform object, and a new platform object needs one line in packages/spec/src/system/constants/platform-object-names.ts, which the claim forbids. Two more lines outside the surface follow from the same object: the CLI ownership inventory row and the plugin-audit skip entry. How should the 3 lines land?",
          "options": [
            "A — Record spec consent on #31021 and correct the claim's file surface to add the 3 lines. The dev or seat adds them to #31083. This is the #30751 precedent ('Spec consent' for sys_lifecycle_state). Cost: 3 lines, one push, one CI round.",
            "B — The spec lane lands the registry line and the inventory row on its own card first; #31083 then merges main and adds the audit skip. Cost: a second card, a second PR and one extra CI round on each.",
            "C — Store the record in existing state instead. This is not recommended: no fit was measured. sys_setting refuses internal state; sys_migration, sys_lifecycle_state and sys_metadata_activation are tenant-less or per artifact; sys_recycle_bin is reaped after its retention window."
          ],
          "recommendation": "A, because the change is three mechanical lines with a landed precedent of the same shape (#30751), and the loader, runtime and object work on #31083 is complete and ablated."
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: cloud — objectstack-ai/cloud#3657 item 2. Wire the hosted 'restore sample data' or reset action to seed-replayer(orgId, { reseed: true }), and confirm that ArtifactKernelFactory's upgrade replay goes through AppPlugin's seed-replayer. That call site was NOT MEASURED here (no cloud read access). Dedupe words: restore sample data reseed, seed-replayer reseed, landed seed keys cloud.",
        "carrier: none — noted in the #31083 Acceptance notes, read-only inference, not measured. The seed doors that do not pass landedKeys still re-insert a removed seed row: runtime domains/packages.ts package install, cloud-connection install-local install and the heal that runs when every seeded object is empty, and the metadata-protocol package-publish apply. This is the same family as this card on another door. Dedupe words: install-local seed deleted row, package upgrade seed returns, heal sample data.",
        "carrier: none — noted only, a boundary not filed. skills/objectstack-data/references/seeds.md mode table says 'upsert (default)' and 'replace: Delete everything, then insert'. The default has been ignore since #30081, and replace deletes nothing. This misleads an author toward metadata the runtime honours, so it falls outside (c). Dedupe words: seeds.md mode table, replace deletes everything, upsert default skill."
      ]
    }
  6. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf
    os-dev-report

    {
      "issue": 31021,
      "status": "done",
      "branch": "claude/issue-31021-seed-landed-keys",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31083",
      "session": "session_017xRBcTJTE7kSbcMoJQ4Txf",
      "premise_still_valid": true,
      "summary": "Patch round 1, option A. New head 6a1892ec. The four edits are in one commit on top of d1abef04, and no origin/main merge was needed: main touched none of these files, only unrelated .changeset entries. (1) packages/spec/src/system/constants/platform-object-names.ts adds 'sys_seed_landed_key' to PLATFORM_OBJECTS_BY_PACKAGE['platform-objects'], sorted between sys_secret and sys_session. Nothing else under packages/spec is touched. (2) packages/cli/src/utils/organization-ownership-inventory.ts adds the ORGANIZATION_OWNERSHIP_INVENTORY row { object: 'sys_seed_landed_key', census: PMAIN, fate: 'attribution', citation: CENSUS_MAIN (in reach, added since the first census); D10_SINGLE, anchors: [] }. That is the inventory's disposition for an organization-owned, engine-written table (fate 3 attribution, as sys_recycle_bin and sys_connector_connection have). It is NOT sys_lifecycle_state's column-drop, which the inventory gives only to tenant-less tables: the loader writes every row with the organization its load seeds, so a NULL row has no producer, and a key names its seed row by natural key, so no parent anchors it. (3) plugin-audit SKIP_OBJECTS adds 'sys_seed_landed_key' beside sys_lifecycle_state, with a reason comment. (4) The changeset adds @objectstack/spec, @objectstack/cli and @objectstack/plugin-audit at minor, not patch: AGENTS.md says a kind other than none takes at least minor on every package the diff moves, and #30751's changeset did the same. A paragraph names the three effects; the Clause-② and Metadata-protocol lines are unchanged. The new PR body is at /tmp/claude-0/-home-user-objectstack/b4c2ffe8-1f36-5713-97f1-a214e3c1b75f/scratchpad/issue-31021/pr-body-r1.md. It is not sent and not PATCHed. It carries no footer block, because an edit-side body sends none; the seat adds its trailer signature line.",
      "tests": "Head 6a1892ec, each exit recorded in a file before reading. spec src/system/constants/platform-object-names.test.ts exits 0 with Tests 14 passed (14); it was 1 failed, 13 passed before. cli src/utils/organization-ownership-inventory.test.ts (--project unit) exits 0 with Tests 26 passed (26). plugin-audit src/audit-writers.test.ts, audit-log-read-visibility.test.ts and activity-read-visibility.test.ts exit 0 with Test Files 3 passed and Tests 203 passed. No plugin-audit test names SKIP_OBJECTS directly; audit-writers.test.ts pins sys_lifecycle_state's skip by name, and the two read-visibility suites read AUDIT_EXCLUDED_OBJECTS. typecheck: plugin-audit exits 0. spec and cli first exited 1 at the default heap because check:test-typecheck's tsc ran out of memory, which is not a type error; with NODE_OPTIONS=--max-old-space-size=4096 both exit 0, and check:test-typecheck reports OK for each. check:platform-object-tenancy-census exits 0: 97 objects, 50 in reach, 47 outside. The loader, runtime and platform-objects code is unchanged since d1abef04, so the earlier runs stand: metadata-protocol 22525 passed, runtime 8878 passed, platform-objects 1638 passed, and ablations A1 to A6.",
      "gates": "Re-derived at 6a1892ec with dispatch-gates --commands --repo objectstack-ai/objectstack from merge base cb8f52000: 13 paths, 98 commands, 26 of them new since d1abef04 (spec check:api-surface, check:docs, check:authorable-surface and their siblings, check:tenant-audit-census, check:i18n-coverage, check:pm-prior-rulings, and others). All 98 were run with exit codes on disk. --ran gives 98 derived, 98 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. check:dual-build-cjs-loads and check:i18n-coverage first exited 3 because the worktree had no full build; after turbo run build (119/119, VERDICT 0) both exit 0. pnpm lint exits 0 at 6a1892ec. PR check-runs at 6a1892ec, read once and not awaited: 55 success, 9 skipped, 0 failed among the runs created so far.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "line_budget": "This round adds 19 lines (+19 / -0) in 4 files. The PR is 1076 changed lines (+1062 / -14) in 13 files at 6a1892ec, against the 3000 human-merge threshold: under. No skills/** file is touched.",
      "files_changed": [
        "packages/spec/src/system/constants/platform-object-names.ts",
        "packages/cli/src/utils/organization-ownership-inventory.ts",
        "packages/plugins/plugin-audit/src/audit-writers.ts",
        ".changeset/seed-landed-keys-31021.md"
      ],
      "deviations": [
        "The changeset bumps @objectstack/spec, @objectstack/cli and @objectstack/plugin-audit at minor, not patch. AGENTS.md (Post-Task Checklist step 3) says a kind other than none takes at least minor on every package the diff moves, and the #30751 changeset bumped spec, cli and plugin-audit at minor.",
        "No sys_seed_landed_key case was added to plugin-audit's audit-writers.test.ts beside the sys_lifecycle_state one. The amended File surface names the SKIP_OBJECTS line and not that test file, so the new skip is not pinned on its own name. Adding the case is one more top-level case in that file if the seat wants it.",
        "The first spec and cli typecheck runs omitted NODE_OPTIONS and died of heap exhaustion (exit 1, no diagnostics). They were re-run at 4096 and exit 0.",
        "The PR body file carries no footer block, because an edit-side PATCH sends none (platform-readings, relay issue_patch: stored equals sent). The seat's trailer signature line goes last."
      ],
      "mcp_calls": "0 this round. Cumulative: 1, the earlier mcp__claude-code-remote__add_repo refusal. 0 GitHub MCP calls.",
      "api_writes": "1 this round: POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay, the post-stamped.mjs delta os-dev-report comment on #31021. The PR body was not PATCHed. Cumulative: 3. git push (6a1892ec) is not a REST write.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: cloud — objectstack-ai/cloud#3657 item 2, unchanged from round 0. Wire the hosted restore-sample-data or reset action to seed-replayer(orgId, { reseed: true }), and confirm that ArtifactKernelFactory's upgrade replay goes through AppPlugin's seed-replayer. NOT MEASURED here. Dedupe words: restore sample data reseed, seed-replayer reseed, landed seed keys cloud.",
        "carrier: none — noted in the #31083 Acceptance notes. The seed doors that do not pass landedKeys still re-insert a removed row: runtime domains/packages.ts install, cloud-connection install-local install and heal, and the publish apply. Dedupe words: install-local seed deleted row, package upgrade seed returns, heal sample data.",
        "carrier: none — noted only. The skills/objectstack-data/references/seeds.md mode table is stale ('upsert (default)'; 'replace' said to delete everything). Dedupe words: seeds.md mode table, replace deletes everything, upsert default skill."
      ]
    }
  7. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    ACCEPT → PR #31083 comment 6702884676 · head 6a1892ec · contract review 6702871453 (domain:spec#1, CONTRACT_REVIEW_TIER, PASS). Not governed, 1076 lines: ready + auto-merge.

  8. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 7, 2026
  9. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    Landing · PR #31083 MERGED 2026-11-07T06:02:55Z as 41238656 (Fixes #31021). Each organization now keeps a record of the seed rows that landed (sys_seed_landed_key), and AppPlugin's seed loads do not insert again a recorded row a person removed. seed-replayer(orgId, { reseed: true }) is the deliberate re-seed.

    Reading Value
    GET /pulls/31083 merged: true, merge_commit_sha 41238656d695
    GET /issues/31021 closed / completed, closed by the PR's Fixes
    Closing keywords in the PR body Fixes #31021 only; no other card closed

    State change: pm:dispatched removed (card closed). Follow-ups:

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-setpriority:p1High: required for production / M2repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions