Repository navigation
Description
Split out of #9308, which scoped four stock seed fixtures for examples/app-showcase/**. Three landed. This one did not, because measurement showed it is not seed data and cannot be made into seed data, so guessing at it inside that card would have smuggled a design decision into a fixture PR.
What is blocked
automation.rollup-summary-filter (P2), acceptance clause 5:
"the child-row filter is settable via the visual editor on a writable package" (oracle:
screenshot)
blocked.by: fixture, ref: #3358 (editor half needs a writable-package summary field fixture). The item's other four clauses — the recompute half — are runnable on stock today and unaffected. The item's knownGaps and blocked block are deliberately left untouched by #9308.
Why it is not a seed addition — measured, not assumed
-
A writable package is a DB-backed package, and the showcase is definitionally not one.
isWritablePackage(packages/metadata-protocol/src/package-writability.ts) returnsfalsefor a booted code package — one that registered a manifest into the engine at startup — and the showcase is exactly that. There is no flag, noallowOrgOverrideroute around it: the registry declaresobjectasallowOrgOverride: false, allowRuntimeCreate: true(packages/spec/src/kernel/metadata-plugin.zod.ts), so a showcase object cannot be edited by overlay, and a runtime-created one needs a writable base to live in. -
sys_packagesis not reachable fromdefineSeed. It is a raw SQL table created byservice-package's own DDL (CREATE TABLE IF NOT EXISTS sys_packages …), not an ObjectQL object, so the stack's declarativedata:block cannot address it. Provisioning one means playing the admin's part imperatively at boot —protocol.installPackageplusprotocol.saveMetaItem— in the shapebind-position-sets.tsandseed-approval-demo.tsalready use for other bootstraps. -
A roll-up needs TWO objects, not one. A
summaryfield lives on the parent and aggregates a child that carries the relationship back. No existing showcase child can serve, because each already points at its own parent (showcase_expense_lineatshowcase_expense_report). So the fixture is a boot-time metadata-authoring bootstrap that mints two new tables on every fresh boot of the reference app.
Why it is a design call rather than a bigger chore
Shipping a permanent writable base changes what the reference app is, in ways that reach past this one item:
access-security.readonly-package-locks-studio(P2) uses the showcase as the read-only side of a two-sided gate and needs "a WRITABLE (draft/app-local) object" as its contrast — so a stock writable base would also serve that item. That is an argument in favour, and it is precisely why the decision is not local to the rollup item.- Studio's package selector, the
/metastate routes, and the schema-sync path all gain a second, mutable metadata home on every boot. - Today the platform's designed path for a writable base is on demand (ADR-0033 zero-package app building: the AI blueprint flow auto-creates one). Nothing consumes a pre-seeded one, so shipping one is capability surface with no measured pull.
Recommendation
Decide the question before building anything: should the stock showcase boot with a project-scoped writable package?
- If yes — provision it once, imperatively, alongside the existing
kernel:bootstrappedbootstraps, with a minimal parent/child pair whose only job is to carry one filteredsummaryfield. That closesautomation.rollup-summary-filterclause 5 and givesaccess-security.readonly-package-locks-studioits contrast side in the same move, and both items should be revised together. - If no — say so on the two items and retarget them at a run-time step (the runner duplicates the showcase base into a writable one via
POST /packages/:id/duplicate, which is the platform's own supported path) rather than leaving them carrying a fixture blocker nobody intends to pay.
Either way it wants a maintainer/showcase-owner ruling first; the implementation is small once the question is answered.
Context
- Parent card: Land the showcase seed fixtures that unblock the checklist's stock-fixture gaps (loginable 2nd member, publicSharing object, writable summary field, readable:false FLS grant) #9308 (three of its four fixtures landed;
FOLLOW-UPS.mdsection 6 records the split). - The checklist item:
docs/qa/platform-checklist/areas/automation.json→automation.rollup-summary-filter. - The read-only contrast item:
docs/qa/platform-checklist/areas/access-security.json→access-security.readonly-package-locks-studio.
Activity
os-support-ai commentedon Aug 19, 2026
Triage:
finding→needs-user-decision. The card's own analysis is complete and measured; restating the decision with the required four-axis block.Question: should the stock showcase boot with a project-scoped writable package (imperative bootstrap minting a minimal parent/child pair for one filtered
summaryfield)?Four-axis block:
automation.rollup-summary-filterclause 5 andaccess-security.readonly-package-locks-studio's writable contrast side), which is genuine coherence value inside the QA surface.POST /packages/:id/duplicate, the platform's supported path) keeps the stock app deterministic.Recommendation: no — retarget both checklist items at the runtime
POST /packages/:id/duplicatestep, per the card's own if-no branch; the duplicate route also exercises a real platform capability instead of a bespoke fixture. If the maintainer rules yes, both items get revised together as the card specifies.本评论来自分诊座位 Routine (session
session_018euHiF12oV8iSfYdjVioUF).Generated by Claude Code
os-zhuang commentedon Aug 19, 2026
Triage half-annotation heal (triage seat, session
session_014qTKTqjme5Fp5BH9iRmy6t): addeddomain:devx— the ruled work is two checklist-item revisions underdocs/qa/platform-checklist/**, which is the devx lane. State (pm:queue) and the 2026-08-19 maintainer ruling are untouched.Generated by Claude Code
os-steve commentedon Aug 25, 2026
Claim: PM dispatch (devx seat)
session_015ahemw8RcTgqtxrj15PEZxclaude/issue-9788-rollup-filter-duplicate-routeThe design question on this card is closed — maintainer ruled NO on 2026-08-19 (「接受你的所有建议」): the stock showcase does not boot with a writable package, and both checklist items retarget at the platform's supported runtime path,
POST /packages/:id/duplicate. Nothing here re-opens that; the remaining work is two mechanical revisions.The ruling names two files. Only one is free:
docs/qa/platform-checklist/areas/automation.jsonautomation.rollup-summary-filterclause 5docs/qa/platform-checklist/areas/access-security.jsonaccess-security.readonly-package-locks-studiowritable-contrast sideMeasured against #11780's actual changed-file list, not its title:
access-security.jsonappears (control: it is 1 of the 7 checklist area files that PR touches),automation.jsondoes not (0). So the split is clean rather than convenient.The two halves land in different files, so each carries its own revision bump and history entry — splitting duplicates nothing. The card therefore stays OPEN after this PR; the PR uses
Part of #9788, ⛔ notFixes.Blocked-by:can only name an issue, but the real condition is "a PR merges" — the #11220 gap. Check PR #11780's merge state, not #11501's.Tier: sonnet. Derived live —
node scripts/pm/dispatch-gates.mjs --tier docs/qa/platform-checklist/areas/automation.jsonreports no path-derived mandate, so sonnet is the floor and this is a deliberate floor call: the design act is already ruled, and what remains is revising one acceptance clause and removing ablocked.by: fixtureentry against a named route.Generated by Claude Code
os-steve commentedon Aug 25, 2026
{ "issue": 9788, "status": "done", "branch": "claude/issue-9788-rollup-filter-duplicate-route", "pr": "https://github.com/objectstack-ai/objectstack/pull/11913", "premise_still_valid": true, "summary": "Retargeted automation.rollup-summary-filter clause 5 (docs/qa/platform-checklist/areas/automation.json) at the platform's POST /packages/:id/duplicate route per the maintainer's 2026-08-19 ruling, replacing the item-level blocked.by:fixture entry and its matching fixtures.knownGaps line; revision bumped 2->3 with a history entry. Verified the duplicate route exists and genuinely produces a writable base (packages/runtime/src/domains/packages.ts:819, protocol.duplicatePackage, ADR-0070 D4) before writing anything, and re-read automation.json on origin/main first to confirm the clause/blocked-block were still present as the card described. The sibling half (access-security.json) is held by open PR #11780 and was left untouched.", "tests": "All local: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (run on final commit 86c4a39b9) names 2 matched families for the 1-path diff, both run under scripts/pm/os-verify-lock.sh and green: `pnpm check:doc-authoring` -> VERDICT command-exit 0, 'doc authoring guard: 389 files clean - no bare metadata literals'; `pnpm --filter @objectstack/lint run check:doc-formula-expressions` -> first run hit its own documented PREREQUISITE-NOT-MET guard (packages @objectstack/formula then @objectstack/lint not built in the fresh worktree), fixed with `pnpm exec turbo run build --filter=@objectstack/formula` and `--filter=@objectstack/lint`, then VERDICT command-exit 0: 'check:doc-formula-expressions self-test: 50 cases passed', '22 record-scoped formula example(s) ... judged clean', '9 @example(s) judged clean', '14 predicate(s) ... judged clean; 6 skipped as undeterminable' (documented, pre-existing, unrelated to this diff). check:platform-checklist is not CI-wired (manual cadence by maintainer decision, per the area README) so dispatch-gates.mjs does not name it, but the README asks for it whenever the checklist itself is touched, so it was run anyway: VERDICT command-exit 0, 'check-platform-checklist: OK - 15 areas, 207 items (207 active); coverage: 31 kinds mapped, 0 waived; traps: 19 documented, 19 in use; provisioning: 4 area recipes, 7 item references resolved (1 area-qualified), 4/4 recipes referenced'. No changeset expected (QA-checklist-only, nothing user-visible/published); skip-changeset applied via the additive labels POST and confirmed present on read-back (GET .../issues/11913/labels returned both size/s and skip-changeset).", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
4 remaining items
claude commentedon Aug 31, 2026
Claim · R33 ·
domain:devxexecution seatsession_01Pk26oZ12t5N1hwGW1m1MgCclaude/issue-9788-readonly-package-locks-retargetsonnet— half 1 already shipped the exact shape; this is the mirrored half.docs/qa/platform-checklist/areas/access-security.json. ⭐ Free.packages/spec/**, no contract behaviour, no public surface.docs/adr/**·.claude/**·skills/**·AGENTS.md·CLAUDE.md) ⇒ armable once green.⛔ This seat's correction, before the dispatch
This seat's own seat-post carried "#9788 是
domain:spec's despite carryingdomain:devx" as an inherited line. That is wrong. The landing file isdocs/qa/platform-checklist/areas/access-security.json— the QA checklist, notpackages/spec— and triage explicitly keptdomain:devx+testswhen it returned the card to the queue.⭐ Recorded because it is the fifth inherited assertion this seat has had to overturn today by actually reading the card, after the #13307 / #13423 / #13424 / #10622 lane rows and the
content/docs/**fence. ⇒ an inherited fence is a hypothesis, not a fact.Zone 1 — 维护者已裁两次. ⛔ 不可重裁.
⛔ Do NOT reopen "should the stock showcase boot with a project-scoped writable package?" It was asked, escalated, and answered NO — twice. The escalation was correct as a visibility action; the ruling already existed.
The remaining work is mechanical:
bb62d4d08, "docs(qa): retarget rollup-summary-filter editor half at duplicate route"):automation.rollup-summary-filterclause 5 now targetsPOST /packages/:id/duplicate(ADR-0070 D4), its item-levelblocked.by: fixtureentry and matchingknownGapsline are gone, and the revision is bumped with a history entry.docs/qa/platform-checklist/areas/access-security.json→access-security.readonly-package-locks-studio, its writable-contrast side, same retarget, same route.⭐ Half 1 is your specification. Read
bb62d4d08and mirror its shape — the retarget, the removal of the staleblocked.by/knownGapspair, the revision bump, the history entry. ⛔ Do not invent a different shape for the same move.⛔ Two stale readings on this card — ⛔ do NOT re-derive them
ADR-0057 D10citations toADR-0124 D1— a classification pass, not a sed #11501's state. Triage says plainly it "was never the real condition (the [finding]Blocked-by:can only name an issue, but the two conditions cards actually wait on are "a PR merges" and "a release lands and the pin covers it" — measured on both #11220 gap)."Blocked-by:/Restart-when:pair on the 2026-08-25T01:38Z comment is SATISFIED — PR docs: retarget the general-ruleADR-0057 D10citations toADR-0124 D1#11780 landed as359e497f8, freeing the file. An older comment on a card is an archive, not a current state; this card's own history shows how easily one is re-read as live.Zone 2 — PM 机制假设(须实测,鼓励证伪)
bb62d4d08contains every structural element you need. If half 1 did something this half must not copy — because the two items differ — say which and why.⭐ Available tooling
docs/qa/platform-checklist/has dedicated skills in this repo —checklist-author(authoring items) andchecklist-test(running them) with aRUNNER.md. ⭐ Read the authoring skill before editing the JSON by hand; it is likely to name the revision/history convention you need.⛔ Hard fences
content/docs/**is epic epic(docs-site): the site is technically un-indexable — fix robots/sitemap/canonical/OG first, then the keyword shape #12243's declared territory — ⛔ not this card's surface and ⛔ not to be touched.content/docs/releases/**is never edited in a code PR.git stash(refs/stashis shared across every worktree of this repo).Generated by Claude Code
docs(qa): retarget readonly-package-locks-studio writable contrast at…
os-project-manager commentedon Aug 31, 2026
os-dev-report
{ "issue": 9788, "status": "done", "branch": "claude/issue-9788-readonly-package-locks-retarget", "pr": "https://github.com/objectstack-ai/objectstack/pull/13607", "premise_still_valid": true, "summary": "Retargeted access-security.readonly-package-locks-studio's writable-package contrast side (step 5, acceptance clause 3, docs/qa/platform-checklist/areas/access-security.json) at the platform's POST /packages/:id/duplicate route per the maintainer's 2026-08-19/2026-08-25 ruling. Added a fixtures block (item had none before) naming the runtime route, retargeted step 5 and acceptance clause 3's wording, added source citations for the duplicate route and ADR-0070 D4, bumped revision 2 to 3 with a history entry. Re-read the item on origin/main first to confirm the premise (generic 'WRITABLE (draft/app-local) object' wording, no fixture blocker) matched the dispatch card, and confirmed PR #11780 had not already touched this wording. This is the second and last of the two mechanical retargets the ruling called for -- the first (automation.rollup-summary-filter, PR #11913) already landed -- so the PR uses Fixes #9788, not Part of.", "tests": "All local, run under scripts/pm/os-verify-lock.sh, on final commit 2821d5d08. Gate family derived live: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack named 2 matched families for the 1-path diff -- `pnpm check:doc-authoring` -> VERDICT command-exit 0, 'doc authoring guard: 393 files clean - no bare metadata literals'; `pnpm --filter @objectstack/lint run check:doc-formula-expressions` -> (built @objectstack/formula and @objectstack/lint first, per the toolchain trap) VERDICT command-exit 0, 'check:doc-formula-expressions self-test: 58 cases passed', '22 record-scoped formula example(s) ... judged clean', '9 @example(s) judged clean', '14 predicate(s) ... judged clean; 6 skipped as undeterminable' (documented, pre-existing skip list, unrelated to this diff). check:platform-checklist is not CI-wired (manual cadence) so dispatch-gates.mjs does not name it, but the area README asks for it whenever the checklist itself is touched, so it was run anyway: VERDICT command-exit 0, 'check-platform-checklist: OK - 15 areas, 221 items (221 active); coverage: 31 kinds mapped, 0 waived; traps: 19 documented, 19 in use; provisioning: 5 area recipes, 8 item references resolved (1 area-qualified), 5/5 recipes referenced'. Also ran pnpm check:nul-bytes (any edit) -> VERDICT command-exit 0, 'scanned 7539 text file(s) -- 7539 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes'. JSON validated with python3 json.load before and after each edit. No changeset (QA-checklist-only, nothing user-visible/published, same precedent as PR #11913); skip-changeset applied via the additive REST POST .../issues/13607/labels (200, no auth wall on this seat) and confirmed present on read-back via pull_request_read (labels: size/s, skip-changeset).", "mcp_calls": "8 -- issue_read x2 (get, get_comments) + pull_request_read x3 (11913 get, 13607 get x2) + create_pull_request x1 + update_pull_request x1 + add_issue_comment x1", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
claude commentedon Aug 31, 2026
✅ ACCEPT · R33 ·
domain:devxPM seat — PR #13607. Small, exact, ⛔ nothing widened.The ruling called for two mechanical retargets. Half 1 landed as PR #11913 (
bb62d4d08); this is half 2, and the last of them — which is why the PR correctly carriesFixes #9788rather than aPart of.⭐⭐ The best thing here is what it did BEFORE editing
⇒ exactly the discipline this card needed. Its history is a minefield of satisfied-but-still-written blockers — a
Blocked-by:/Restart-when:pair that PR #11780 had already cleared, and a #11501 dependency triage says "was never the real condition." ⭐ A dev that re-derives the premise instead of trusting either the card or the PM prompt is the only kind whose "premise still valid" means anything. This lane dispatched already-finished work earlier today for want of exactly this check.The delivery
POST /packages/:id/duplicate;fixturesblock added — the item had none — naming the runtime route;bb62d4d08's shape rather than inventing one.⛔ Zone 1 held: the design question was not reopened, no writable package provisioned, no seed fixtures added. ⛔ One file,
docs/qa/platform-checklist/areas/access-security.json, +19/−5.Zone 2 — all three confirmed
bb62d4d08contains every structural element needed ✅ — mirrored, nothing deliberately omitted.⭐ It ran a gate the derived family does not name, and was right to
check:platform-checklistis not CI-wired (manual cadence), sodispatch-gates.mjscorrectly did not name it. The area README asks for it whenever the checklist itself is touched, so the dev ran it anyway:⇒ ⭐⭐ The derived family is a floor, not a ceiling. A gate that the wiring does not reach is still the gate that judges this file, and running it is the difference between "CI is green" and "the artifact is correct." ⛔ And it did not stop there: JSON validated with
python3 json.loadbefore and after each edit — the explicit instruction was ⛔ not to hand-verify shape by eye, and it did not.Derived family (2 matched for the 1-path diff) green:
check:doc-authoring(393 files clean) andcheck:doc-formula-expressions(58 self-test cases; ⭐ built@objectstack/formulaand@objectstack/lintfirst per the toolchain trap, rather than reporting a PREREQUISITE-NOT-MET as a result).check:nul-bytesgreen over 7539 files. Label written via the additive REST POST and confirmed on read-back.Landing
⛔ Not governed (
docs/qa/**is not on the register) and ⛔ not clause ②. ⇒ armable once its last check converges.Generated by Claude Code
claude commentedon Aug 31, 2026
pm:dispatcheddropped — PR #13607 merged 03:36Z; a closing keyword does not touch labelsdomain:devxPM seat (#6023), R33. 关闭即摘pm:*状态标, in the same stroke.⭐ This is the second and last of the two mechanical retargets the 2026-08-19 ruling called for — half 1 landed as PR #11913 (
bb62d4d08), half 2 is this one. ⇒ the ruling is now fully discharged, and the card closes rather than parking.domain:*and the type labels stay: 归属不是状态.Generated by Claude Code
docs(qa): retarget readonly-package-locks-studio writable contrast at…