Repository navigation
Closed
Labels
area:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portaldomain:specenhancementNew feature or requestNew feature or requestpriority:p1High: required for production / M2High: required for production / M2
Description
domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut
Part-of #28722
Ruled: 6566915346 · letter E · 2026-11-02T01:30Z
Ruling-ref: 6566915346
Re-cut as the domain:spec p1 slice (spec seat 2, 2026-11-02T12:21Z), as the ruling's Execution line orders: "this card is re-cut as the domain:spec p1 slice (Part-of #28722, Ruling-ref: naming this comment)". The original domain:ui#3 body (the served nav owner-stamp ask, with its measure) is the prior revision of this body; the measure and the options are in comments 6556726236, 6556991855, 6559222926 and 6566865190.
What the ruling binds (letter E, quoted from 6566915346)
- "
GET /packages/:id/customizationscontributions(packages/spec/src/api/package-lifecycle.zod.ts:406, PR feat(runtime): the per-base customizations read names the package behind each field and flow another package contributes #28749) gainskind: 'nav'. A nav entry names the base-ownedappit was contributed to, thegroupwhen the contribution targets one, the nav item's id as itsname, andpackageId; the entry shape is per kind (objectforfield/flow,app+ optionalgroupfornav), spelled by the spec card.counts.contributionskeeps counting items." - "Served from the same
appNavContributionsregistry the fold reads … never by a client-side join on names. A disabled package's contributions are not listed (packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117); the base and its<base>.custompair are not contributions, as the member already says." - "No key is added to any nav item: the served app's
navigationstays as declared andBaseNavItemSchemastays strict. NonavContributorsmap on the item read." - "This is a protocol addition:
Clause-②: yes (widening),Metadata-protocol: added, spec slice atCONTRACT_REVIEW_TIER."
This card (spec slice)
GetPackageCustomizationsResponseSchema.contributions(packages/spec/src/api/package-lifecycle.zod.ts) gains thenavkind with a per-kind entry shape; the member's and the schema's describes name the third kind and its ordering; a liveness row and the docs pages that list the member.- Declared ahead of its producer: until the server slice serves it, the
navarm says so in its describe (no served key without a reader of record, ADR-0049).
Not this card
domain:server: runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 Wanted 3,readBaseContributionsreads theappNavContributionsregistry (server seat 3, after this lands).domain:ui: drawing the contributed entries greyed with the package label (Setup and Studio: suggestions from a full HotCRM browser pass on 18.2.0: user onboarding, packaged automation state, run-now for scheduled flows, admin lists, and Studio entry, field table, flow inspector wording and one designer per item #27356 row 20), filed by ui seat 4 after the server slice.
Metadata
Metadata
Assignees
Labels
area:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portaldomain:specenhancementNew feature or requestNew feature or requestpriority:p1High: required for production / M2High: required for production / M2
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p3 ·
domain:server·area:studio· first touch (retriage) · 2026-10-30T11:02Z⛔ Not a claim. This first touch was owed: a filer's labels with no triage audit.
packages/objectql/src/registry.ts, so the server lane stands. If serving the contributing package beside each folded nav entry is a new served key, it is a protocol addition and comes back here before code. p3, not dispatched on its own.pm:retriageremoved.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH
Claim: PM loop round 1 · card thread · 2026-11-01T10:24Z
Session:
session_01FEkQ5kE5BrPUPNMMyv6oCH(the seat); the card thread issession_01FEkQ5mmZYpLmZVtuxRHzKCAccount:
os-project-manager(the seat's linked user; the card's assignee)Branch:
claude/project-thread-tt1ra6(the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#3Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」, and 2026-11-01T06:39Z 「server 队列还是很多任务,再开一个席位吧」. Leehom 2026-11-01T10:18Z: every graded
pm:queue+domain:servercard is dispatchable. Triage6521106045binds: a new served key comes back to triage before code.File surface:
packages/objectql/src/registry.ts(applyNavContributions), the served app read tests, and a changeset, ONLY if the measure finds the owner stamp already declared. ⛔ Notpackages/spec.Container & model:
S(p3),mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: highClause-②: no — expected only if the served nav item shape already declares an owner stamp; if the stamp is a new served key, the dev stops with
needs_decisionand the card goes back to triage as triage6521106045says.Metadata-protocol: none (expected; the dev measures and declares)
Responsibility: the code is the registry fold of
navigationContributions· the platform path is the served app read · reached by a Studio author whose nav groups are filled by other packages and show "No items in this package"Thread-read: 6521106045
Premise: holds (card body:
applyNavContributionsdropspackageId); measure-first on the spec question before any codeSerial constraints cleared: none: no open PR found on
applyNavContributionsat this read; the dev re-reads overlap at start and beforepr_create.Resume-from: none — fresh from
origin/mainState: →
pm:dispatched, assigned toos-project-manager, recorded by this claim. Order:pm-orders/server/order-27928.md(project folder).objectstack-fleet commentedon Nov 1, 2026
domain:server#3 · os-project-manager · session_01FEkQ5mmZYpLmZVtuxRHzKC
os-dev-report
{
"issue": 27928,
"status": "needs_decision",
"branch": "claude/project-thread-tt1ra6",
"pr": null,
"session": "session_01FEkQ5mmZYpLmZVtuxRHzKC",
"premise_still_valid": true,
"summary": "Measured on origin/main a798ae8, read-only, no code. The premise holds:
SchemaRegistry.registerAppNavContributionkeepspackageIdper contribution (packages/objectql/src/registry.ts:7240) andapplyNavContributions(registry.ts:7267-7307) pushesc.itemsinto the group or top level unchanged, so the served app cannot say who contributed an entry. The served nav item shape does NOT admit an owner stamp: every nav branch is astrictObjectoverBaseNavItemSchema(packages/spec/src/ui/app.zod.ts:303; keys id, label, icon, order, badge, badgeVariant, visible, dataSource, requiredPermissions, requiresObject, requiresService), the separator branch declares only type/id/order (app.zod.ts:842), andMetadataProtectionFields(_packageIdat packages/spec/src/kernel/metadata-protection.zod.ts:117) is spread only at the AppSchema level (app.zod.ts:2119). No passthrough exists either:getAppNavContributions(registry.ts:7252) has zero non-test readers, and no served key names a contributor. So any stamp on the entry or beside the item is a spec addition; per the order and triage 6521106045 this stops before code and goes back to triage.","tests": "n/a — measure-first reading, no code, no build. Readings are git show / git grep on origin/main a798ae8 (shallow checkout; no ancestry claims made).",
"gates": "n/a — no diff, so
dispatch-gates --commandsderives nothing and no gate ran.","dogfood_battery": "n/a — no PR",
"mcp_calls": "5 — mcp__github__issue_read x5 (get #27928 x1, get_comments #27928 x4, incl. reading claim 6556692704 which names this branch), all reads, no write tool",
"api_writes": "1 — POST issues/27928/comments (this os-dev-report, via scripts/pm/post-stamped.mjs)",
"open_questions": [
{
"question": "Where should the served answer name the package that contributed each folded nav entry? Every option is a spec addition except C and D. Measured facts the options rest on: (1) a stamped key inside a nav item would be REFUSED by the app's own schema on any parse, because
Registry.validate('app')runsAppSchema.parse(registry.ts:6185) and the save door answers 422 on an off-spec body; (2) Studio edits the layeredeffectivebody (ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx ~4572,client.layered('app', name)), which carries no contributions, and reads the served, folded answer only throughshellClient.list('app'); (3)GET /packagesalready serves each package'smanifest(packages/runtime/src/domains/packages.ts:316-317) includingnavigationContributions, plusenabled; (4) metadata-protocol folds on both reads (packages/metadata-protocol/src/protocol.ts:10449 list, :11590 by-name). Producers measured: 16 non-test source files declarenavigationContributions(packages/apps/setup, cloud-connection x2, mcp connect-ui, plugin-approvals/audit/auth/security/sharing/webhooks, service-automation/datasource/messaging/settings, examples/app-multi-package x2) and hotcrmobjectstack.config.ts. Reader today: none; the Studio half (#27356 row 20) is the named reader, filed after this lands.","options": [
"A — stamp on the entry: declare a machine-managed optional
_packageId(string) onBaseNavItemSchemaand the separator branch in packages/spec/src/ui/app.zod.ts, and haveapplyNavContributionsset it on each folded item fromc.packageId; the app's own items stay unstamped (the app's_packageIdalready names them). Owes: the liveness row (packages/spec/liveness/app.jsonnavigation),Metadata-protocol: added, and a save-door rule refusing the key on authored nav items, because_-prefixed keys are skipped by the authoring-key lint (packages/spec/src/data/authoring-key-lint.ts:264) and an AI copying a served app into source would otherwise author it silently. Work: M (spec + objectql + save door + tests).","B — serve it beside the item: add an optional
navContributorsrecord (nav item id to package id) toGetMetaItemResponseSchema(packages/spec/src/api/protocol.zod.ts:712), thedisabledActions/cascadeDeleteObjectsshape, present only on anappread and absent on a draft read; the registry returns the map from the same fold, metadata-protocol carries it on the by-name read, the rest cached arm folds it into the ETag. The authoring schema is unchanged. Studio readsGET /meta/app/:nameinstead of the list row for this. Metadata-protocol: none to my reading (a response envelope key nobody authors); the seat should confirm against the level table. Work: M (spec api + objectql + metadata-protocol + rest cached arm + tests).","C — no server change: the Studio card joins the served app with
GET /packagesmanifests (navigationContributions[].itemsby id, skipping packages withenabled: false). Zero spec. Costs: a second copy of the fold's ownership logic in ui (the #28117 disabled-package rule and any future rule must be mirrored), and I found no check that nav ids are unique across contributing packages into one app (unverified), so a join by id can be ambiguous. This card closes as not needed and the work moves to adomain:uicard.","D — do not build now: p3, zero reader today; close not planned (or on-hold with a Restart-when on the Studio row being ruled)."
],
"recommendation": "B. 长远合理性(权重最高):fold 是唯一生产者,它本来就握着 packageId,B 让同一个生产者在 API 信封里说出这个派生事实,沿用 disabledActions / cascadeDeleteObjects 的「beside item, never inside it」先例,作者可写的 nav schema 一个键都不加;C 在 ui 端复制一份 fold 的归属逻辑,正是 lint 注释里点名的漂移来源。防 AI 写错:A 把一个
_键加进作者 schema,而 authoring-key lint 跳过_前缀,AI 从 served app 抄回源码时会静默通过,还要另加一条保存门拒收;B 不增加任何可写面;C 的消费端推导出错时静默。实际业务需求:拉动是真的但还未兑现,16 个生产者文件把条目塞进 setup 和 HotCRM 的分组,Studio 在这些分组上显示「这个软件包里没有条目」(#27356 第 20 行实测);读者是随后的 ui 卡,今天零读者。创业阶段不扩散:D 最省,C 零 spec,B 只加一个可选响应键,A 最重(作者 schema + 保存门)。有实测拉动 ⇒ 荐长远形态一次付清,故荐 B;若维护者认为 p3 不值一个协议键,次选 D 而不是 C。"}
],
"out_of_scope_findings": []
}
Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH
Release: claim
6556692704(session_01FEkQ5kE5BrPUPNMMyv6oCH, card threadsession_01FEkQ5mmZYpLmZVtuxRHzKC, branchclaude/project-thread-tt1ra6) · 2026-11-01T10:28Z · measure-first ended atneeds_decision, no codeProduce: none (no commit on the branch; os-dev-report 6556726236)
Resume-from: none — fresh from
origin/mainonce a ruling picks an optionorigin/maina798ae8f): every nav item branch is a strict object overBaseNavItemSchema(packages/spec/src/ui/app.zod.ts) with no owner key, and nothing passes one through. Any owner stamp is a new served key, so per triage6521106045the card comes back before code._packageIdon each entry; B serve anavContributorsmap beside the item in the item read (thedisabledActionsshape); C Studio joins theGET /packagesmanifests, no server change; D do not build. The dev recommends B, then D.pm:dispatched→pm:retriage, assignee cleared. The maintainer is asked for the ruling in the seat's thread; a B or A ruling makes it a spec-lane card at p1 under 「协议新增定 p1」.8 remaining items
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Exit stroke · #27928 · 2026-11-02T12:18Z
Ruling-ref: director record
6566915346(batch #451 item 2, letter E, maintainer 「同意」 2026-11-02T01:29Z); the director's notify on the server seat 3 mailbox #29125 (6576895608) names this stroke as owed by the lane.needs-user-decision→pm:queue. The ruling is made, so the card is ready to work.domain:server→domain:spec. Priority:priority:p3→priority:p1. Both come from the record itself: "per 「协议新增定 p1」 this card is re-cut as thedomain:specp1 slice (Part-of #28722)". The seat is applying the ruling's grade here, not grading the card itself.contributionsmember gainskind: 'nav'withapp, an optionalgroup,nameandpackageId; a liveness row; docs;Part-of #28722; and aRuling-ref:naming6566915346. Declaration:Clause-②: yes (widening),Metadata-protocol: added, contract review atCONTRACT_REVIEW_TIER.readBaseContributionsreads theappNavContributionsregistry. runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 stayspm:blockeduntil then.objectstack-fleet commentedon Nov 2, 2026
domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut
Claim: PM loop round 1 · 2026-11-02T12:26Z
Session:
session_01ADHkmSduNGC2SZXszyrNut(seat); dev = card threadsession_01ADHkmQ28WWiNo3u94yGTPbAccount:
os-steveBranch:
claude/project-thread-845vdnWorktree: the card thread's own checkout of
objectstack-ai/objectstackDomain:
domain:specSeat:
domain:spec#2File surface:
packages/spec/src/api/package-lifecycle.zod.ts(GetPackageCustomizationsResponseSchema.contributionsgains thenavkind, per-kind entry shape, describes and docblock) and its tests; the liveness row and the docs pages that list the member; regenerated references; root.changeset/; narrowing-guard edits in consumers only if a typecheck forces them (named in the PR body); ⛔ not the producerreadBaseContributions(#28722 Wanted 3,domain:server) (stop on breach; explain in the report)Container & model:
S,mode:thread,model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); Clause-② widening of a served response schema, one CONTRACT_REVIEW_TIER review by the seat before landing,effort: xhighClause-②: yes (widening)
Metadata-protocol: added
Responsibility:
n/a — not a defect cardThread-read: 6576949541
Premise: holds (on origin/main 12:20Z,
contributions[].kindisz.enum(['field', 'flow'])with a requiredobject, and nonavkind exists)Serial constraints cleared: none (no in-flight
domain:specclaim namespackage-lifecycle.zod.ts; the earlierdomain:server#3claim 6556692704 was released in 6556736104)Ruling-ref: 6566915346 (director record, batch #451 item 2, letter E, the maintainer's 「同意」); exit stroke 6576949541 (server seat 3); body re-cut by this seat as the spec slice.
objectstack-fleet commentedon Nov 2, 2026
domain:spec#2 · os-steve · session_01ADHkmQ28WWiNo3u94yGTPb
os-dev-report
Stamped 2026-11-02T14:08Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut
Landed: PR #29401, merged as
0c640141at 2026-11-02T15:33Z.ACCEPT → PR #29401 comment 6580492378 · contract review PASS 6579472483 (
3bdb4133) and delta PASS 6580471213 (71941530).Follow-ups filed: #29411 (skills platform), #29412 (variant docs
z.enum). #28722 Wanted 3 is now unblocked fordomain:server; the seat tells server seat 3.