Snapshot: 2026-06-14. A point-in-time handoff for the next agent. The durable tracker is BACKLOG.md; update it as you go and delete this file when its plan is stale.
SpecKit is a spec-driven framework: a Go binary (specify) that is both the engine
(scan/verify/lock/drift/cover/parity/gate) and the project bootstrapper.
Everything needed to onboard an existing repo now exists — the engine reads
trove's spec library clean (specify scan → clean), and specify target register records an existing member as a target without scaffolding. The next
arc is the actual conversion of ~/Developer/Projects/trove
(a Workbench-shaped monorepo). Its members:
| member | stack | format / bindings |
|---|---|---|
cmd/troved, cmd/tangerined |
go-service | gotest · scoped |
cmd/trove-transcode |
go CLI | gotest · scoped |
apps/trove, apps/tangerine-dashboard |
web | junit · scoped |
packages/services, packages/tangerined-contract |
npm-package | junit · scoped |
The conversion work, in order:
- Register every member with its real wiring:
specify target register <name> --stack <s> --dir <path> [--command/--report/--source/--bindings …]. Manifest stacks (web, go-service) seed the wiring; the others take explicit flags. - The open engine question — multi-dir
source. A smoke-test (register troved --source cmd/troved→verify) showed trove's bound tests spancmd/trovedandinternal/(shared packages), and a target'ssourceis a single dir today. Decide + implement: either a targetsourcethat spans multiple dirs, or a convention for shared-internal/bindings. This is the first real blocker. - Reconcile scenario↔test ids until each target verifies green (the smoke-test
surfaced
scenario.library-scan.*dangling/unjoinable under a too-narrow scope). - Then: the protocol
x-speccoverage reader (verify trove's 17 protocol contracts against the OpenAPI — today they scan-clean + drift-track only) and the product-rollup render (per-productcover/parity— trove is multi-product: trove · tangerine). - CI: the gate action is dormant until the first release tag (P6); trove's CI
needs the released action (or a pinned binary) to run
scan → gate → verify.
Don't pollute the real trove while iterating — register writes only
.speckit/specs.json (+ any report files the test command emits); clean them up,
or work in a throwaway checkout.
- P1–P2 ✅ — PR gating + the entire GitHub-native core + agent memory.
- P3 web scaffold ✅ (complete for now) — green-on-arrival TanStack Start across
{cloudflare,node} × {convex,drizzle,none}, with--withfeatures clerk · tiptap · posthog · email · stripe. UI comes from racket-ui (markmals/racket-ui) via the shadcn CLI — shadcn-native@/*→member-root layout,components.jsonwith the@racket-uiregistries map (racket-ui's per-itempublic/rdistribution published in racket-ui#1). Slice 5 shipped a base.vscode/(oxc/tsgo/Tailwind-cvaIntelliSense) + the web-development pack refresh; Varlock deferred. Recipe + gotchas:.claude/memory/rac-ui-shadcn.md,.claude/memory/web-scaffold.md. - go-service stack ✅ (trove-parity complete) — members compose into ONE repo-root
go.mod(sharedModule: each acmd/<name>sharinginternal/; module path from the git remote), plus three--withfeatures matching troved's shape: openapi (contract-first via oapi-codegen strict-server +x-spec), sqlite (glebarez store + embedded migrations + flag/env config), client (boundedhttp.Client+GetJSON/APIError/URL-sanitization + afakeServerhttptest harness).target add … --with openapi --with sqlite --with clientis the full troved shape, green on arrival. specify target register✅ — onboard an existing member as a target (no scaffolding); the enabler for the trove conversion above.- Tier 1 — trove engine adoption ✅ —
protocolkind; filename rule (id-tail and full-id stems); nested### Scenarioparsing; Go + generic// [scenario.id]binding reader;gotestformat (go test -json); per-targetbindings: scopedmode. - P5 docs ✅ — harness & usage guides (
docs/harnesses/*,docs/usage/*).
mise run cibefore every push (build → vet → test + gofmt). The gate.- Golden init manifests: any change to projected assets (
templates/{skills,rules,agents, commands,memory}/or an adapter's paths) drifts them —go test ./internal/project -run TestInitGoldenTrees -update, then eyeball the diff. - Scaffolds are prototype-first / resolve-by-running. Build the real app green in a
throwaway
mktemp -d(pnpm add/go getresolve versions; run the quality checks +vite build/go build/go testuntil green), THEN templatize. Green-on-arrival is verified by a freshspecify target add <name>→specify verify+ the quality checks — never asserted. Verify combos SERIALLY — the web type-awaretsgolintlint flakes (SIGSEGV / falseTS2307) under parallel-install contention. - Offline determinism line (core invariant):
internal/engine+internal/specmodelnever importinternal/githuband never touch the network. All GitHub/network code lives ininternal/github, imported only bycmd/specify. - PR-per-change. Branch off
main,mise run ci, open + merge a PR. The fork ismarkmals/spec-kit— pass-R markmals/spec-kittogh(bareghresolves the upstreamgithub/spec-kit). Mark's standing pref: auto-merge green PRs (build ×3 OSes + selftest). Stacked PRs: merge in order; merging a parent with--delete-branchcan close (not retarget) a child — retarget the child tomainfirst, or merge the stack's tip (it carries all the commits) and close the intermediates. - Commit scopes are enforced (
<scope>: <subject>); valid scopes in .claude/commit-scopes. - No paid/closed component code in scaffolds — never vendor Tailwind Plus / Catalyst.
- Keep README + docs/ + BACKLOG current alongside usage-affecting changes.
- Read the project memory (
.claude/memory/): engine-boundaries, dev-workflow, web-scaffold, rac-ui-shadcn.
Web scaffold:
- pnpm 11 hard-errors on native build scripts →
pnpm-workspace.yamldangerouslyAllowAllBuilds: true. - Convex green offline = anonymous local deployment:
CONVEX_AGENT_MODE=anonymous pnpm exec convex dev --once. - React Compiler on Vite 8 /
@vitejs/plugin-reactv6: a separate@rolldown/plugin-babel(DEFAULT import) pass runningreactCompilerPreset(). @/*resolves via tsconfigpaths(nobaseUrl— tsgo dropped it, TS5102) + Vite 8resolve.tsconfigPaths;import/extensions: off(rac-ui extensionless + codegen extensioned coexist).- racket-ui: consuming a namespaced shadcn registry over GitHub needs its per-item
public/r/*.jsondistribution committed (the aggregateregistry.jsonalone only powers the shorthand); the consumer'scomponents.jsonregistriesmap points at the raw per-item URL.
go-service scaffold:
- Feature files that import a non-stdlib dep (sqlite→glebarez, openapi→oapi-codegen) must be
.tmpl— else speckit's owngo build ./...compiles them and fails on the missing import (the basefiles/package IS compiled by the suite, so it must stay valid stdlib Go). - oapi-codegen runs via a
tooldirective (go get -tool …) +go tool oapi-codegen; the basego mod tidymoved to a late phase so feature codegen lands before tidy. - Members import their own generated/internal pkgs by full module path (
Data.Module=resolveModulePath); it's passed to templates and to the go.mod writer so they agree.
Both:
- A freshly rendered
mise.tomlis untrusted → scaffold install runsmise trust. - E2E PITFALL: do NOT
cdinside a$(...)subshell — thecdis lost andtarget addfires in the current repo. Alwayscd "$dir" && specify …in a throwawaymktemp -d. - A scaffold dotdir template (
.vscode/) whose name matches the repo-root.gitignoreis silently dropped from commits (embed reads the working tree, so it builds locally but CI lacks it) — add a!-negation and confirm withgit check-ignore.
- Finish the web scaffold — remaining
--with: sentry (client provider rides theWrapseam, but@sentry/vite-plugintouchesvite.config.ts— mirror the seam on the runtime axis with{{if .Features.sentry}}), then tanstack-db / electron. Plus the--ssr/--spamodes (trove proves SPA is needed — per-app). - Tier 2 monorepo (trove parity) — the go-service shared
go.mod✅; still: a rootpnpm-workspace.yaml(+ catalogs) maintained bytarget add, repo-rootinternal/sharing across go members, then the npm-package (packages/<name>) + ts-rest contract scaffolds. - New stack coverage — apple next (exercises the
swiftreport format +SpecTraits.swift), thenkind: libraryproducts + a go-cli stack (trove-transcode's shape). Designs: library-products.md, scaffolds/node-cli.md. - P6 — Release
⚠️ needs Mark's explicit go-ahead. Wire thegh extension installdistribution + the firstv0.1.0tag. Do NOT tag or push to the tap without confirmation.
- Don't tag a release / push to the Homebrew tap without explicit go-ahead.
- Don't run scaffold e2e inside the speckit repo, and never
cdin a$()subshell. - Don't vendor Catalyst / paid component code into scaffolds.
- Don't let
internal/github(or any network code) leak intointernal/engine. - Don't templatize a go-service feature file (importing a non-stdlib dep) as plain
.go— it breaks speckit's owngo build.
#22 (web → racket-ui) · #28 (Slice 5 — .vscode + pack refresh) · #27 (go-service trove-parity:
root go.mod + --with openapi/sqlite/client, carrying #24·#25·#26) · #29 (target register).
Plus racket-ui#1 (the per-item registry distribution).