Skip to content

T-4VNC-learning-p1-scaffold-solution

State: open/ready · Impact: high · Complexity: medium

Stand up the empty shape D-LIRI decides: a reader experience, a thin product and two package stubs, all inside solutions/determined/, built on the frame and determined’s native vault APIs only. Two of the determined-local packages gain a consumer outside the solution here, which is D-0001’s promotion trigger, so they move to packages/ts/ in the same change. Every later phase lands inside this scaffold.

LocationRole today
solutions/determined/packages/vault-platform-client/@determined/vault-platform-client: the manifest and product types plus the ontogen-generated transport. Written by crates/determined-platform’s build.rs
solutions/determined/packages/code-editor/@determined/code-editor: CodeSurface, a themed CodeMirror 6 layer with an extensions prop. Tier 0
solutions/determined/packages/obsidian-astro/@sksizer/obsidian-astro: vault to Astro content collections. Tier 0
solutions/determined/products/fitness/The reference product shape: extends @sksizer/app-frame, one experience, @determined/ui; ssr: false; no shell, no vaults layer
solutions/determined/experiences/fitness/app/plugins/register.tsThe reference module registration: registerModule(defineModule(...))
dev-ports.yamlThe port registry. Books takes the next free number in determined’s 15000-15999 band
.moon/workspace.ymlProject globs and the explicit solutions/determined/packages/* sources
docs/LIBRARIES.mdThe tier roster; promoted packages move from the tier 0 table to the tier 1 table
solutions/determined/
packages/book-model/ @determined/book-model — note kinds, exercise specs, contract corpus (stub)
packages/runners/ @determined/runners — plain Vue, no Nuxt (stub)
experiences/learning/ @determined/exp-learning — registers module `learning`, scope `scoped`
products/books/ extends [app-frame, exp-learning, ui]; Tauri crate is the three-line main
packages/ts/code-editor moved, name unchanged
packages/ts/obsidian-astro moved, name unchanged

@determined/vault-platform-client stays where it is: it is a build artifact of crates/determined-platform, so it belongs beside the crate that writes it.

The experience renders one page: the vault roster through vaultGetVaults, one vault’s doc list through vaultNoteGetDocs, and one note through vaultNoteReadDoc into MdViewer. That proves the native-API path end to end before any learning code exists. The product builds for web and for Tauri.

  1. git mv code-editor and obsidian-astro to packages/ts/; update the moon sources, scripts/guard-raw-palette.ts and docs/LIBRARIES.md. Names are unchanged, so no import moves.
  2. Create the four projects above. The root workspaces and the moon experience/product globs already cover solutions/determined/; only the two packages need explicit moon sources, and Cargo.toml’s solutions/determined/products/*/src-tauri member already covers the books crate.
  3. Write the experience: register.ts after fitness’s, one page under /apps/learning, useTransport<Transport>() for reads. No server routes, no new determined-platform code.
  4. Write the product after products/fitness, with homeExperience: 'learning', the determined deep-link scheme, and the next free port in the determined band.
  5. Verify: bun install --frozen-lockfile; moon run product-books:build for web and cargo build -p product-books for Tauri; the determined products still build with the promoted packages.
AreaNote
solutions/determined/packages/code-editor/git mv to packages/ts/code-editor/
solutions/determined/packages/obsidian-astro/git mv to packages/ts/obsidian-astro/
packages/ts/code-editor/Promoted package, name unchanged
packages/ts/obsidian-astro/Promoted package, name unchanged
solutions/determined/packages/{book-model,runners}/The two stubs
solutions/determined/experiences/learning/The reader layer
solutions/determined/products/books/The product and its Tauri crate
.moon/workspace.ymlTwo package sources; drop the two promoted ones
dev-ports.yamlproduct-books in the determined band
docs/LIBRARIES.mdTwo rows move to tier 1; a determined row for the two stubs
solutions/determined/products/README.mdThe books row and what it extends
  • AC-1: moon run product-books:build and cargo build -p product-books both pass; the app opens, lists the vaults in the roster, and renders one note.
  • AC-2: git grep 'solutions/determined/packages/\(code-editor\|obsidian-astro\)' outside docs/planning/ returns nothing; determined products build unchanged.
  • AC-3: solutions/determined/experiences/learning/ reads the vault API only through @determined/vault-platform-client and adds no file under solutions/determined/crates/.
  • AC-4: bun install --frozen-lockfile passes at root.
  • Any learning content, exercise, or progress code. Later phases.
  • @determined/shell. The product runs on the frame alone, as fitness does.
  • A solutions/learning/ tree. D-LIRI places books inside determined.
  • none
  • D-LIRI, the decision this scaffold realizes.

Captured by /sdlc:task-work on 2026-09-13. PR: pending.

  • AC-1: agent-manual — moon run product-books:build (nuxt generate, prerenders /apps/learning), cargo build -p product-books and moon run product-books:check all pass. The app was not launched; “opens, lists vaults, renders a note” is proven by build and typecheck only. deferred-user for the running window.
  • AC-2: auto — grep for the two old package paths outside docs/planning/ returns nothing (bun.lock and the system-graph lab fixtures excluded); moon run product-fitness:build passes.
  • AC-3: auto — the experience imports @determined/vault-platform-client and nothing else from determined; no file added under solutions/determined/crates/.
  • AC-4: auto — bun install --frozen-lockfile exits 0.
  • The fitness product and experience were a complete template: product manifest, transport plugin, Tauri crate shape and moon tags copied across with only names and ports changed.
  • The generated transport’s method names were enough to write the page without touching the shell or the scope machinery.
  • Pre-commit took 4 to 12 minutes per commit, almost all of it check_skill_docs.ts rendering every mermaid block through a headless browser regardless of what is staged — scope that gate to staged skill docs. → T-JL2Q-scope-skill-docs-gate-to-staged
  • sdlc quality run --diff-against-baseline resolves .sdlc/quality-baselines/ against the worktree while baseline capture writes it to the main checkout, so the file had to be copied by hand — resolve the baseline directory against the common git dir. → T-OLTA-task-work-step7-worktree-baseline-dir
  • Two live relative paths (tests/ui/mvux/vault-nodes.vaults.e2e.ts, experiences/fitness/tests/admin-registry.test.ts) resolved into the moved package by .. segments and were invisible to a path grep — a move recipe should grep for resolve( and ../ reaches into the moved directory, or the repo should ban cross-package relative reaches. → T-U2JP-guard-cross-package-relative-reaches
  • The system-graph lab fixtures (repo.json, repo-external.json, moon-facets.json) now describe a stale layout; regenerating is a 37,000-line diff that also invalidates hand-written counts in lab/fixtures/index.ts — a separate refresh chore, and a note on the fixtures README about when the snapshot is meant to be retaken. → T-ERF6-refresh-stale-system-graph-fixtures
  • scripts/guard-project-shape.ts is already red on main (product-suspenders, product-system-graph match no aspect), so the guard cannot ratchet — pre-existing, needs its baseline updated. → T-356Q-fix-guard-project-shape-baseline

← Back to Tasks