T-PJ8G-the-tool-and-product-tiers-get-their-gates
State: closed/done · Impact: medium · Complexity: medium
Three tiers of the moon graph carry no gate at all. sdlc and
determined-root are layer: tool and match neither ts-lib.yml nor any
other aspect, so they have no check, test, format, format:check or
lint task of their own — the root project compensates by widening its own
check/test inputs to reach directly into solutions/ontological. The 21
untagged solutions/determined/products/* and the experience layers under
solutions/determined/experiences/* are not registered as moon projects at
all, so they carry no gate either, even though they hold real source files
that need formatting and linting. And one bun install invocation is
hand-typed in 9 moon.yml files with two silently different shapes. This
task gives the tool tier its own gates, gives the untagged product/experience
tier the two verbs it can actually support, and collapses the install
duplication into shared aspects — closing the last three gaps in the task
vocabulary before the conformance guard (task 11) can assert the rule
end to end.
| Location | Role today |
|---|---|
moon.yml | Root project, layer: 'tool'. Its check task inputs list solutions/ontological/**/*.ts directly (via tsconfig.json’s own include) and its test task command is bun test solutions/ontological scripts — the root project is doing sdlc’s typecheck and test run for it. |
solutions/ontological/moon.yml | sdlc project, layer: 'tool'. No check, test, format, format:check or lint task; only a doc-site task. |
solutions/determined/moon.yml | determined-root project, layer: 'tool'. No check, test, format, format:check or lint task; its package.json typecheck script (moon run product-workbench:check product-agent-pants:check) is invoked by hand, never by a moon task. |
.moon/tasks/nuxt-product.yml | Gives check to the 3 nuxt-product-tagged products (product-workbench, product-agent-pants, product-agent-chat) only. Documents that those 3 together compose every live experience, so checking the rest would re-prove the same files. |
.moon/workspace.yml | Registers only the 3 nuxt-product-tagged products plus a curated list of solutions/determined/apps/* and packages/* as explicit sources:. No glob or source covers the other 21 solutions/determined/products/* directories or solutions/determined/experiences/* — they are not moon projects at all today. |
apps/legacy-polish/moon.yml | polish project. Hand-writes install: command: 'bun install' with cache: false, runFromWorkspaceRoot: true and mutex: 'root-bun-install' — the same shape as root’s, because its src-nuxt/ is a root Bun workspace member. |
sites/df-docs/moon.yml, packages/ts/intersect/docs-site/moon.yml, packages/ts/flowline/docs-site/moon.yml, packages/ts/waypost/docs-site/moon.yml, solutions/augmented/apps/augmented_dot_com/moon.yml, solutions/augmented/apps/augmented-books/moon.yml, solutions/augmented/apps/vimit/moon.yml | Each hand-writes install: command: 'bun install' with cache: false only — no runFromWorkspaceRoot, no mutex. Correct as written (root package.json workspaces excludes augmented-books, vimit and augmented_dot_com by name, and never lists sites/* or the three docs-site directories), but the shape is retyped by hand in 7 places instead of shared. |
Proposed
Section titled “Proposed”sdlc and determined-root each carry their own check, test, format,
format:check and lint tasks — reached through a new layer: 'tool'
aspect for the two verbs every tracked manifest gets, plus project-level
check/test tasks for the two verbs a tool-tier project can genuinely
support. Root’s own check/test inputs narrow to drop the direct reach
into solutions/ontological, depending on sdlc:check/sdlc:test instead
— the same aggregation shape check already has in the target vocabulary.
determined-root:check aggregates its existing per-product nuxt-product
checks plus its own fmt-check/lint, so it asserts real coverage rather
than a typecheck it cannot perform standalone.
The 21 untagged solutions/determined/products/* and the experience layers
under solutions/determined/experiences/* are registered as moon projects
and carry format, format:check and lint — never check — via a new
tag-based aspect, sibling to nuxt-product.yml. nuxt-product.yml’s own
reasoning (checking one layer in isolation drops the generated types and
reports errors that are not real) is why this task never adds a check
task to them.
The bun install command exists in exactly two places: a
layer: 'tool'-adjacent tag aspect for the root-anchored shape (root,
polish — the two Bun-workspace-member installs needing the shared
root-bun-install mutex), and a second tag aspect for the standalone shape
(df-docs, the three docs-site projects, augmented_dot_com,
augmented-books, vimit — projects with their own lockfile, no mutex
needed). No project moon.yml hand-writes command: 'bun install' any
more.
Approach
Section titled “Approach”- Add
.moon/tasks/tool.yml,inheritedBy: { layer: 'tool' }, givingformat,format:checkandlint, each delegating to the `bun run - Give
solutions/ontological/moon.ymlits ownchecktask (the samebunx tsc --noEmitcommand root runs today, sincesolutions/ontological,tests/andscripts/still compile as onetsconfig.jsonprogram — this is not a per-directory split, just moving where the task is declared) andtesttask (bun test solutions/ontological scripts …, root’s command verbatim). Givesolutions/determined/moon.ymlachecktask that depends onproduct-workbench:check,product-agent-pants:checkandproduct-agent-chat:checkplus its own~:fmt-check/~:lint— the Rustcheckshape (deps-only aggregate), not a typecheck it cannot run itself. - Update root
moon.yml:checkandtestgaindeps: ['sdlc:check']/deps: ['sdlc:test']and drop thesolutions/ontological/**/*entries from theirinputs:(the dependency edge now carries the staleness signal). Leavedashboard-client:checkand thepackages/ts/**/*.tsedge glob as they are — a different, already-documented gap. - Add
.moon/tasks/determined-product.yml(or equivalent name), anuxt-product-adjacent aspect keyed on a new tag (e.g.determined-app) givingformat,format:check,lintand nothing else. In.moon/workspace.yml, register the 21 untaggedsolutions/determined/products/*directories and thesolutions/determined/experiences/*directories as moon projects and apply the tag. Verify against real moon behavior whether a baresolutions/determined/products/*glob double-registers the 3 already-explicitproduct-*sources under a second folder-derived id (the documentedpolish/legacy-polishtrap in.moon/workspace.yml) — if it does, register the 21 as explicitsources:entries instead of a glob, or split the glob to exclude the 3 tagged directories. - Add
.moon/tasks/bun-workspace-install.yml(tag, e.g.bun-workspace-install) with the root/polishshape (cache: false,runFromWorkspaceRoot: true,mutex: 'root-bun-install') and.moon/tasks/standalone-install.yml(tag, e.g.standalone-install) with the simpler shape (cache: falseonly). Apply the first tag torootandpolish, the second todf-docs,intersect-docs,flowline-docs,waypost-docs,augmented_dot_com,augmented-booksandvimit. Delete each project’s localinstall:block. - Run
moon task <target>(prints the resolved command) againstsdlc:check,determined-root:check, one collapsedinstalltarget of each shape, and one newly-registered product’sformat— confirming delegation actually happened, per the plan’s verification method.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
moon.yml | modify | Narrow check/test inputs; add deps on sdlc:check/sdlc:test; replace the local install task with the bun-workspace-install tag. |
solutions/ontological/moon.yml | modify | Add check/test tasks; apply layer: 'tool' aspect (already the declared layer) for format/format:check/lint. |
solutions/determined/moon.yml | modify | Add check (deps-only aggregate) task; pick up format/format:check/lint from the tool aspect. |
apps/legacy-polish/moon.yml | modify | Replace the local install task with the bun-workspace-install tag. |
sites/df-docs/moon.yml | modify | Replace the local install task with the standalone-install tag. |
packages/ts/intersect/docs-site/moon.yml | modify | Replace the local install task with the standalone-install tag. |
packages/ts/flowline/docs-site/moon.yml | modify | Replace the local install task with the standalone-install tag. |
packages/ts/waypost/docs-site/moon.yml | modify | Replace the local install task with the standalone-install tag. |
solutions/augmented/apps/augmented_dot_com/moon.yml | modify | Replace the local install task with the standalone-install tag. |
solutions/augmented/apps/augmented-books/moon.yml | modify | Replace the local install task with the standalone-install tag. |
solutions/augmented/apps/vimit/moon.yml | modify | Replace the local install task with the standalone-install tag. |
.moon/workspace.yml | modify | Register the 21 untagged solutions/determined/products/* and the solutions/determined/experiences/* directories as moon projects, tagged for the new determined-product aspect. |
.moon/tasks/tool.yml | new | layer: 'tool' aspect: format, format:check, lint. |
.moon/tasks/determined-product.yml | new | Tag aspect for untagged determined products/experiences: format, format:check, lint only. |
.moon/tasks/bun-workspace-install.yml | new | Tag aspect for the root-anchored install shape (mutex + runFromWorkspaceRoot). |
.moon/tasks/standalone-install.yml | new | Tag aspect for the standalone install shape (no mutex). |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
moon query tasks --jsonreports a non-nullsdlc:check,sdlc:test,sdlc:format,sdlc:lint,determined-root:check,determined-root:formatanddetermined-root:lint— all absent today. - AC-2:
moon run sdlc:check,moon run sdlc:testandmoon run determined-root:checkeach exit 0. - AC-3:
grep -rL "^tags:" --include=moon.yml -l "command: 'bun install'"finds no projectmoon.yml— the literal command exists only inside.moon/tasks/bun-workspace-install.ymland.moon/tasks/standalone-install.yml. - AC-4:
moon query projects --json | jq '.projects | length'is at least 43 higher than today’s count (21 untagged products + the registered experience layers). - AC-5:
moon query tasks --jsonshowsformat,format:checkandlintfor a sampled untagged product (e.g. onesolutions/determined/products/*directory outside the 3nuxt-product-tagged ones) and nochecktask for it. - AC-6:
moon run :fmt-checkandmoon run :linteach returnsdlcanddetermined-rootin their target list (grep the run output), where today neither appears.
Out of scope
Section titled “Out of scope”- Rewriting
ts-lib.ymlitself to delegate throughbun run—T-0DSA. - The Rust aspect’s per-crate override collapse —
T-7VPK. - The repo-wide prettier reformat and the lefthook auto-format wiring.
- The conformance guard script (
scripts/guard-project-shape.ts) —T-0G2O. - Deleting app-local
justfile/Makefilerunners —T-TB73. - Adding
typecheckto the publish-channel standalone lane —T-ZFM9.
Dependencies
Section titled “Dependencies”T-VAF5— the standard defining the baseline vocabulary and the which-verb-which-project rule this task applies to the tool and product/experience tiers.T-076AandT-9FH9— the Layer A tasks that add theformat,format:checkandlintpackage.jsonscripts this task’s moon aspects delegate to (solutions/ontologicalandsolutions/determinedboth fall underT-9FH9’s scope).
Depends on
Section titled “Depends on”T-VAF5-a-standard-for-the-baseline-task-vocabulary, T-076A-the-script-vocabulary-lands-in-packages-apps-and-sites, T-9FH9-the-script-vocabulary-lands-across-solutions