Skip to content

fix(cli): pass unrecognised functions entries through the lowering (#7318) - #7461

Merged
os-help merged 1 commit into
mainfrom
claude/issue-7318-lower-callables-passthrough
Aug 10, 2026
Merged

fix(cli): pass unrecognised functions entries through the lowering (#7318)#7461
os-help merged 1 commit into
mainfrom
claude/issue-7318-lower-callables-passthrough

Conversation

@os-help

@os-help os-help commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7318

The map branch of the top-level functions lowering rebuilt the map rather than editing it: out admitted an entry only in the three shapes it knew — a bare callable, { handler: callable }, or a plain string ref — and deleted everything else. No error, no warning, no key. Two failures came out of that.

1. Lowering stopped being idempotent. { handler: 'syncBilling', effect: 'writes' } — the shape this step itself emits for a declared writer, and the one FlowFunctionLoweredDeclarationSchema was added to accept in #4976 — matched none of the recognised shapes, so a second pass dropped the key and silently un-declared the writer the first pass had kept. Measured on examples/app-showcase/dist/objectstack.json: re-lowering it returned { summarizeCompletedTask: 'summarizeCompletedTask' }, sweepProjectHealth gone, and the result still parsed green.

2. A malformed entry was destroyed instead of reported. The headless husk { effect: 'writes' } that a plain JSON.stringify(stack) leaves where a declaration was (#6293) left the lowering as functions: {} and the stack parsed green, so the build wrote an artifact missing the function rather than refusing — the evidence deleted before the parse could name it.

The fix

Unrecognised entries now ride through under their own key, untouched, and FlowFunctionEntrySchema decides. The husk is refused where the build checks: invalid_union on functions, with functions.sweep in the branch tree that formatZodErrors (#5341) prints. The dedicated loop that re-added string entries is folded into the same pass. Bare callables, declared callables, pre-existing refs and the array form lower exactly as before.

Tests pin both halves against the real pipeline: a second lowering of a lowered stack leaves the key set and the declarations unchanged (map and array), and the husk reaches the parse and is refused by key.

On the stand-in the card named

packages/qa/dogfood/test/build-shaped-artifact.ts keeps its key-for-key reconciliation — it is now unreachable on this path but is still the only check that compares input functions keys against output ones, so it stays as the backstop against a producer that starts dropping again. Its measured claims and the showcase fixture's expectation are updated to the gate that now speaks.


Implemented by a dispatched dev agent in its own container; PR opened by the PM seat because the container had git push but no GitHub API access. Full rationale is preserved verbatim in the commit message of 9ec2b2239.


Generated by Claude Code

…7318)

The map branch of the top-level `functions` lowering REBUILT the map rather
than editing it: `out` admitted an entry only in the three shapes it knew — a
bare callable, `{ handler: callable }`, or a plain string ref — and deleted
everything else. No error, no warning, no key. Two failures came out of that.

1. Lowering stopped being IDEMPOTENT. `{ handler: 'syncBilling', effect:
   'writes' }` — the shape this step itself emits for a declared writer, and
   the one `FlowFunctionLoweredDeclarationSchema` was added to accept in
   #4976 — matched none of the recognised shapes, so a second pass dropped the
   key and silently un-declared the writer the first pass had kept. Measured on
   `examples/app-showcase/dist/objectstack.json`: re-lowering it returned
   `{ summarizeCompletedTask: 'summarizeCompletedTask' }`, `sweepProjectHealth`
   gone, and the result still parsed green.

2. A MALFORMED entry was destroyed instead of reported. The headless husk
   `{ effect: 'writes' }` that a plain `JSON.stringify(stack)` leaves where a
   declaration was (#6293) left the lowering as `functions: {}` and the stack
   parsed green, so the build wrote an artifact missing the function rather
   than refusing — the evidence deleted before the parse could name it.

Unrecognised entries now ride through under their own key, untouched, and
`FlowFunctionEntrySchema` decides. The husk is refused where the build checks:
`invalid_union` on `functions`, with `functions.sweep` in the branch tree that
`formatZodErrors` (#5341) prints. The dedicated loop that re-added string
entries is folded into the same pass. Bare callables, declared callables,
pre-existing refs and the array form lower exactly as before.

Tests pin both halves against the real pipeline: a second lowering of a lowered
stack leaves the key set and the declarations unchanged (map and array), and
the husk reaches the parse and is refused by key.

`packages/qa/dogfood/test/build-shaped-artifact.ts` keeps its key-for-key
reconciliation — it is now unreachable on this path but is still the only check
that compares input `functions` keys against output ones, so it stays as the
backstop against a producer that starts dropping again. Its measured claims and
the showcase fixture's expectation are updated to the gate that now speaks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RiF5oDWaCLK57mPuBsyB4t
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 1:38pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/cli, @objectstack/dogfood.

20 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/skills-reference.mdx (via packages/cli)
  • content/docs/api/client-sdk.mdx (via @objectstack/cli)
  • content/docs/api/data-flow.mdx (via @objectstack/cli)
  • content/docs/api/environment-routing.mdx (via @objectstack/cli)
  • content/docs/api/error-catalog.mdx (via @objectstack/cli)
  • content/docs/automation/hook-bodies.mdx (via packages/cli)
  • content/docs/deployment/backup-restore.mdx (via @objectstack/cli)
  • content/docs/deployment/cli.mdx (via @objectstack/cli)
  • content/docs/deployment/self-hosting.mdx (via @objectstack/cli)
  • content/docs/deployment/validating-metadata.mdx (via packages/cli)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/cli)
  • content/docs/kernel/runtime-services/data-service.mdx (via @objectstack/cli)
  • content/docs/kernel/runtime-services/index.mdx (via packages/cli)
  • content/docs/permissions/authentication.mdx (via @objectstack/cli)
  • content/docs/permissions/authorization.mdx (via packages/qa/dogfood)
  • content/docs/permissions/delegated-administration.mdx (via packages/qa/dogfood)
  • content/docs/plugins/index.mdx (via @objectstack/cli)
  • content/docs/plugins/packages.mdx (via @objectstack/cli)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/cli)
  • content/docs/protocol/kernel/realtime-protocol.mdx (via @objectstack/cli)

3 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/cli)
  • content/docs/releases/v16.mdx (via @objectstack/cli)
  • content/docs/releases/v17.mdx (via @objectstack/cli)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling labels Aug 10, 2026
@os-help
os-help marked this pull request as ready for review August 10, 2026 13:50
@os-help
os-help added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit bf4ebe2 Aug 10, 2026
27 checks passed
@os-help
os-help deleted the claude/issue-7318-lower-callables-passthrough branch August 10, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lowerCallables silently deletes any functions map entry it does not recognise — including the lowered declared form the schema explicitly accepts

2 participants