You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Seed datasets cannot carry a file: a Field.file column needs a sys_file id only an upload can mint, so a declarative seed either drops the row, breaks the ADR-0104 attestation, or inserts a dangling token silently #25779
Filing class: ③ platform gap, filed at destination from an app ruling. Reader: domain:server / area:records seed + storage triage. Unlabelled, no assignee. Origin: objectstack-ai/hotclm#19, ruled D by the maintainer on 2026-10-25 (ruling comment objectstack-ai/hotclm#19 (comment)): "the platform's seed loader should carry bundled fixture files; the app keeps file required".
Context
hotclm's clm_contract_version.file is Field.file({ required: true, storage: { notNull: true } }) (a version without its document is not a version), and its design asks for 300 seeded versions so the demo shows a negotiation timeline with counterparty redlines. A file value is an opaque sys_file id; the bytes live in the storage backend under the row's key. A declarative seed has no upload and cannot mint one. The same wall stands in front of clm_contract_type.template_file, clm_signature.executed_file, clm_obligation.evidence, and in this repo's own showcase (#4891: an image column seeded with a data: URI blocks the ADR-0104 attestation).
Measured (17.3.0, sqlite; premise re-checked on hotclm main 2026-10-25 — field unchanged, loader unchanged)
One seed load, three version rows differing only in file:
file omitted → ERROR [SeedLoader] Failed to write clm_contract_version record #2 … File is required; the whole row is lost.
file is a URL → the row inserts, then WARN [migration] NOT attesting 'adr-0104-file-references' … Expected an opaque sys_file id.
file is an id-shaped token (probe-file-token-0001) → inserts silently, no warning, reads back verbatim, download 404s. ⚠️ This third shape is the one a seed could "get away with" and is itself a gap: nothing validates that a seeded sys_file reference exists.
Consequence in the app: zero seeded versions, version_count reads 0 on all 120 contracts, the version timeline is empty, and the ten seeded drafts cannot be submitted (the draft → submitted guard wants a version file or a type with a template, and the seed can supply neither).
The gap
packages/runtime/src/seed-loader.ts and the dataset schema in packages/spec/src/data have no notion of a file column: no way to point a seed value at bytes the package ships, and no check that a seeded sys_file id resolves.
What is asked
A seed-time file reference, shape the platform's to choose, e.g. file: seedFile('fixtures/nda-v1.pdf') (or { $file: 'fixtures/nda-v1.pdf', contentType: 'application/pdf' }) in a dataset record: the loader writes the bytes to the storage backend, mints the sys_file row with the (object, record, field) ownership the platform already enforces for uploads, and stores the id in the column; idempotent across boots (content hash or the dataset's identity key); the fixture path resolved relative to the package so both locales produce identical rows. 300 rows may reference the same bundled file (the platform copies bytes per owner today).
The loader refuses an id-shaped sys_file value that does not resolve (closes shape 3 above), or at least warns loudly, the same way the ADR-0104 migration refuses shape 2.
Cross-app pull: HotCRM attachments on accounts/opportunities, the showcase's images (#4891), hotsrm supplier documents.
Dedupe
search_issues on this repo for seed + file / sys_file / fixture documents: #22149, #19672, #4704, #15262, #9308, #9070, #4891, #3415 — seed identity, env, replay and showcase problems; 0 about seeding file columns.
Not asked
No relaxing of required on app file fields to accommodate seeds (hotclm option C, rejected by the maintainer).
No runtime upload inside the app's demo script (hotclm option B, rejected: the seed must stay declarative). hotclm#19 is Blocked-by this card and ships 0 versions until it lands.
Parked by domain:spec seat 2 at the round-1 dispatch: its fix needs the file-reference lifecycle in service-storage, which is being reworked under #25692 (PR #25951, open, accepted on the server lane). Building a seed-time file mint on the old lifecycle would collide with that rework. The card goes back to pm:queue when #25692 closes; nothing else about the card changes.
Claim: PM loop round 1 · 2026-10-26T12:10Z
Session: session_01HbmCEPMBmMLU3VZCEzfec7 (seat 4; the card thread is session_012eJQ8dtut5bZsnhFE3XGHF, which writes no claim of its own)
Account: zhuangjianguo
Branch: claude/project-thread-x6ueoz (the platform assigns the card thread's branch, and the thread can push only that branch. Written as measured, instead of claude/issue-25779-<slug>.)
Worktree: objectstack-issue-25779
Domain: domain:spec
Seat: domain:spec#4 (seat post #18917; 由 zhuangjianguo 账户的项目负责)
File surface: packages/spec/src/data/seed.zod.ts (a seed-time file reference), packages/metadata-protocol/src/seed-loader.ts (write the bytes, mint the sys_file row with (object, record, field) ownership, refuse an unresolvable id-shaped value), the storage/file-service call it needs, liveness rows and generated references, tests, and one changeset. The card names packages/runtime/src/seed-loader.ts, but at main0a694821 the loader that writes rows is the metadata-protocol one; the thread measures which is the producer. If measurement puts the producer elsewhere, fix it there and say so. Stop on a breach and explain it in the report.
Container & model: M/L, mode:thread, model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate, effort: xhigh (p1)
Clause-②: yes
Metadata-protocol: added
Responsibility: n/a — not a defect card (a capability gap filed from a maintainer ruling)
Thread-read: 6411019871
Premise: holds (the landing point is packages/spec/src/data/seed.zod.ts + packages/metadata-protocol/src/seed-loader.ts, not packages/runtime/src/seed-loader.ts. The gap holds: at main0a694821, neither file has a notion of a file column (0 hits for sys_file/fixture-file; control word record: 41 and 333). The blocker #25692 is closed (PR #25951 merged 06:40Z).)
Ruling-ref: hotclm#19 ruled D by the maintainer (2026-10-25, comment 6396327991, quoted in the card body)
Serial constraints cleared: #25813 (493a6c4a) touched seed.zod.ts today; sibling #25801 (seat 4) shares the service-storage claim lifecycle — the first PR to open owns a shared file, the other merges main after it lands.
Resume-from: none
{
"issue": 25779,
"status": "done",
"branch": "claude/project-thread-x6ueoz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26244",
"head": "2d0dd7dd1ad15f6cc68f7d5b02a7441598b0f040",
"session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)",
"premise_still_valid": true,
"summary": "A seed record now fills a file-class field with a file the package ships: `seedFile(path)` writes `{ $file: path }`. `os build` reads the file relative to the config's directory and embeds its bytes, size and SHA-256 in the dataset's new `files` map. `os validate` refuses the same paths, and `os serve` on a config mirrors the collection. The metadata-protocol seed loader stores the bytes through a new `field-files` service registered by service-storage, as a pending sys_file in the row's organization. It writes the id into the field and claims (object, record, field) ownership once the row lands. Each row gets its own file, a replay keeps an unchanged file, and a refused row stores nothing. Shape 3 is refused by row: an id-shaped value in a file field that names no stored file in the row's organization. An inline seed carrying seed files defers to kernel:bootstrapped, so the files land in the store the deployment serves from.",
"tests": "New: spec seed-file.zod.test.ts and storage-service.test.ts (51 with the alias pin); service-storage field-file-service.test.ts (9, real ObjectQL on sqlite); metadata-protocol seed-loader-seed-files.test.ts (16); cli bundle-seed-files.test.ts plus the two ledgers (46); and two nightly-tier e2e suites (3 tests). One suite is os build plus loadArtifactBundle, where os build and os validate both refuse a missing path. The other is os serve --dev on a config with a required file field: each seeded row holds its own file, and GET /storage/files/ID answers the fixture's bytes. Its negative control, with the serve.ts mirror removed, seeded 0 rows; with the mirror, 2. All of these ran on the final code. Full suites: metadata-protocol 21554 passed / 19 skipped; service-storage 1206 passed; runtime 457 files, 8352 passed / 19 skipped; all on the final code. cli: 506 files, 0 failed tests. 491 files ran on a7fc798d; the commits after it touch no CLI file and change only types; the 15 that need a built CLI ran on b8fe94f8.",
"gates": "dispatch-gates --commands derived 140 commands on b8fe94f8, each exit code captured before any pipe. 139 exit 0. `pnpm check:dual-build-cjs-loads` exits 3 (PREREQUISITE NOT MET: a full workspace build), declared to CI. `dispatch-gates --ran` reports 140 derived, 139 run, 1 NOT-MEASURED, 0 UNRUN. Head 2d0dd7dd changes only the changeset's two declaration lines. On it, these exit 0: check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check-empty-changeset --base origin/main, check:changeset-gate-self-tests. The PR-body readers also exit 0, run against the body as sent through a local GITHUB_EVENT_PATH: the level axis declares `yes` / `added`, the ADR-0087 marker is found, and check-closing-keyword-parity passes. CI check-runs on PR #26244: in_progress at report time. Reviewer requests: the pr_create run row lists none. The PR is Tier H, so GOVERNED_APPROVERS still need requesting by the seat.",
"dogfood_battery": "b8fe94f8 · os-verify-lock command-exit 0 · Test Files 296 passed / 3 skipped (299) · Tests 2523 passed / 18 skipped (2541) · no failures. Title carries `!`. Head 2d0dd7dd differs only in the changeset text.",
"line_budget": "54 files, +3356 / -35 against main. By kind: source 18 files +1576/-17; tests 10 files +1430/-4; generated and ledgers 23 files +266/-13; docs and changeset 3 files +84/-1. Over 3000 lines with generated files, so the PR body carries the 维护者速读 draft.",
"files_changed": "spec: data/seed-file.zod.ts (new), data/seed.zod.ts, data/index.ts, contracts/storage-service.ts, type-alias-convention.pin.test.ts (790), llms.txt and the regenerated surfaces. service-storage: field-file-service.ts (new), storage-service-plugin.ts, file-reference-lifecycle.ts (only `export` added to releaseOwnership and ownedBySlot). metadata-protocol: seed-files.ts (new), seed-loader.ts, protocol.ts, protocol-publish-batch.ts, index.ts. runtime: app-plugin.ts, domains/packages.ts. cli: utils/bundle-seed-files.ts (new), commands/compile.ts, validate.ts, serve.ts, two ledger tests, two e2e suites. Docs: data-modeling/seed-data.mdx, quick-reference.mdx, references/data/seed-file.mdx (generated). Ledgers: strictness-ledger row, dropped-refinements baseline, liveness seed, engine-double-contract pin. skills/objectstack-data/references/_index.md: one generated line. Changeset: .changeset/25779-seed-files.md.",
"deviations": [
"Declaration lines: the PR body and the changeset carry the Claim's `Clause-②: yes` / `Metadata-protocol: added` verbatim. Measured, the change narrows: shape 3 refuses a seed value that used to be written. By the pr-automation.yml rule (name the kind highest in breaking-ness), the lines should read `Clause-②: yes (narrowing)` / `Metadata-protocol: narrowed`. Both grade minor. The changeset carries the BREAKING banner, the ADR-0087 not-required marker and a What-to-do line either way. To correct: amend the Claim, then edit both lines in the PR body and in .changeset/25779-seed-files.md. The PR body notes this under Acceptance notes.",
"File surface beyond the Claim, each needed for acceptance: `os validate` (it runs the same seed-file gate), the `os serve` config-boot mirror (without it a config boot refused every seeded row), the CLI gate-parity and call-site ledgers, the runtime callers that pass the field-files service, and the contract in spec contracts/storage-service.ts.",
"Gate-driven additions: a hand-written strictness-ledger row for seed-file.zod.ts, ADR-0122 Parsed aliases plus a SeedFilePath type with its isomorphic pin (789 to 790), and the engine-double-contract pin refreshed with --write.",
"Dogfood and the full sweep ran on b8fe94f8. The final head 2d0dd7dd changes only the changeset's two declaration lines, and the four changeset gates were rerun on it.",
"The full CLI suite ran locally, both tiers, because the diff changes serve.ts, compile.ts and validate.ts, which the integration tier spawns."
],
"contract_review": "CONTRACT_REVIEW_TIER review owed before queueing. The PR is Tier H (one generated line under skills/**, and over 3000 lines with generated files).",
"serial_constraint": "#25801's PR #26134 opened first; the two diffs share no file. This PR adds only the `export` keyword to two functions in service-storage file-reference-lifecycle.ts, which #26134 does not touch.",
"mcp_calls": "3 — all reads: search_pull_requests, list_pull_requests, pull_request_read (get_files), used to check #26134's overlap. No write tool.",
"api_writes": "2 relay writes, 3 REST requests, all through scripts/pm: (1) fleet-write pr_create run 40361316337, which sent POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/26244/assignees (zhuangjianguo), read back byte-identical at 15130 bytes; (2) this report, POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped. git push is not counted: 2 pushes to claude/project-thread-x6ueoz, b8fe94f8 and 2d0dd7dd. No labels written; the card names none, and the PR carries a changeset.",
"open_questions": [],
"out_of_scope_findings": []
}
The diff both widens and narrows the accept set. It widens because seedFile(path), which writes { $file: path }, is a new value a seed can write. It narrows under shape 3: a seed value in a file field that looks like an id but names no stored file in the row's organization used to be written, and that row is now refused. When a diff has several kinds, narrowed wins over added (AGENTS.md Post-Task Checklist step 3). The level stays minor.
Route: the PR is Tier H. It touches skills/**, a governed generated line that the #11705 exception did not lift, and it changes more than 3,000 lines. A CONTRACT_REVIEW_TIER review is owed. After that the PR waits for a GOVERNED_APPROVERS approval, carrying needs-user-decision.
{
"issue": 25779,
"status": "done",
"branch": "claude/project-thread-x6ueoz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26244",
"head": "c33b95d89fa4a66dd871a0ab617f49bf870421e9",
"session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)",
"premise_still_valid": true,
"summary": "Follow-up to the first report, after the Claim amendment (comment 6421695515) and CI. (1) `.changeset/25779-seed-files.md` now reads `Clause-②: yes (narrowing)` / `Metadata-protocol: narrowed` (6c5c49cc). It still grades minor and keeps the BREAKING banner and the ADR-0087 not-required marker. The PR body still reads `yes` / `added`; it was not touched, as ordered. (2) Spec property liveness was red at 2d0dd7dd because main had added schemas the strictness count did not include. Fixed by merging origin/main (9c6345d1, the os-regen driver: spec build, gen:schema, gen:export-origins, gen:api-surface, gen:strictness-ledger, check:generated, check-regen-pending). (3) CI then found three more reds, fixed in 976a6ee6 and c33b95d8. The dropped-refinements baseline header was set to the entry totals (247 schemas, 866 sites). A test record's `code: 'a'` field, which the error-code casing guard read as an error code, is now `name: 'a'`. The liveness evidence anchor now names `placeSeedFiles`, and the level-1 module-description pin moves from 30 to 31 for the new `data/seed-file.zod.ts`. No source behaviour changed after 6c5c49cc.",
"tests": "On c33b95d8, locally: spec `test`, 726 files, 21995 tests passed; spec `test:repo`, 79 files, 1279 tests passed; CLI unit tier, 334 files, 4882 tests passed. Earlier, on the merged tree: service-storage 1227 passed; metadata-protocol 21555 passed; runtime on 6c5c49cc, 459 files, 8359 passed; the nightly e2e pair, 3 tests passed.",
"gates": "dispatch-gates --commands on c33b95d8 derives 140 commands. 139 exit 0. check:dual-build-cjs-loads exits 3 (it needs a full workspace build) and is left to CI. --ran reconciles 140 derived, 139 run, 1 NOT-MEASURED, 0 UNRUN. With the amended lines, check-adr-0087-registration and check-changeset-no-major (both --base origin/main) exit 0. CI check-runs on c33b95d8: 48 in total. Green or skipped: Test Core and all 8 shards, Spec property liveness, Lint · docs & code guards, Lint & Repo Gates, Check Changeset, Governed Surface Queue Guard, Build Core, Build & E2E UI, Type Check UI, Type Check · consumer gates / source gates / debt ledger, and every other Lint lane. Red: Type Check · workspace (job 121738515222) and TypeScript Type Check (job 121747810706, the 3-second roll-up that is red because the first is). Both are a tsc heap OOM (exit 134) in packages/plugins/plugin-hono-server, with no type error. The same lane passed on 6c5c49cc, and nothing after 6c5c49cc changes a type. See out_of_scope_findings.",
"dogfood_battery": "c33b95d8 · os-verify-lock VERDICT command-exit 0 (held 19m40s) · Test Files 297 passed / 3 skipped (300) · Tests 2527 passed / 18 skipped (2545) · no failures",
"mcp_calls": "18, all reads: search_pull_requests, list_pull_requests, pull_request_read ×4 (get_files, get_check_runs ×2, get_reviews), get_job_logs ×6, actions_get ×1, actions_list ×3, search_issues ×1. No write tool.",
"api_writes": "3 relay writes in total: (1) pr_create of #26244; (2) the first report on #25779; (3) this report, POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped. git push is not counted: since the first report, 2 pushes to claude/project-thread-x6ueoz, 6c5c49cc and c33b95d8. No labels written.",
"open_questions": [
{
"question": "If a single re-run of the failed Type Check jobs OOMs again, should this PR carry the one-line plugin-hono-server tsconfig patch?",
"options": [
"A: the seat re-runs the failed jobs once (run_rerun_failed on run 40370187707); file the margin as its own card either way",
"B: add `\"skipLibCheck\": true` to packages/plugins/plugin-hono-server/tsconfig.json in this PR",
"C: raise the Type Check · workspace heap limit in CI, as a separate card"
],
"recommendation": "A. The lane passed on 6c5c49cc with the same types, so a re-run is likely green. B widens this PR past the card. If the re-run fails too, B as its own small PR clears it for every spec-touching PR."
}
],
"out_of_scope_findings": [
"class: a · reach: CI's Type Check · workspace lane, the typecheck of any PR that touches packages/spec (it pulls plugin-hono-server into the affected set), refuses with a heap OOM, not a type error · evidence: plugin-hono-server's tsconfig extends nothing and sets no skipLibCheck, so tsc type-checks spec's dist .d.ts. Measured locally under NODE_OPTIONS=--max-old-space-size=4136 (CI's limit): main peaks at 4,745,939 KB RSS and this branch at 4,770,597 KB. Both pass at 4136 MB, the branch fails at 3900 MB, and check time is 67.6s. With skipLibCheck the program peaks at 872,405 KB, the check takes 3.85s and there are no errors. CI OOMed at 2d0dd7dd and c33b95d8 and passed at 6c5c49cc with identical types, and #25657 measured main at 4,167,189 KB on Oct 24, so the margin is shared with main and shrinking · dedupe words: plugin-hono-server typecheck heap OOM, skipLibCheck, Type Check workspace exit 134, max-old-space-size 4136",
"carrier: none · noted, not filed"
]
}
ACCEPT → PR #26244 comment 6425084895 (seat domain:spec#4, 2026-10-26T19:14Z). Contract review 6425043305 PASS. Tier H: os-zhuang APPROVED on 6c5c49cc; landing waits on a re-run of the OOM type-check lane (#26288).
{
"issue": 25779,
"status": "done",
"branch": "claude/project-thread-x6ueoz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26244",
"head": "8f07f5cb1cd03b0fc37c03c192fb7b081a38f3ab",
"session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)",
"premise_still_valid": true,
"summary": "Head 8f07f5cb merges origin/main, including #26356 (the plugin-hono-server skipLibCheck fix for #26288). CI on 8f07f5cb: 48 check-runs, 41 success, 7 skipped (opt-in and UI-matrix lanes), 0 failure. `Type Check · workspace` is green, and so is its roll-up `TypeScript Type Check`. The merge had two conflicts, both resolved by keeping both sides. (1) The metadata-protocol `protocol.ts` imports: main dropped the unused `ALL_CONVERSIONS` import, and this branch keeps its `IFieldFileService` and `FIELD_FILE_SERVICE` imports. (2) The ADR-0122 isomorphic pin count: main's `NowAnchorSchema` pin took 789 -> 790, so `SeedFilePathSchema` is now 790 -> 791 in the assertion, the title and the header. The deferred spec artifacts were regenerated from the merged tree; check:generated and check-regen-pending exit 0. No source behaviour changed.",
"tests": "On the merged tree, before the push: the dogfood closure build; typecheck exit 0 for spec, metadata-protocol, service-storage, runtime and cli; plugin-hono-server typecheck exit 0 under NODE_OPTIONS=--max-old-space-size=4136; spec `test`, 727 files, 22009 passed; spec `test:repo`, 79 files, 1279 passed; metadata-protocol seed suites, 320 passed / 14 skipped. On 8f07f5cb: metadata-protocol full, 21565 passed / 19 skipped; service-storage full, 1245 passed; CLI unit tier, 336 files, 4898 passed; runtime full, 460 files, 8369 passed / 19 skipped.",
"gates": "CI check-runs on 8f07f5cb cited above. The derived dispatch-gates sweep was not re-run for this merge: the PR's own diff is unchanged apart from the pin count, and every CI Lint and Type Check lane is green on this head.",
"dogfood_battery": "8f07f5cb · os-verify-lock VERDICT command-exit 0 (held 16m26s) · Test Files 298 passed / 3 skipped (301) · Tests 2530 passed / 18 skipped (2548) · no failures",
"mcp_calls": "22 in total, all reads. Since the last report: issue_read ×3 (get ×2, get_comments ×1), pull_request_read get_check_runs ×1. No write tool.",
"api_writes": "4 relay writes in total; this report is the 4th (POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped). git push is not counted: 1 push since the last report, 8f07f5cb.",
"open_questions": [],
"out_of_scope_findings": []
}
Activity
objectstack-fleet commentedon Oct 25, 2026
Triage: first grade —
enhancement·priority:p1·domain:spec·area:files·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T11:56Z⛔ Not a claim, ⛔ not a dispatch.
filerequired and a seed cannot mint one hotclm#19 (D): the seed loader carries bundled fixture files, and the app keepsfilerequired.sys_filerows under ADR-0104's one-file, one-owner rule. Read beside files: an authorization gap in the file-reference lifecycle, within one organization (detail withheld) #25692 (file-reference lifecycle).Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Blocked-by: #25692
Parked by domain:spec seat 2 at the round-1 dispatch: its fix needs the file-reference lifecycle in service-storage, which is being reworked under #25692 (PR #25951, open, accepted on the server lane). Building a seed-time file mint on the old lifecycle would collide with that rework. The card goes back to
pm:queuewhen #25692 closes; nothing else about the card changes.objectstack-fleet commentedon Oct 26, 2026
Unlock scan: unlocked →
pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-26T07:55Z⛔ Not a claim, ⛔ not a dispatch.
completed, with its fix PR fix(storage)!: a record write claims or copies only a file its caller may read #25951 merged at 06:40Z (3761710927). The 07:04Z parking comment read the PR as still open. The seed-time file mint builds on the reworked file-reference lifecycle now onmain. Grade unchanged (p1 ·domain:spec).Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 1 · 2026-10-26T12:10Z
Session:
session_01HbmCEPMBmMLU3VZCEzfec7(seat 4; the card thread issession_012eJQ8dtut5bZsnhFE3XGHF, which writes no claim of its own)Account:
zhuangjianguoBranch:
claude/project-thread-x6ueoz(the platform assigns the card thread's branch, and the thread can push only that branch. Written as measured, instead ofclaude/issue-25779-<slug>.)Worktree:
objectstack-issue-25779Domain:
domain:specSeat:
domain:spec#4(seat post #18917; 由 zhuangjianguo 账户的项目负责)File surface:
packages/spec/src/data/seed.zod.ts(a seed-time file reference),packages/metadata-protocol/src/seed-loader.ts(write the bytes, mint thesys_filerow with (object, record, field) ownership, refuse an unresolvable id-shaped value), the storage/file-service call it needs, liveness rows and generated references, tests, and one changeset. The card namespackages/runtime/src/seed-loader.ts, but atmain0a694821the loader that writes rows is the metadata-protocol one; the thread measures which is the producer. If measurement puts the producer elsewhere, fix it there and say so. Stop on a breach and explain it in the report.Container & model:
M/L,mode:thread,model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate,effort: xhigh (p1)Clause-②: yes
Metadata-protocol: added
Responsibility: n/a — not a defect card (a capability gap filed from a maintainer ruling)
Thread-read: 6411019871
Premise: holds (the landing point is
packages/spec/src/data/seed.zod.ts+packages/metadata-protocol/src/seed-loader.ts, notpackages/runtime/src/seed-loader.ts. The gap holds: atmain0a694821, neither file has a notion of a file column (0 hits forsys_file/fixture-file; control wordrecord: 41 and 333). The blocker #25692 is closed (PR #25951 merged 06:40Z).)Ruling-ref: hotclm#19 ruled D by the maintainer (2026-10-25, comment 6396327991, quoted in the card body)
Serial constraints cleared:
#25813 (493a6c4a) touched seed.zod.ts today; sibling #25801 (seat 4) shares the service-storage claim lifecycle — the first PR to open owns a shared file, the other merges main after it lands.Resume-from: none
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25779, "status": "done", "branch": "claude/project-thread-x6ueoz", "pr": "https://github.com/objectstack-ai/objectstack/pull/26244", "head": "2d0dd7dd1ad15f6cc68f7d5b02a7441598b0f040", "session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)", "premise_still_valid": true, "summary": "A seed record now fills a file-class field with a file the package ships: `seedFile(path)` writes `{ $file: path }`. `os build` reads the file relative to the config's directory and embeds its bytes, size and SHA-256 in the dataset's new `files` map. `os validate` refuses the same paths, and `os serve` on a config mirrors the collection. The metadata-protocol seed loader stores the bytes through a new `field-files` service registered by service-storage, as a pending sys_file in the row's organization. It writes the id into the field and claims (object, record, field) ownership once the row lands. Each row gets its own file, a replay keeps an unchanged file, and a refused row stores nothing. Shape 3 is refused by row: an id-shaped value in a file field that names no stored file in the row's organization. An inline seed carrying seed files defers to kernel:bootstrapped, so the files land in the store the deployment serves from.", "tests": "New: spec seed-file.zod.test.ts and storage-service.test.ts (51 with the alias pin); service-storage field-file-service.test.ts (9, real ObjectQL on sqlite); metadata-protocol seed-loader-seed-files.test.ts (16); cli bundle-seed-files.test.ts plus the two ledgers (46); and two nightly-tier e2e suites (3 tests). One suite is os build plus loadArtifactBundle, where os build and os validate both refuse a missing path. The other is os serve --dev on a config with a required file field: each seeded row holds its own file, and GET /storage/files/ID answers the fixture's bytes. Its negative control, with the serve.ts mirror removed, seeded 0 rows; with the mirror, 2. All of these ran on the final code. Full suites: metadata-protocol 21554 passed / 19 skipped; service-storage 1206 passed; runtime 457 files, 8352 passed / 19 skipped; all on the final code. cli: 506 files, 0 failed tests. 491 files ran on a7fc798d; the commits after it touch no CLI file and change only types; the 15 that need a built CLI ran on b8fe94f8.", "gates": "dispatch-gates --commands derived 140 commands on b8fe94f8, each exit code captured before any pipe. 139 exit 0. `pnpm check:dual-build-cjs-loads` exits 3 (PREREQUISITE NOT MET: a full workspace build), declared to CI. `dispatch-gates --ran` reports 140 derived, 139 run, 1 NOT-MEASURED, 0 UNRUN. Head 2d0dd7dd changes only the changeset's two declaration lines. On it, these exit 0: check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check-empty-changeset --base origin/main, check:changeset-gate-self-tests. The PR-body readers also exit 0, run against the body as sent through a local GITHUB_EVENT_PATH: the level axis declares `yes` / `added`, the ADR-0087 marker is found, and check-closing-keyword-parity passes. CI check-runs on PR #26244: in_progress at report time. Reviewer requests: the pr_create run row lists none. The PR is Tier H, so GOVERNED_APPROVERS still need requesting by the seat.", "dogfood_battery": "b8fe94f8 · os-verify-lock command-exit 0 · Test Files 296 passed / 3 skipped (299) · Tests 2523 passed / 18 skipped (2541) · no failures. Title carries `!`. Head 2d0dd7dd differs only in the changeset text.", "line_budget": "54 files, +3356 / -35 against main. By kind: source 18 files +1576/-17; tests 10 files +1430/-4; generated and ledgers 23 files +266/-13; docs and changeset 3 files +84/-1. Over 3000 lines with generated files, so the PR body carries the 维护者速读 draft.", "files_changed": "spec: data/seed-file.zod.ts (new), data/seed.zod.ts, data/index.ts, contracts/storage-service.ts, type-alias-convention.pin.test.ts (790), llms.txt and the regenerated surfaces. service-storage: field-file-service.ts (new), storage-service-plugin.ts, file-reference-lifecycle.ts (only `export` added to releaseOwnership and ownedBySlot). metadata-protocol: seed-files.ts (new), seed-loader.ts, protocol.ts, protocol-publish-batch.ts, index.ts. runtime: app-plugin.ts, domains/packages.ts. cli: utils/bundle-seed-files.ts (new), commands/compile.ts, validate.ts, serve.ts, two ledger tests, two e2e suites. Docs: data-modeling/seed-data.mdx, quick-reference.mdx, references/data/seed-file.mdx (generated). Ledgers: strictness-ledger row, dropped-refinements baseline, liveness seed, engine-double-contract pin. skills/objectstack-data/references/_index.md: one generated line. Changeset: .changeset/25779-seed-files.md.", "deviations": [ "Declaration lines: the PR body and the changeset carry the Claim's `Clause-②: yes` / `Metadata-protocol: added` verbatim. Measured, the change narrows: shape 3 refuses a seed value that used to be written. By the pr-automation.yml rule (name the kind highest in breaking-ness), the lines should read `Clause-②: yes (narrowing)` / `Metadata-protocol: narrowed`. Both grade minor. The changeset carries the BREAKING banner, the ADR-0087 not-required marker and a What-to-do line either way. To correct: amend the Claim, then edit both lines in the PR body and in .changeset/25779-seed-files.md. The PR body notes this under Acceptance notes.", "File surface beyond the Claim, each needed for acceptance: `os validate` (it runs the same seed-file gate), the `os serve` config-boot mirror (without it a config boot refused every seeded row), the CLI gate-parity and call-site ledgers, the runtime callers that pass the field-files service, and the contract in spec contracts/storage-service.ts.", "Gate-driven additions: a hand-written strictness-ledger row for seed-file.zod.ts, ADR-0122 Parsed aliases plus a SeedFilePath type with its isomorphic pin (789 to 790), and the engine-double-contract pin refreshed with --write.", "Dogfood and the full sweep ran on b8fe94f8. The final head 2d0dd7dd changes only the changeset's two declaration lines, and the four changeset gates were rerun on it.", "The full CLI suite ran locally, both tiers, because the diff changes serve.ts, compile.ts and validate.ts, which the integration tier spawns." ], "contract_review": "CONTRACT_REVIEW_TIER review owed before queueing. The PR is Tier H (one generated line under skills/**, and over 3000 lines with generated files).", "serial_constraint": "#25801's PR #26134 opened first; the two diffs share no file. This PR adds only the `export` keyword to two functions in service-storage file-reference-lifecycle.ts, which #26134 does not touch.", "mcp_calls": "3 — all reads: search_pull_requests, list_pull_requests, pull_request_read (get_files), used to check #26134's overlap. No write tool.", "api_writes": "2 relay writes, 3 REST requests, all through scripts/pm: (1) fleet-write pr_create run 40361316337, which sent POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/26244/assignees (zhuangjianguo), read back byte-identical at 15130 bytes; (2) this report, POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped. git push is not counted: 2 pushes to claude/project-thread-x6ueoz, b8fe94f8 and 2d0dd7dd. No labels written; the card names none, and the PR carries a changeset.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Claim amendment — PM loop round 1, seat
domain:spec#4, sessionsession_01HbmCEPMBmMLU3VZCEzfec7, 2026-10-26T16:43Z.The dev measured PR #26244 against this seat's claim 6415670720, and the seat takes the correction:
Clause-②: yes (narrowing)
Metadata-protocol: narrowed
The diff both widens and narrows the accept set. It widens because
seedFile(path), which writes{ $file: path }, is a new value a seed can write. It narrows under shape 3: a seed value in a file field that looks like an id but names no stored file in the row's organization used to be written, and that row is now refused. When a diff has several kinds,narrowedwins overadded(AGENTS.md Post-Task Checklist step 3). The level staysminor.Route: the PR is Tier H. It touches
skills/**, a governed generated line that the #11705 exception did not lift, and it changes more than 3,000 lines. ACONTRACT_REVIEW_TIERreview is owed. After that the PR waits for a GOVERNED_APPROVERS approval, carryingneeds-user-decision.objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25779, "status": "done", "branch": "claude/project-thread-x6ueoz", "pr": "https://github.com/objectstack-ai/objectstack/pull/26244", "head": "c33b95d89fa4a66dd871a0ab617f49bf870421e9", "session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)", "premise_still_valid": true, "summary": "Follow-up to the first report, after the Claim amendment (comment 6421695515) and CI. (1) `.changeset/25779-seed-files.md` now reads `Clause-②: yes (narrowing)` / `Metadata-protocol: narrowed` (6c5c49cc). It still grades minor and keeps the BREAKING banner and the ADR-0087 not-required marker. The PR body still reads `yes` / `added`; it was not touched, as ordered. (2) Spec property liveness was red at 2d0dd7dd because main had added schemas the strictness count did not include. Fixed by merging origin/main (9c6345d1, the os-regen driver: spec build, gen:schema, gen:export-origins, gen:api-surface, gen:strictness-ledger, check:generated, check-regen-pending). (3) CI then found three more reds, fixed in 976a6ee6 and c33b95d8. The dropped-refinements baseline header was set to the entry totals (247 schemas, 866 sites). A test record's `code: 'a'` field, which the error-code casing guard read as an error code, is now `name: 'a'`. The liveness evidence anchor now names `placeSeedFiles`, and the level-1 module-description pin moves from 30 to 31 for the new `data/seed-file.zod.ts`. No source behaviour changed after 6c5c49cc.", "tests": "On c33b95d8, locally: spec `test`, 726 files, 21995 tests passed; spec `test:repo`, 79 files, 1279 tests passed; CLI unit tier, 334 files, 4882 tests passed. Earlier, on the merged tree: service-storage 1227 passed; metadata-protocol 21555 passed; runtime on 6c5c49cc, 459 files, 8359 passed; the nightly e2e pair, 3 tests passed.", "gates": "dispatch-gates --commands on c33b95d8 derives 140 commands. 139 exit 0. check:dual-build-cjs-loads exits 3 (it needs a full workspace build) and is left to CI. --ran reconciles 140 derived, 139 run, 1 NOT-MEASURED, 0 UNRUN. With the amended lines, check-adr-0087-registration and check-changeset-no-major (both --base origin/main) exit 0. CI check-runs on c33b95d8: 48 in total. Green or skipped: Test Core and all 8 shards, Spec property liveness, Lint · docs & code guards, Lint & Repo Gates, Check Changeset, Governed Surface Queue Guard, Build Core, Build & E2E UI, Type Check UI, Type Check · consumer gates / source gates / debt ledger, and every other Lint lane. Red: Type Check · workspace (job 121738515222) and TypeScript Type Check (job 121747810706, the 3-second roll-up that is red because the first is). Both are a tsc heap OOM (exit 134) in packages/plugins/plugin-hono-server, with no type error. The same lane passed on 6c5c49cc, and nothing after 6c5c49cc changes a type. See out_of_scope_findings.", "dogfood_battery": "c33b95d8 · os-verify-lock VERDICT command-exit 0 (held 19m40s) · Test Files 297 passed / 3 skipped (300) · Tests 2527 passed / 18 skipped (2545) · no failures", "mcp_calls": "18, all reads: search_pull_requests, list_pull_requests, pull_request_read ×4 (get_files, get_check_runs ×2, get_reviews), get_job_logs ×6, actions_get ×1, actions_list ×3, search_issues ×1. No write tool.", "api_writes": "3 relay writes in total: (1) pr_create of #26244; (2) the first report on #25779; (3) this report, POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped. git push is not counted: since the first report, 2 pushes to claude/project-thread-x6ueoz, 6c5c49cc and c33b95d8. No labels written.", "open_questions": [ { "question": "If a single re-run of the failed Type Check jobs OOMs again, should this PR carry the one-line plugin-hono-server tsconfig patch?", "options": [ "A: the seat re-runs the failed jobs once (run_rerun_failed on run 40370187707); file the margin as its own card either way", "B: add `\"skipLibCheck\": true` to packages/plugins/plugin-hono-server/tsconfig.json in this PR", "C: raise the Type Check · workspace heap limit in CI, as a separate card" ], "recommendation": "A. The lane passed on 6c5c49cc with the same types, so a re-run is likely green. B widens this PR past the card. If the re-run fails too, B as its own small PR clears it for every spec-touching PR." } ], "out_of_scope_findings": [ "class: a · reach: CI's Type Check · workspace lane, the typecheck of any PR that touches packages/spec (it pulls plugin-hono-server into the affected set), refuses with a heap OOM, not a type error · evidence: plugin-hono-server's tsconfig extends nothing and sets no skipLibCheck, so tsc type-checks spec's dist .d.ts. Measured locally under NODE_OPTIONS=--max-old-space-size=4136 (CI's limit): main peaks at 4,745,939 KB RSS and this branch at 4,770,597 KB. Both pass at 4136 MB, the branch fails at 3900 MB, and check time is 67.6s. With skipLibCheck the program peaks at 872,405 KB, the check takes 3.85s and there are no errors. CI OOMed at 2d0dd7dd and c33b95d8 and passed at 6c5c49cc with identical types, and #25657 measured main at 4,167,189 KB on Oct 24, so the margin is shared with main and shrinking · dedupe words: plugin-hono-server typecheck heap OOM, skipLibCheck, Type Check workspace exit 134, max-old-space-size 4136", "carrier: none · noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
ACCEPT → PR #26244 comment 6425084895 (seat
domain:spec#4, 2026-10-26T19:14Z). Contract review 6425043305 PASS. Tier H: os-zhuang APPROVED on6c5c49cc; landing waits on a re-run of the OOM type-check lane (#26288).objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 25779, "status": "done", "branch": "claude/project-thread-x6ueoz", "pr": "https://github.com/objectstack-ai/objectstack/pull/26244", "head": "8f07f5cb1cd03b0fc37c03c192fb7b081a38f3ab", "session": "session_012eJQ8dtut5bZsnhFE3XGHF (the card thread; the Claim is seat 4's, session_01HbmCEPMBmMLU3VZCEzfec7)", "premise_still_valid": true, "summary": "Head 8f07f5cb merges origin/main, including #26356 (the plugin-hono-server skipLibCheck fix for #26288). CI on 8f07f5cb: 48 check-runs, 41 success, 7 skipped (opt-in and UI-matrix lanes), 0 failure. `Type Check · workspace` is green, and so is its roll-up `TypeScript Type Check`. The merge had two conflicts, both resolved by keeping both sides. (1) The metadata-protocol `protocol.ts` imports: main dropped the unused `ALL_CONVERSIONS` import, and this branch keeps its `IFieldFileService` and `FIELD_FILE_SERVICE` imports. (2) The ADR-0122 isomorphic pin count: main's `NowAnchorSchema` pin took 789 -> 790, so `SeedFilePathSchema` is now 790 -> 791 in the assertion, the title and the header. The deferred spec artifacts were regenerated from the merged tree; check:generated and check-regen-pending exit 0. No source behaviour changed.", "tests": "On the merged tree, before the push: the dogfood closure build; typecheck exit 0 for spec, metadata-protocol, service-storage, runtime and cli; plugin-hono-server typecheck exit 0 under NODE_OPTIONS=--max-old-space-size=4136; spec `test`, 727 files, 22009 passed; spec `test:repo`, 79 files, 1279 passed; metadata-protocol seed suites, 320 passed / 14 skipped. On 8f07f5cb: metadata-protocol full, 21565 passed / 19 skipped; service-storage full, 1245 passed; CLI unit tier, 336 files, 4898 passed; runtime full, 460 files, 8369 passed / 19 skipped.", "gates": "CI check-runs on 8f07f5cb cited above. The derived dispatch-gates sweep was not re-run for this merge: the PR's own diff is unchanged apart from the pin count, and every CI Lint and Type Check lane is green on this head.", "dogfood_battery": "8f07f5cb · os-verify-lock VERDICT command-exit 0 (held 16m26s) · Test Files 298 passed / 3 skipped (301) · Tests 2530 passed / 18 skipped (2548) · no failures", "mcp_calls": "22 in total, all reads. Since the last report: issue_read ×3 (get ×2, get_comments ×1), pull_request_read get_check_runs ×1. No write tool.", "api_writes": "4 relay writes in total; this report is the 4th (POST /repos/objectstack-ai/objectstack/issues/25779/comments via post-stamped). git push is not counted: 1 push since the last report, 8f07f5cb.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Landing — seat
domain:spec#4, sessionsession_01HbmCEPMBmMLU3VZCEzfec7, 2026-10-27T01:44Z.8f07f5cborigin/main2163e806 feat(spec,metadata-protocol,service-storage,runtime,cli)!: a seed record can carry a file the package ships, seedFile(path) (#26244)The card was closed
completedbyFixes. The seat removespm:dispatchedin this stroke.