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
Observation-class finding, surfaced while implementing #4976. One site exists today and it is fixed in that PR; this issue records the shape, because the next fixture that needs "the stack as the build would emit it" walks into the same trap.
The trap
lowerCallables lives in packages/cli/src/utils/lower-callables.ts and is not exported from @objectstack/cli's public entry. A test that needs a built-shaped artifact therefore cannot call it, and the reachable substitute is JSON.stringify(stack) — which does only half of what the build does:
real objectstack build
JSON.stringify(stack)
bare callable fn: () => …
lowered to 'fn', callable into the sidecar .mjs
key omitted entirely
declared { handler: fn, effect }
{ handler: 'fn', effect }, callable into the sidecar
{ effect } — a headless husk
Why it hides
The bare-form column is the dangerous one: the entry vanishes key and all, so the artifact holds functions: {} and parses green. packages/qa/dogfood/test/showcase-declarative-endpoints.dogfood.test.ts had been writing its artifact that way, and it had never carried either of the showcase's two functions — the boot it advertises as "the way a deployment boots it" ingested zero of them, invisibly, for as long as the fixture has existed.
The declared-form column is what finally made a noise: #4976 restored the showcase's honest { handler: sweepProjectHealth, effect: 'writes' } spelling, the husk { effect: 'writes' } reached the parse, and FlowFunctionEntrySchema refused it in all four members — correctly, since an entry declaring an effect for a function it does not carry is not a thing the runtime can honour. That red CI job is the only reason anybody learned the artifact was empty.
So the failure mode is the one this repo keeps paying for: a fixture that silently degrades and reports success (see AGENTS.md "Absence must be loud" — a verifier that silently degrades is worse than no verifier).
Not urgent
Nothing a user hits: this is test infrastructure, and the single existing site is fixed in #4976's PR by declaring the omission explicitly (drop functions, say why, note that the live stack handed to bootStack is what actually supplies them). Hence finding, not pm:queue.
The question worth deciding, when it next comes up
Whether the lowering should be reachable outside the CLI at all — so that a fixture standing in for the build agrees with the build by construction rather than by re-derivation. Three readings, none obviously right:
Export it (move lowerCallables to a shared package, or re-export from @objectstack/cli). Fixtures get the real thing; the surface grows for a consumer set of one test.
Have fixtures consume a real built artifact rather than synthesising one. Truest, heaviest.
Per the startup-focus principle there is no measured pull for (1) today — one site, now explicit. Recording it so the second site is a decision rather than a rediscovery.
Observation-class finding, surfaced while implementing #4976. One site exists today and it is fixed in that PR; this issue records the shape, because the next fixture that needs "the stack as the build would emit it" walks into the same trap.
The trap
lowerCallableslives inpackages/cli/src/utils/lower-callables.tsand is not exported from@objectstack/cli's public entry. A test that needs a built-shaped artifact therefore cannot call it, and the reachable substitute isJSON.stringify(stack)— which does only half of what the build does:objectstack buildJSON.stringify(stack)fn: () => …'fn', callable into the sidecar.mjs{ handler: fn, effect }{ handler: 'fn', effect }, callable into the sidecar{ effect }— a headless huskWhy it hides
The bare-form column is the dangerous one: the entry vanishes key and all, so the artifact holds
functions: {}and parses green.packages/qa/dogfood/test/showcase-declarative-endpoints.dogfood.test.tshad been writing its artifact that way, and it had never carried either of the showcase's two functions — the boot it advertises as "the way a deployment boots it" ingested zero of them, invisibly, for as long as the fixture has existed.Measured:
The declared-form column is what finally made a noise: #4976 restored the showcase's honest
{ handler: sweepProjectHealth, effect: 'writes' }spelling, the husk{ effect: 'writes' }reached the parse, andFlowFunctionEntrySchemarefused it in all four members — correctly, since an entry declaring an effect for a function it does not carry is not a thing the runtime can honour. That red CI job is the only reason anybody learned the artifact was empty.So the failure mode is the one this repo keeps paying for: a fixture that silently degrades and reports success (see AGENTS.md "Absence must be loud" — a verifier that silently degrades is worse than no verifier).
Not urgent
Nothing a user hits: this is test infrastructure, and the single existing site is fixed in #4976's PR by declaring the omission explicitly (drop
functions, say why, note that the live stack handed tobootStackis what actually supplies them). Hencefinding, notpm:queue.The question worth deciding, when it next comes up
Whether the lowering should be reachable outside the CLI at all — so that a fixture standing in for the build agrees with the build by construction rather than by re-derivation. Three readings, none obviously right:
lowerCallablesto a shared package, or re-export from@objectstack/cli). Fixtures get the real thing; the surface grows for a consumer set of one test.functions: { fn: { handler, effect: 'writes' } }cannot surviveobjectstack build— lowering emits a shape FlowFunctionEntrySchema rejects #4976's PR does. Cheapest, and honest, but each new fixture must remember.Per the startup-focus principle there is no measured pull for (1) today — one site, now explicit. Recording it so the second site is a decision rather than a rediscovery.
Filed unassigned per Prime Directive #10.