Split out of #10504 while implementing its UI: 0 Apps fix. Filed unassigned — not routed, not graded.
Measured
packages/cli/src/utils/format.ts → printMetadataStats. The summary is built from four sections (Data, UI, Logic, Security), each rendered by the same loop:
for(constsectionofsections){letshown=section.items.filter(([,v])=>v>0);if(shown.length===0){if(!section.zeroFallback)continue;// ← whole row silently skipped
...
}
...
}#10504 measured this only through the UI: row (zero apps vs one app on the blank scaffold) and triage ruled narrowly on that row: print UI: 0 Apps instead of dropping it. That PR adds an opt-in zeroFallback per section and sets it only on UI.
The underlying shape, though, is general: any section whose every item is 0 drops out of the summary entirely — the same "reads as never asked, not as zero" defect #10504 fixed for UI:. Concretely:
- A stack with no
flows/workflows/agents/apis — plausible for a data-only backend service — silently loses the whole Logic: line. - A stack with no
positions/permissions declared yet — the default state before any RBAC authoring — silently loses the whole Security: line. Data: is comparatively unlikely to hit this in practice (every scaffold ships one object), but the same code path applies to it too.
Why this is a separate card, not a rider on #10504
Triage's ruling in #10504 named the UI: row specifically, reasoned from that card's own measurement (a warning would fire on every clean scaffold). Whether Logic:/Security: should get the same "print a zero" treatment — and if so, which single item is each section's canonical zero-signal (there's no single obvious analog to Apps for Security:, which has two peer items Positions/Permissions) — is a fresh product-judgment call triage hasn't made. #10504's dispatch brief explicitly fenced this: "if the pattern is general, report it, do not unilaterally widen."
Suggested landing
packages/cli/src/utils/format.ts — extend the zeroFallback mechanism #10504 introduces (or design a section-appropriate variant for Security:'s two peer items) to Logic: and Security:, once triage decides whether/how.
Split out of #10504 while implementing its
UI: 0 Appsfix. Filed unassigned — not routed, not graded.Measured
packages/cli/src/utils/format.ts→printMetadataStats. The summary is built from four sections (Data,UI,Logic,Security), each rendered by the same loop:#10504 measured this only through the
UI:row (zero apps vs one app on theblankscaffold) and triage ruled narrowly on that row: printUI: 0 Appsinstead of dropping it. That PR adds an opt-inzeroFallbackper section and sets it only onUI.The underlying shape, though, is general: any section whose every item is
0drops out of the summary entirely — the same "reads as never asked, not as zero" defect #10504 fixed forUI:. Concretely:flows/workflows/agents/apis— plausible for a data-only backend service — silently loses the wholeLogic:line.positions/permissionsdeclared yet — the default state before any RBAC authoring — silently loses the wholeSecurity:line.Data:is comparatively unlikely to hit this in practice (every scaffold ships one object), but the same code path applies to it too.Why this is a separate card, not a rider on #10504
Triage's ruling in #10504 named the
UI:row specifically, reasoned from that card's own measurement (a warning would fire on every clean scaffold). WhetherLogic:/Security:should get the same "print a zero" treatment — and if so, which single item is each section's canonical zero-signal (there's no single obvious analog toAppsforSecurity:, which has two peer itemsPositions/Permissions) — is a fresh product-judgment call triage hasn't made. #10504's dispatch brief explicitly fenced this: "if the pattern is general, report it, do not unilaterally widen."Suggested landing
packages/cli/src/utils/format.ts— extend thezeroFallbackmechanism #10504 introduces (or design a section-appropriate variant forSecurity:'s two peer items) toLogic:andSecurity:, once triage decides whether/how.