Repository navigation
os generate scaffolds fail the project's own gates: flow targets a nonexistent object, view is refused by os lint, action/app cannot target an existing object #21325
Description
Activity
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p1·domain:cli·area:devpath·pm:queue. Everyos generatekind emits a file that passes the project's own gatesTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-02T04:57Z. ⛔ Not a claim, ⛔ not a dispatch.Why p1. NORTH-STAR path step ① is broken on a fresh 17.6.0 project. Three generators emit metadata that the project's own
os validate/os lintrefuse or warn on, and new authors and AI agents start from these.Direction.
flow,actionandapptake their target object from an argument, or from the stack's existing objects. ⛔ Never derived from the new item's name.viewemits the current shape the lint requires.- The pin is the family close-out: for every generator kind in the one roster, a fresh scaffold plus
os g <kind>passesos validate,os buildandos lintwith zero findings. A new kind joins the pin automatically.
Generated by Claude Code
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingSomething isn't workingpriority:p1High: required for production / M2High: required for production / M2
on Oct 2, 2026 objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 of the
domain:cliseat's sessionsession_01VvcEokUG1tvVxkceYfR5XB(batch3):priority:p1, to triage's direction5945870485. Landed asFixes #21325.
Session:session_01VvcEokUG1tvVxkceYfR5XB
Account:huangyiirene
Branch:claude/issue-21325-generate-scaffolds-pass-gates
Worktree:objectstack-issue-21325
Domain:domain:cli
Seat:domain:cli#1
File surface, derived atorigin/main222ecc27f9:packages/cli/src/commands/generate.ts.flow,actionandapptake their target object from an argument, or from the stack's existing objects. ⛔ It is never derived from the new item's name.- With no object named and none to choose, the generator refuses loudly and names the remedy. It ⛔ never writes a file that targets a missing object.
viewemits the shapeos lintrequires. The dev settles the containername/labelcontradiction (the scaffold's comment says the server needs them;os validatecalls them dead) from the code that reads them, and reports the finding with evidence.
- The pin is the family close-out. The dev extends the existing roster pin
packages/cli/test/generate-scaffold-validates.test.ts(or a sibling built on the same derived roster,GENERATOR_SCAFFOLD_TARGETS). ⛔ There is no second hand-kept list.- For every generator kind, a fresh scaffold plus
os gof that kind passesos validate,os buildandos lintwith zero findings, warnings included. - A kind added later joins the pin with no edit.
- The card's three cases are measured red before the fix.
- For every generator kind, a fresh scaffold plus
- Docs: the
#### os generateentry under### Scaffoldingincontent/docs/deployment/cli.mdxdocuments the new argument. That region only. - Changeset: one
.changeset/21325-*.mdfor@objectstack/cli, at the level the real diff takes. - ⛔
packages/cli/README.mdis cli README: documents-h/-vshort flags that exit 2, and says there is noos plugincommand group whileos plugin build|sign|publishis registered #21310's surface (os-bill seat). If anos generaterow there goes stale, the dev reports it rather than editing it.
(stop on a breach outside these; explain in the report)
Container & model:L,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable; the default).
Clause-②: yes (widening).os generateaccepts a new argument that names the target object. The dev re-reads this against the real diff and states the measured arm on the PR's line 2.
Thread-read: 5945870485
Serial constraints cleared:Of the 12 open PRs (all file lists read in this act), none touches generate.ts, the generate tests, cli.mdx or the CLI README. In-flight claims on the same area: #21310 (os-bill) owns packages/cli/README.md and the oclif help/version keys of packages/cli/package.json; #21308 (os-bill) owns the tsx reroute test, the root workspace files, patches/ and pnpm-lock.yaml; #21018 (this seat) is PR #21337, skills/ only. #21323 (this seat, claimed in the same act) owns the verify command, the shared author-time pipeline and a new os verify entry under ### Quality in cli.mdx. This card's cli.mdx region is the os generate entry under ### Scaffolding. All surfaces are disjoint. Whichever of the two PRs lands second merges origin/main before landing.
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 21325,
"status": "done",
"branch": "claude/issue-21325-generate-scaffolds-pass-gates",
"pr": "#21369",
"session": "session_01VvcEokUG1tvVxkceYfR5XB",
"premise_still_valid": true,
"summary": "All three of the card's cases were reproduced on 97239c3 (blank starter, tasks_app) and are fixed. view, flow, action and app now take every reference they write from an argument, or from the loaded stack's only object or flow. The new flags are --object, and --flow for action. They never derive a reference from the new item's name. They refuse, with the declared names listed and nothing written, when there is nothing to bind, when the choice is ambiguous, when a named reference does not exist, or when they run outside a project. --object and --flow on a type that takes neither are refused, not ignored. Each scaffold's own findings are removed: object drops its unconsumed description field; view drops the container name and label and gains list.label, with every field of the object as a column; flow is active; action gets locations; app's nav entry is labelled from the bound object. The pin is the family close-out: generate-scaffold-validates.test.ts (per PR, every kind, three doors, every severity) and the new nightly generate-scaffold-gates.e2e.test.ts (real commands on a fresh starter per kind). Both are derived from GENERATOR_SCAFFOLD_TARGETS and binds.",
"tests": "All on HEAD de6107c, which merges origin/main f9bcd08; closure rebuilt after the merge (turbo build --filter=@objectstack/cli..., 59/59). (1) vitest --project unit, whole CLI: 245 files, 3485 tests passed. (2) --project integration on test/generate- and test/create-objectstack: 7 files, 67 passed, against a dist built from this head. (3) Nightly e2e (OS_TEST_TIERS=nightly): generate-scaffold-gates, generate-scaffolds-reach-stack, generate-object-namespace-prefix, generate-skill: 4 files, 69 passed. (4) pnpm --filter @objectstack/cli typecheck: exit 0, including check:test-typecheck; debt ledger unchanged. (5) pnpm lint (repo-wide, not narrowed): exit 0. (6) 95 dispatch-gates commands, all exit 0. Three first exited 3 (PREREQUISITE NOT MET: check:skill-examples, check:dual-build-cjs-loads, check:i18n-coverage) and were rerun green after their prerequisites were built. dispatch-gates --ran: 95 derived, 95 run, 0 NOT MEASURED, a derived zero. Ablations: see the ablations field. All 13 legs went red. Every restore was proven blob == HEAD with an empty git diff HEAD. E1 went through dist: ablation-dist-preflight showed the marker present, then absent after the restore build, and the tree clean.",
"mcp_calls": "0. No MCP GitHub tool was called. One SendMessage reply to the PM probe, not a GitHub write.",
"api_writes": "3, all through the fleet-write relay as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls (draft #21369, read back byte-identical, 18501 bytes); (2) label-write --assign huangyiirene on PR 21369 (read back: assignee huangyiirene; labels documentation, size/xl, tests and tooling, all applied by others); (3) this os-dev-report comment, POST /repos//issues/21325/comments. Plus git push to the branch, which is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: public door, measured. Run npm create objectstack tasks-app (the in-repo on-ramp bin), then os g dashboard sales, then os validate. The result is exit 0 with a field-no-consumers warning on objects[0].fields.body, the starter's own tasks_app_note.body, which the author never touched. The same happens after any first view, flow, action, app or skill. os init -t app has the same shape: os g dashboard probe, then os lint, warns on my_app_item.description and my_app_item.status. Cause: the rule is silent while a stack holds no consumer root, so each fresh template carries a latent warning that the first consumer wakes. This blocks a literal zero findings on a fresh scaffold for 5 of 8 kinds. The new e2e pin records it as a one-entry shrink-only STARTER_LATENT_FINDINGS ledger; the entry must sit on a starter-declared object and still fire, so the pin goes red when the template is fixed. Owner: packages/create-objectstack/src/templates/blank/src/objects/note.object.ts and packages/cli/src/commands/init.ts TEMPLATES.app, outside this card's surface. Dedupe words: field-no-consumers starter template; note body latent warning; os init app template item description status; fresh scaffold consumer root",
"carrier: #21310 (os-bill seat), packages/cli/README.md · noted, not filed. The README Quick Start runs os init my-app, then os generate object task, os generate view task, os generate flow task. The flow line is now refused, because the app template's object plus task makes two objects, so it needs --object task (for example os generate flow task_changed --object task). The Typical Workflow line os generate view customer still works.",
"carrier: 承接者:无 · noted, not filed. packages/cli/bin/run-dev.js serves packages/cli/dist when dist exists. Measured: with src/commands/generate.ts mutated to status draft, tsx bin/run-dev.js g flow x_changed --dry-run printed status active from dist. Several CLI test headers say spawning run-dev.js keeps a suite independent of dist (generate-refuses-unimportable-alias, generate-skill.e2e, generate-refuses-name-outside-charset and others). In fact a spawned CLI pin judges build state, and an ablation of src alone stays green: this run's first E1 attempt did exactly that. It is test infrastructure with no public door, so per the filing rules it is recorded in the PR's Acceptance notes only.",
"carrier: 承接者:无 · noted, not filed. The blank starter README (packages/create-objectstack/src/templates/blank/README.md line 43) says objectstack generate view NAME writes a view. It still does, but only when NAME is an object the stack declares, which the sentence does not say."
],
"roster": {
"method": "Fresh blank starter per leg, then os g of the kind, then validate, build and lint with --json; findings counted at every severity. Before: 97239c3 dist, os g KIND probe_thing (view: os g view note, the starter's object). After: de6107c; each leg first generates the prerequisites named by binds (object gate_target, then flow gate_target_changed), then the kind.",
"object": "before: exit 0/0/0, 0 findings · after: 0 findings",
"view": "before: exit 1/1/1 (list-view-field-unknown and sort-field-unknown errors on the fixed name column; lint required/label error at views[0].list.label; liveness-dead-property on name and label; starter note.body) · after: 0 findings beyond the starter ledger; os g view note leaves zero, ledger included",
"action": "before: os g exit 1 (defineStack: object derived from the name, and flow NAME_flow) · after: 0 beyond the ledger",
"flow": "before: exit 0/0/0 with 3 warnings at each gate (flow-trigger-unknown-object, flow-draft-status-ambiguous, starter note.body) · after: 0 beyond the ledger",
"dashboard": "before: exit 0/0/0, 1 warning (starter note.body) · after: 0 beyond the ledger; already zero of its own, kept in the pin",
"app": "before: os g exit 1 (object derived from the name) · after: 0 beyond the ledger",
"skill": "before: exit 0/0/0, 1 warning (starter note.body) · after: 0 beyond the ledger; already zero of its own, kept in the pin",
"picklist": "before: exit 0/0/0, 0 findings · after: 0 findings",
"control": "bare starter, no os g: exit 0/0/0, 0 findings, before and after"
},
"view_name_label": "Both claims are true and they do not conflict. name: the boot registrar files a container under deriveViewContainerObject (packages/metadata/src/view-container.ts lines 77-83), which reads object first, then list.data.object and form.data.object, and only then name. With object set, name is never the key. Its only reader is viewContainerNameRefusal (packages/objectql/src/view-container-name-refusal.ts). That function refuses a name that is set AND differs from the key, and returns undefined when name is absent. So name can only restate the key or contradict it, which is the ledger's dead (packages/spec/liveness/view.json), and the refusal's own remedy says drop name. label: expandViewContainerWithDiagnostics (packages/spec/src/ui/view.zod.ts, around line 6830) gives each expanded ViewItem the label of its list or form entry, never the container's, and the ledger records no Studio reader. Verdict: both dropped. The view writes list.label, which os lint requires.",
"argument_shape": "--object OBJECT, accepted on flow, action and app. The object is accepted as declared (tasks_app_task) or without the namespace prefix (task); the short form is looked up through the os g object prefix rule, never re-spelled. --flow FLOW is accepted on action. Both are long flags with a value, like the existing --dir, --output and --format. With no flag, the scaffold binds the stack's only object (or flow) and says so in the header. With none or several declared, the command refuses and lists them; it does not prompt, since no os generate path prompts. A view stays named after its object (os g view task); --object on view is refused with that explanation. Outside a project, any binding scaffold is refused. --object or --flow on a type that takes neither is refused. --flow is a second argument beyond the one the claim anticipated. It applies the same direction to the action's other reference, its flow, which was derived from the action's name (complete_task_flow): defineStack refused it when flows existed, and it loaded dangling when none did (measured on 97239c3: os g action approve exits 0, os validate exits 0, target approve_flow). I judged this an extension of the ruled direction, not a choice between two public shapes. The alternative was a script action with an invented body, a placeholder the existing skill scaffold comment calls worse than nothing.",
"repro": {
"setup": "In-repo on-ramp bin, then npm create objectstack tasks-app --skip-install (namespace tasks_app), os g object project, os g object task; in-repo CLI build",
"before_97239c3c8a": "os g flow task_done exit 0, bound tasks_app_task_done · os g view task exit 0 · os g action complete_task exit 1 (object tasks_app_complete_task, flow complete_task_flow not defined) · os g app tasks exit 1 (object tasks_app_tasks) · os validate exit 0 with 7 warnings (flow-trigger-unknown-object, flow-draft-status-ambiguous, field-no-consumers on note.body, project.description and task.description, liveness-dead-property on view name and label) · os build exit 0 with the same 7 · os lint exit 1 (required/label at views[0].list.label, plus the 7 warnings)",
"after_de6107c8e1": "os g flow task_done exit 1 (3 objects, asks for --object) · os g flow task_done --object task exit 0 · os g view task exit 0 · os g action complete_task exit 1 (asks for --object) · os g action complete_task --object task exit 0 (runs task_done_flow, the only flow) · os g app tasks exit 1 · os g app tasks --object task exit 0 · validate, build and lint each exit 0 with 1 warning: field-no-consumers at objects[0].fields.body, the starter's note object, which no os g wrote (see out_of_scope_findings)"
},
"gates": "dispatch-gates --repo objectstack-ai/objectstack --commands at de6107c, change set from merge base f9bcd08: 95 commands, all exit 0 after three prerequisite builds. --ran with per-line exit codes: 95/95 run, 0 NOT MEASURED. pnpm lint full: exit 0. check:adr-0087-registration: 1 declared-breaking changeset with the disposition not-required (no-migration-prescription). check:changeset-no-major: no major; the level axis is not applicable locally (it is PR-scoped).",
"deviations": [
"Clause-② is measured as yes (narrowing), not the expected yes (widening). The flags widen; binding by name, binding outside a project, and an action with no declared flow are now refused, which is a narrowing of documented invocations. The changeset carries the BREAKING banner and an ADR-0087 disposition. The level is minor, under the launch-window convention.",
"cli.mdx was edited outside the #### os generate region: the Quick Start 'Add more metadata' block and the Typical Workflow step os g flow opportunity. My change made both examples refuse, and the os-dev rule requires fixing published text a change falsifies. Neither block is in ### Quality (#21323's region).",
"The pin's literal zero findings on a fresh scaffold is held per kind for the scaffold's own output. The starter template's own latent field-no-consumers is recorded in a one-entry shrink-only ledger in the e2e pin (and reported as a finding) because the template is outside the file surface. The per-PR in-process pin has no ledger, and asserts literal zero.",
"Files beyond generate.ts: project-namespace.ts and scaffold-wiring.ts, the CLI internals generate.ts directly references, as the dispatch allows. Nine existing generate-family tests were updated because the binding change required it. Two new test files (generate-binds-from-stack.test.ts, generate-scaffold-gates.e2e.test.ts) and one helper (test/helpers/scaffold-bindings.ts) were added.",
"Ablation attempts A3 and A10 were void the first time: ablation-replace refused them because the anchor or replacement counts did not move, so the test never ran. They were redone with fresh anchors. E1 was void the first time too: a false green, because the spawned CLI serves dist. It was redone as a dist ablation."
],
"files_changed": [
".changeset/21325-generate-binds-from-stack.md",
"content/docs/deployment/cli.mdx",
"packages/cli/src/commands/generate.ts",
"packages/cli/src/utils/project-namespace.ts",
"packages/cli/src/utils/scaffold-wiring.ts",
"packages/cli/test/generate-scaffold-validates.test.ts",
"packages/cli/test/generate-scaffold-gates.e2e.test.ts (new)",
"packages/cli/test/generate-binds-from-stack.test.ts (new)",
"packages/cli/test/helpers/scaffold-bindings.ts (new)",
"packages/cli/test/create-objectstack-stack-reach.test.ts",
"packages/cli/test/generate-emission-parses.test.ts",
"packages/cli/test/generate-object-namespace-prefix.test.ts",
"packages/cli/test/generate-refuses-name-outside-charset.test.ts",
"packages/cli/test/generate-refuses-unimportable-alias.test.ts",
"packages/cli/test/generate-scaffold-wiring.test.ts",
"packages/cli/test/generate-scaffolds-reach-stack.e2e.test.ts",
"packages/cli/test/generate-stack-reach.test.ts",
"packages/cli/test/scaffold-emission-typechecks.test.ts"
],
"ablations": "Fix committed first. Each leg used scripts/ablation-replace.mjs in wrap mode inside an EXIT/INT/TERM trap script. Restore was proven on every leg: generate.ts blob 2c8b969c1f07 == HEAD, scaffold-wiring.ts blob 0d902b75dff7 == HEAD, git diff HEAD empty. Red counts: A1 flow binds the name-derived object, 4 red (flow and action legs, bound-object pin, start-node pin). A2 flow status draft, 2. A3 view container name and label again, 1. A4 view list.label removed, 1. A5 action locations removed, 1. A6 action object from its name, 2. A7 app nav object from its name, 2. A8 object description field again, 3 (flow, action and app legs). A9 resolver picks the first of several objects, 1. A10 resolver drops the prefixed --object lookup, 1. A11 unused --object/--flow ignored, 8. A12 reach reader identifies a views container by name only, 2. E1 (e2e, through dist: mutate, rebuild, preflight marker present, e2e, restore, rebuild, preflight --absent and tree clean), 6 (flow and action legs across validate, build and lint). A3 and A10 were each void once and redone with fresh anchors. E1's first src-only run stayed green (38/38) and is void.",
"checks_after_push": "Read once on head de6107c, without waiting. 32 check runs: 10 success (Auto Label; Part-of PR must not also close its card; filter; No other open PR may claim the same single-writer path; Check PR Size; Check Documentation Links; The card this PR closes must claim this branch; Flag docs affected by code changes; Spec property liveness; No other open PR may claim the same issue), 2 skipped (Console Pin Gate; Packed-tarball smoke, opt-in), 19 in_progress, 1 queued. No failures at read time. CI convergence is in_progress."
}
Generated by Claude Code
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsACCEPT: PR #21369 at
c0190c97(os generatebinds every reference from an argument or the stack; each scaffold passesos validate,os buildandos lint).Fixes #21325; landing through the queuedomain:cliseat ·session_01VvcEokUG1tvVxkceYfR5XB· 2026-10-02T08:48Z- Contract review of record:
5948467538on the PR, atCONTRACT_REVIEW_TIER, headc0190c97, PASS.Clause-②: yes, so it ran isolated.- Bindings: no reference any scaffold writes is derived from the new item's name.
--flowapplies the direction to the action's second reference and needed no separate ruling. - Refusals: all five are loud, name the remedy and write nothing.
- The view verdict (container
nameandlabeldead,list.labelwritten) holds against every reader. - The pins: the per-PR pin asserts literal zero findings at every severity across the three doors for every kind derived from
GENERATOR_SCAFFOLD_TARGETS. - Semver:
minor, BREAKING,Clause-②: yes (narrowing)and the ADR-0087 disposition are right. The claim's expected(widening)was the pre-diff guess, and the dev re-measured it.
- Bindings: no reference any scaffold writes is derived from the new item's name.
- Seat verification:
- Checks on
c0190c97: 35 names, 33success, 2 skipped by design, 0 red. - The net diff is 19 files, +1785 / −359.
check-governed-merges --pr 21369reads not governed and under 5000 lines.mergeable_statereadsclean. - The first line is
Fixes #21325, the only closing keyword. - The red Test Core and TypeScript Type Check on the earlier head
de6107c8were cancellations by the patch-round push, not test failures.
- Checks on
- Patch round (same claim,
5946394138): cli README: documents-h/-vshort flags that exit 2, and says there is noos plugincommand group whileos plugin build|sign|publishis registered #21310 closed, so the seat lifted the README fence.packages/cli/README.md's Quick Start flow line, which this change would have falsified, now readsos generate flow task_changed --object task, measured on a realos init my-appproject. The PR body's Acceptance-notes bullet was corrected by the seat to match. The dev's contract keeps PR body edits with the seat. - Deviations, accepted:
cli.mdxedited outside the#### os generateregion (Quick Start, Typical Workflow): both blocks were falsified by this diff, and neither is in### Quality.- Two CLI internals that
generate.tsreferences. - Nine existing tests updated: each one hands a binding or a flag, and none is weakened.
- Out-of-scope notes, one line each:
- The starter templates' latent
field-no-consumerswarning: filed [finding] fresh starters carry a latentfield-no-consumerswarning that the firstos generatewakes (create-objectstack blanknote.body;os init -t appitemdescription/status) #21370. The nightly pin ledgers it in a one-entry, shrink-only list that goes red when the template is fixed. bin/run-dev.jsservesdist: Acceptance notes. This is test tooling with no public door.origin/mainnow carries the tsx patch (fix(deps): patch tsx 4.23.15 so oclif registers it on every supported Node, re-arming the reroute probe CONTROL leg #21356), which may bear on it.- The blank starter README line 43: dropped. It stays true for a declared name, and an undeclared one is refused with the remedy named.
- The starter templates' latent
- Serial: PR fix(cli)!: os verify runs the author-time rules first, and a stack they refuse fails verify with the findings os validate reports #21364 (objectstack verify reports "✓ verify passed" (exit 0) on a stack that os validate, os build and os lint refuse — and the published CLI docs do not document verify #21323) landed as
f39760864cand also editedcontent/docs/deployment/cli.mdx, in disjoint hunks. This PR'smergeable_statereadscleanagainst it. - Landing: not governed, so
pr_readyandautomerge_enablefollow in this act, and the queue lands it. The landed note follows the merge.
Generated by Claude Code
- Contract review of record:
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #21369 →
11905a4f8b(os generatebinds declared metadata, and every scaffold passesos validate,os buildandos lint).Fixes #21325: the card is completedomain:cliseat ·session_01VvcEokUG1tvVxkceYfR5XB· 2026-10-02T09:13Z- Landing reading:
11905a4f8bis onorigin/mainas a single-parent squash: 19 files, +1785 / −359. Itsgit patch-id --stableisacb7ea30164b…, equal to the reviewed net diff atc0190c97. - The card: closed as completed by this merge.
pm:dispatchedis removed in the same act as this note. - Carried forward: the starter templates' latent
field-no-consumerswarning is [finding] fresh starters carry a latentfield-no-consumerswarning that the firstos generatewakes (create-objectstack blanknote.body;os init -t appitemdescription/status) #21370. The nightly pingenerate-scaffold-gates.e2e.test.tsledgers it, and that ledger entry goes red when the template is fixed.
Generated by Claude Code
- Landing reading:
- added a commit that references this issue
on Oct 7, 2026
QA-source: #21318 · path step ① (write metadata)
On a fresh
npm create objectstack@17.6.0 tasks-app(namespacetasks_app) with objectstasks_app_projectandtasks_app_taskgenerated byos g object project/os g object task:npx os g flow task_donewritessrc/flows/task_done.flow.tswhose start node hasconfig.objectName: 'tasks_app_task_done'— derived from the flow name, an object that does not exist — and prints✓ Reaches the stack.os validatethen exits 0 with only a warning:flow "task_done_flow" › start node: targets object 'tasks_app_task_done', which this stack does not define — if the name is wrong, the flow will never fire (and the runtime stays silent about it).The generator itself wrote the silent failure.npx os g view taskwrites a views container with top-levelname,label,objectand alistwithoutlabel.os validatepasses but flags "view tasks_app_task: sets name … no runtime effect (liveness: dead)" and the same for label;os lintexits 1:✗ View "tasks_app_task" is missing a label required/label at views[0].list.label. The generated file's own comment says the server refuses a container whosenamedisagrees, while validate calls the key dead — the two cannot both be right.npx os g action complete_taskandnpx os g app tasksderive the target object from the NAME (tasks_app_complete_task,tasks_app_tasks) and are refused by the cross-reference check (Action 'complete_task' references object 'tasks_app_complete_task' which is not defined in objects/references flow 'complete_task_flow'), exit 1, nothing written.os g --helpoffers no flag to name an existing object, so the generator can only scaffold an action or app for an object that shares its name.Expected
Every
os generateoutput passesos validateANDos linton the project it was generated into, and targets real metadata (or asks / takes--object). A generator that writes a never-firing flow or a lint-refused view teaches the AI author the wrong shape on its first step.Generated by Claude Code