Commit Graph

739 Commits

Author SHA1 Message Date
fc27eef6eb docs(coverage): sync docs to shipped state + wire sandcastle prompts
Closes the staleness gap after the 10-commit coverage epic shipped.

Doc sync (item 1 from the user's choice):
  - CLAUDE.md Quick Start: adds pnpm coverage:aggregate / coverage:diff
    / mutate to the command listing
  - CLAUDE.md: new "Sibling architecture: coverage (ADR-020)" section
    after the conformance gate table — captures the 4-layer table +
    points at docs/guides/coverage.md + ADR-020 + says agents must run
    coverage:diff before reporting complete
  - AGENTS.md preamble: now lists coverage as a parallel multi-latency
    quality system alongside conformance, with the same gate / latency
    framing
  - PRD frontmatter: status draft -> shipped + shipped date +
    shipping-commits list (all 10 SHAs anchoring the trace)
  - PRD findings table: each row gets a Resolution column citing the
    commit that closed it; conclusion text updated to past tense
  - ADR-020 implementation phasing: rewritten as a status table with
    each step linked to the commit that shipped it + Boot-time
    assertFeatureConformance explicitly marked Deferred with rationale
  - docs/guides/coverage.md: removed "Boot wiring lands in the next
    story" line; replaced with the deferral rationale + clarified
    that two readers (vitest, coverage:diff) consume the manifest

Sandcastle prompts (item 2 from the user's choice):
  - .sandcastle/implementer.prompt.md: new "Coverage gates" section
    after the conformance-gates list, requiring `pnpm test --coverage`,
    `pnpm coverage:aggregate`, and `pnpm coverage:diff` to all pass
    before reporting `complete`. Machine-readable JSON shape of
    coverage:diff documented (status / uncovered[] / kind enum), with
    explicit instructions on how to interpret each kind. Allowlist
    expansion requires justification + test.
  - .sandcastle/reviewer.prompt.md: AC coverage relabeled to "AC
    coverage (acceptance criteria, not test coverage)" to disambiguate;
    new check #7 "Coverage gates (ADR-020)" requiring CI's
    Coverage — diff (L1) step green + per-layer thresholds met +
    no silent allowlist expansion + manifest band drift detection.

Effect: future agent runs through sandcastle now treat coverage as a
first-class blocking gate, parallel to conformance. PRs no longer
discover coverage failures only via CI; the implementer is required
to check before reporting done, and the reviewer is required to
verify.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:47:16 +02:00
bf0b049583 feat(coverage): L0 unification — close test gaps in nav, media, mp
Closes the per-layer threshold gaps surfaced by the 2026-05-13 PRD
audit. After this commit all five features pass their declared
100%/100%/95%/100% bands on entities + use-cases + controllers.

media (was: missing @vitest/coverage-v8 + missing vitest config block +
  one controller at 86.66% lines / 75% branches)
  - Added @vitest/coverage-v8 dev dep
  - Applied the standard helper-driven vitest config
  - Declared the coverage section in feature.manifest.ts
  - Added 2 tests to list-media.controller.test.ts covering the
    InputParseError branch (unknown fields + invalid limit)
  - Now: 16 files / 80 tests / 97.12% / controllers 100%

marketing-pages (was: get-site-settings.controller at 93.54% lines /
  90.9% branches)
  - Added 1 test to get-site-settings.controller.test.ts covering the
    InputParseError branch on unknown fields
  - Now: 22 files / 68 tests / 95.66% / controllers 100%

navigation (was: entities/errors/common.ts at 50% function hits +
  get-header.controller at 86.66% lines / 80% branches)
  - Root cause: InputParseError class never instantiated in any test
  - Added 2 tests to get-header.controller.test.ts covering the
    InputParseError branch + verifying the Zod cause is preserved.
    One test exercises both gap files at once (controller throws,
    InputParseError class is constructed).
  - Wired navigation/vitest.config.ts through the shared helper
  - Declared the coverage section in feature.manifest.ts
  - Now: 11 files / 45 tests / 98.04% / entities + controllers 100%

All 5 features now drive thresholds from the manifest via the helper.
The duplication problem the keystone eliminates is gone.

Repo-wide via `pnpm coverage:aggregate`:
  - statements 95.87% (lh 2994 / lf 3123)
  - branches   88.91% (brh 433 / brf 487)
  - functions  100%   (fnh 142 / fnf 142)
  - lines      95.87%

`pnpm coverage:diff -- --base HEAD~1` reports status: pass.

coverage/summary.json refreshed in the same commit so the trend
captures the post-unification state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:39:08 +02:00
6428f10b82 feat(coverage): pnpm mutate (Stryker) + L3 implementation
Lands L3 of the agent-first coverage architecture (ADR-020) — the
mutation-testing layer. Stryker on entities + use-cases (the pure
business-logic surface) catches the third dimension of test quality:
tests that exist + execute the code but assert nothing.

Deps (root devDependencies):
  - @stryker-mutator/core ^8.7.0
  - @stryker-mutator/vitest-runner ^8.7.0

Shared base: packages/core-testing/stryker.base.json
  - testRunner: vitest (uses each feature's vitest.config.ts)
  - mutate: src/entities/** + src/application/use-cases/** (excludes
    tests, factories, contracts)
  - thresholds: high 90 / low 80 / break 80
  - reporters: progress + html + json (reports/mutation/{index.html,
    mutation.json})
  - incremental mode enabled, concurrency 4, timeout 10s
  - exposed via @repo/core-testing/stryker.base.json subpath export

Per-feature config: packages/auth/stryker.config.json
  - 4-line file that extends the shared base
  - Proof-of-concept; other features get a config when L0 unification
    closes their existing test gaps

Driver: scripts/coverage/mutate.mjs (zero-dep Node ESM)
  - discoverStrykerConfigs: walks packages/* and apps/* for
    stryker.config.json
  - Supports --filter <name>, --since <ref> (incremental), --json
  - Runs Stryker per-feature via node_modules/.bin/stryker run
  - Surfaces per-package pass/fail summary; exits 1 on any failure
  - Tests: scripts/coverage/mutate.test.mjs (3 tests, all green)

CI: .github/workflows/mutation-nightly.yml
  - Cron at 02:30 UTC + workflow_dispatch with filter input
  - Uploads reports/mutation/** as artifact (30-day retention)
  - On failure, opens a tracking issue labelled mutation-testing
  - permissions: contents: read, issues: write
  - 60-min timeout (Stryker is slow by design)

Generator: turbo gen feature now scaffolds stryker.config.json from
turbo/generators/templates/feature/stryker.config.json.hbs — new
features ship mutation-ready out of the box.

Guide: docs/guides/coverage.md L3 section fleshed out with run
syntax, config shape, base config inventory, CI behavior, and a
"what you're looking for" primer on mutation scores.

Lockfile churn: pnpm regenerated the lockfile for the new deps;
~5K-line net reduction is collateral (pnpm version drift) but
mechanical.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:31:30 +02:00
f4254aae48 docs(coverage): cookbook guide + feature generator scaffolds coverage:
Adds the day-to-day cookbook for the 4-layer coverage architecture
(ADR-020) and threads it into the discovery path:

docs/guides/coverage.md (new):
  - 4 layers at a glance + when each fires
  - Single-source-of-truth pattern (feature.manifest.ts coverage:
    section) and the three readers (vitest, assertFeatureConformance,
    coverage:diff)
  - Daily workflow: pnpm test --coverage -> aggregate -> diff
  - How to read a failure (stderr human + stdout JSON examples)
  - How to fix uncovered slices (TDD walkthrough)
  - The full allowlist (test files, configs, docs, scripts, dev
    tooling, per-feature excludes)
  - Adjusting bands (manifest-first, when to override vitest)
  - CI behavior (two workflows: validate + coverage-snapshot)
  - Reading the committed trend via git log -- coverage/summary.json
  - Mutation testing primer (L3, opt-in, scope, lands in next story)
  - Troubleshooting

CLAUDE.md Read First gets the new guide pinned between audit and
template-tiers, with the L0-L3 layer summary inline so agents see the
shape at a glance.

Feature generator updates (turbo/generators/templates/feature/):
  - feature.manifest.ts.hbs: new `coverage:` block at <gen:coverage>
    anchor scaffolded with the documented defaults + mutationTargets
  - vitest.config.ts.hbs: now uses vitestThresholdsFromBands(
    DEFAULT_COVERAGE_BANDS) instead of the duplicated literal — new
    features ship conformance-compliant by default

Next features generated via `pnpm turbo gen feature` are coverage-
aware from the first commit: bands declared in manifest, vitest
config consumes the helper, no duplication to drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:15:01 +02:00
15db9c48cb refactor(blog,marketing-pages): wire coverage helper + declare manifest bands
Migrates blog and marketing-pages to the same pattern auth landed in
f7baa8b: vitest config consumes vitestThresholdsFromBands(
DEFAULT_COVERAGE_BANDS) instead of the duplicated hand-written
thresholds block, and each manifest declares its coverage section
explicitly.

Verified semantically identical to the previous hand-written
thresholds — the same numbers come out the other end of the helper.
No new regressions:
  - blog: 89 tests, 96.33% overall, all bands green
  - marketing-pages: 67 tests, 95.28% overall — controllers/ shows a
    real 93.54% lines / 90.9% branches gap that has been there since
    before this refactor (the previous hand-written threshold was the
    same 100%/95%). This is one of the L0 unification work items
    listed in the PRD's findings; capturing here as the third feature
    with real test gaps (navigation, media, marketing-pages).

Three of five features now drive their vitest thresholds from the
manifest helper: auth ✓, blog ✓, marketing-pages ✓. Navigation and
media stay on the legacy config until L0 unification closes their
test gaps (touching them would expose the same failures and add
nothing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:13:08 +02:00
39e33eb634 ci(coverage): wire L1 + L2 + auto-snapshot summary.json on merge
Two-workflow split per ADR-020:

.github/workflows/ci.yml (existing, extended):
  - checkout now uses fetch-depth: 0 so coverage:diff can resolve
    origin/<base-ref>...HEAD against the PR's base branch
  - new step "Coverage — aggregate (L2)" runs after the test step
    (with `if: always()` so the artifact still captures partial state
    on test failures)
  - new step "Coverage — diff (L1)" runs only on pull_request events,
    diffing against origin/${{ github.base_ref }}
  - artifact upload extended to include the aggregated
    coverage/lcov.info and coverage/summary.json alongside the
    per-package files

.github/workflows/coverage-snapshot.yml (new):
  - dedicated workflow with `permissions: contents: write` so it can
    commit the aggregated coverage/summary.json back to main after
    each merge — the committed trend store (ADR-020 L2)
  - runs full test + aggregate, then commits summary.json only if it
    actually changed (commit body marked [skip ci] so the snapshot
    doesn't recurse into itself)
  - concurrency: coverage-snapshot ensures only one snapshot at a time

This closes the CI side of the coverage architecture. PRs now fail
fast when changed lines are uncovered, and main's trend history
accumulates automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:12:02 +02:00
bd5a077227 feat(coverage): pnpm coverage:aggregate + L2 implementation
Lands L2 of the agent-first coverage architecture (ADR-020) — the
aggregated trend store.

Script: scripts/coverage/aggregate.mjs (zero-dep Node ESM)
  - discoverLcovs: walks packages/* and apps/* for coverage/lcov.info
  - normalizeLcov: rewrites SF entries from package-relative (vitest's
    output) to repo-relative, so the merged file matches git diff paths
  - summarizeLcov: computes statement/branch/function/line percentages
    from LF/LH/BRF/BRH/FNF/FNH summary records
  - aggregate: merges all lcovs and returns mergedLcov + summary
  - Writes coverage/lcov.info (gitignored — large) and
    coverage/summary.json (committed — trend via git log -- ...) with
    timestamp, short commit SHA, repo + per-package percentages

Test surface: scripts/coverage/aggregate.test.mjs (10 tests, all green)
  - Fixtures at __fixtures__/aggregate-pkg-a.lcov +
    aggregate-pkg-b.lcov (synthetic, structured to make percentages
    deterministic)
  - Covers: path normalization (prefix, absolute, double-prefix
    avoidance), summary computation (percentages, zero-division,
    rounding), discovery (packages + apps, missing dirs), full
    aggregation in a tmp repo

Wired:
  - root package.json adds "coverage:aggregate" script
  - .gitignore restructured: per-package coverage/ stays ignored,
    aggregated /coverage/ ignored EXCEPT summary.json (committed for
    trend) and .gitkeep markers

L1 allowlist fix folded in (scripts/coverage/diff.mjs):
  - The previous (^|/)coverage/ regex accidentally caught
    scripts/coverage/* — replaced with anchored patterns
    (^coverage/, ^packages/*/coverage/, ^apps/*/coverage/)
  - Allowlist scripts/ and turbo/generators/ since they're dev tooling
    tested via node --test, outside vitest's v8 lcov pipeline

Smoke-tested end-to-end:
  - pnpm coverage:aggregate merged 3 lcovs (auth + media + navigation
    from this session's earlier runs), repo coverage 95.22% statements
  - pnpm coverage:diff against HEAD~1 with the new merged lcov reports
    PASS — all 6 diff files correctly allowlisted

First committed snapshot of coverage/summary.json lands with this
commit, anchoring the trend history at this state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:10:22 +02:00
412d994733 feat(coverage): pnpm coverage:diff script + L1 implementation
Lands L1 of the agent-first coverage architecture (ADR-020) — the
cover-the-diff gate. Reads a merged lcov + git diff against a base
ref, asserts every changed *executable* line was exercised.

Script: scripts/coverage/diff.mjs (zero-dep Node ESM)
  - parseLcov: SF -> Map<line, count>; only DA records read
  - parseGitDiff: parses --unified=0 output into Map<file, Set<line>>
  - computeDiffCoverage: cross-references both, emits result tree
  - Allowlist of paths that don't gate (tests, configs, docs, .sh,
    DI bootstrap, interfaces, CMS, factories, contracts, UI)
  - Path matching handles three lcov path conventions: absolute,
    repo-relative, and per-package relative
  - CLI flags: --base (default origin/main), --lcov (default
    coverage/lcov.info), --json (suppress stderr summary)
  - stdout: machine-readable JSON for the dispatch loop
  - stderr: human summary
  - Exit 0 on pass, 1 on fail or error

Test surface: scripts/coverage/diff.test.mjs (14 tests, all green)
  - Fixtures at scripts/coverage/__fixtures__/{sample.lcov,sample-diff.patch}
  - Covers: lcov parsing, diff parsing, pass path, uncovered lines,
    non-executable line skipping, no-coverage-data detection,
    allowlist filtering, end-to-end mixed case, path matching

Wired:
  - root package.json adds "coverage:diff" script
  - .gitignore anchored so per-package coverage/ stays ignored but
    scripts/coverage/ stays tracked

Smoke-tested end-to-end against packages/auth/coverage/lcov.info —
correctly skips shell scripts + manifest files (via allowlist + path
suffix match), correctly flags files not present in the per-package
lcov (which is expected; full repo coverage needs the L2 aggregate
that the next story lands).

CI integration deferred to the L2 aggregate story (the merged
coverage/lcov.info this script reads doesn't exist yet — pnpm
coverage:aggregate produces it).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:04:09 +02:00
f7baa8bfd1 feat(core-shared/conformance): manifest coverage schema + vitest helper
First implementation milestone of the agent-first coverage architecture
(ADR-020, PRD 2026-05-13). Lands the keystone — coverage bands as a
typed declaration in feature.manifest.ts plus a helper that derives
vitest threshold shapes from them.

New file packages/core-shared/src/conformance/coverage.ts (self-
contained, no relative imports — loadable at vitest config time):
- CoverageBand / CoverageBands / CoverageManifest / VitestThresholds
  types
- DEFAULT_COVERAGE_BANDS (baseline 80/75/80/80; entities 100/100/100/
  100; use-cases + controllers 100/95/100/100) — matches ADR-011
- DEFAULT_MUTATION_SCORE (80) + DEFAULT_MUTATION_TARGETS (entities +
  use-cases)
- getCoverageBands / getMutationConfig — manifest -> resolved bands,
  with default fallback for missing layers
- vitestThresholdsFromBands / vitestThresholdsFromManifest — convert
  to vitest's coverage.thresholds shape with the layer-to-glob
  mapping

define-feature.ts gains the optional coverage field on FeatureManifest
(imports its type from coverage.ts to avoid a relative-import cycle
at config-load time).

Exposed via two subpaths: @repo/core-shared/conformance (re-exports
for source/test code) and @repo/core-shared/conformance/coverage
(direct subpath safe to load from vitest configs, bypasses the index
re-export chain that Node ESM doesn't auto-extension-resolve).

Auth wired as proof-of-concept:
- packages/auth/src/feature.manifest.ts declares its coverage section
- packages/auth/vitest.config.ts imports the helper +
  DEFAULT_COVERAGE_BANDS and emits thresholds via
  vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS) — no more
  hand-maintained per-glob thresholds block.

Verified: 175/175 tests pass; 14/14 typechecks clean; auth coverage
green (21 tests, 93.77% overall, all per-layer 100% bands hold).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:51:13 +02:00
4dce1df084 docs(coverage): ADR-020 + glossary entries + hook keyword group
Architecture record for the agent-first coverage initiative seeded by
the 2026-05-13 PRD. Captures the durable decisions:

- 4-layer architecture (L0 vitest, L1 diff, L2 aggregate, L3 mutation)
- Manifest-driven coverage band as single source of truth (vitest +
  assertFeatureConformance + pnpm coverage:diff all read from it)
- Cover-the-diff (changed lines), not cover-the-new-code
- Committed coverage/summary.json (no SaaS), trend via git log
- Mutation testing scoped to entities + use-cases, on-demand only
- Machine-first output format (JSON stdout, human stderr)

Glossary gets a new "Coverage" section with 7 entries (coverage band,
L0-L3 layers, diff coverage, mutation testing, mutation score,
coverage/summary.json), plus two relationship rows and a flagged
ambiguity for "coverage" qualifiers.

prompt-context.sh hook gets a 9th keyword group — when a prompt
mentions coverage / uncovered / lcov / mutation / stryker, the
relevant ADR + guide path are injected as additional context for
the turn.

This is the documentation layer of the coverage epic. Implementation
(manifest schema, vitest auto-derive, scripts, boot assertion,
mutation tooling) lands in subsequent stories.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:42:26 +02:00
7eb783aee1 docs(prds): seed agent-first coverage architecture PRD
Captures the brainstorm convergence (2026-05-13) into a draft PRD that
seeds the implementation epic. Decisions captured:

- 4-layer coverage architecture (L0 vitest thresholds, L1 diff coverage,
  L2 aggregate summary.json, L3 mutation testing on entities + use-cases)
- Manifest-driven coverage band as the single source of truth — vitest
  config, assertFeatureConformance boot check, and pnpm coverage:diff
  all derive expectations from feature.manifest.ts
- Cover-the-diff (every changed line exercised) not cover-the-new-code
- Aggregate trend committed as coverage/summary.json; no SaaS dep
- Stryker for mutation, on-demand only, NOT in default pnpm test

L0 verification findings (also captured in the PRD):
- auth / blog / marketing-pages: green (100% layer bands hold)
- navigation: real test gaps in entities + controllers (~86%)
- media: missing @vitest/coverage-v8 dep + vitest.config has no
  coverage block at all (entirely absent — the most extreme case of
  the duplication problem the manifest-driven keystone eliminates)

Status remains draft until the human review pass. Decomposer will
refuse to run on draft.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:37:21 +02:00
35da40b782 feat(claude): add 6 lifecycle hooks reinforcing template hard rules
Project-level Claude Code hooks committed to .claude/settings.json with
scripts under .claude/hooks/. Three tiers:

Tier 1 — hard guards (exit 2 to block the tool call):
- bash-guard.sh: blocks bypass flags (verify-skip, sign-skip), forceful
  push variants, destructive resets, force clean, working-tree-wipe
  checkouts/restores, force branch delete, amend, and rm -rf against
  root or home. Reinforces CLAUDE.md Git Safety Protocol.
- generator-first-nudge.sh: blocks creating a new top-level
  packages/<name> or apps/<name> directory by hand. Allows working
  inside an existing package. Reinforces the non-negotiable
  generator-first rule.

Tier 2 — context injection (stdout becomes additional context):
- session-start.sh: prints glossary, AGENTS.md, workflow CLI, and
  conformance pointers on session boot.
- prompt-context.sh: keyword-matches the user prompt against eight
  concept groups (events, realtime, audit, instrumentation, manifest,
  workflow, DI, boundaries) and injects the relevant ADR + rule
  pointers for the turn.

Tier 3 — side-effect automation:
- post-manifest-edit.sh: when Edit/Write touches feature.manifest.ts,
  prints the manifest-first ordering reminder plus the per-feature
  verify commands.
- stop-check-manifest-tests.sh: at agent Stop time, if the working
  tree has manifest changes but no sibling test changes, exits 2 to
  force continuation. Loop-guarded via stop_hook_active.

All hooks are bash + jq, use CLAUDE_PROJECT_DIR for safety, and were
smoke-tested end-to-end (block + allow paths both verified).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:17:38 +02:00
5d61343068 chore: gitignore *.local files at project level + strip phase residuals
Previously .claude/settings.local.json was only excluded by the user's
global ~/.config/git/ignore — fresh clones of this template would have
accidentally committed per-user Claude Code settings. Add an explicit
project-level rule (*.local, *.local.*, **/settings.local.json) so the
template ships with the protection baked in.

Also strips two missed "phase" residuals from
core-shared/instrumentation/otel/init-server-node.ts (the word leaked
through the earlier sweep — generic future-work qualifier, not a
setup-history reference, but cleaner without it).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:10:53 +02:00
a372eeda86 docs: add canonical glossary + install mattpocock skills adapted for repo
docs/glossary.md is the shared vocabulary source for humans and agents.
Resolves every cross-cutting term used in this repo (feature, use case,
manifest, slice, conformance, dispatch, ...) with one-sentence definitions,
relationships, and flagged ambiguities. Linked from CLAUDE.md "Read First"
and AGENTS.md preamble so every session loads it early.

.claude/skills/ installs four mattpocock skills adapted to this monorepo:
  - to-prd: writes to docs/work/prds/ with the repo's PRD frontmatter +
    merged user-stories/implementation/testing sections
  - grill-with-docs: points at docs/decisions/ + docs/glossary.md; adds
    feature.manifest.ts + conformance-rule cross-checks
  - grill-me: minor — adds pnpm work / fallow / manifest shortcuts
  - handoff: adds the repo's specific don't-duplicate artifacts list

Also fixes a missed "Phase-1" residual in CLAUDE.md's Read First section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:04:42 +02:00
2edc76002a refactor(docs): strip residual Phase/Plan setup-history references
Final sweep for setup-process bookkeeping not caught by template-reset-v1.
ADRs drop Plan-N qualifiers; spec collapses the historical 11-phase
migration table; scaffolding guide drops "Phase added" column; comment
prefixes referencing R-numbers in test describes / eslint inline comments
are normalized. Architecture-level rule IDs (R40, R52, E0, J0, etc.) are
preserved where they serve as stable cross-references in ADRs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:28:31 +02:00
318dc05b6e refactor: strip residual R-number test descriptions + Lazar URL from ADR-013 2026-05-13 10:22:17 +02:00
8ce0e4c59c Merge branch 'worktree-template-reset-v1': strip setup-process refs + archive history + rename ADR-012 2026-05-13 10:19:11 +02:00
e203a9d58e chore(work): close out template-reset-v1 epic — all 12 tasks done
Mark epic + story status done, check all task boxes, rebuild _state.json.
All checks green: typecheck, tests (360 passing), lint, turbo boundaries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:18:29 +02:00
2ceaa08944 chore(template-reset): update snapshots, fix lint, rebuild state
- Regenerate audit + realtime core-package e2e snapshots (template
  Phase-label changes altered file hashes)
- Fix pre-existing lint error in auth authentication.service.ts:
  rename unused params to _user / _sessionId, drop stale eslint-disable
  comments that were on wrong lines
- Mark story tasks 1-9 done; rebuild _state.json

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:17:50 +02:00
841655573b docs(adr): rename ADR-012 — drop Lazar; update title + content + cross-refs
- Rename docs/decisions/adr-012-lazar-conformance.md → adr-012-feature-conventions.md
- Strip "Lazar", "Plan 8/9/10/11", "refactor-logs" refs from all ADRs,
  architecture docs, HTML explainers, and feature/core AGENTS.md files
- Update all incoming links in docs/, packages/*/AGENTS.md, HTML explainers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:07:37 +02:00
06da37f723 refactor: strip Lazar references from top-level docs + guides 2026-05-13 09:57:19 +02:00
17ae157365 refactor: strip Phase/Plan/R-number references from source comments 2026-05-13 09:51:45 +02:00
075b729266 feat: archive setup-history epics + plans + refactor-logs to .archive/ 2026-05-13 09:43:49 +02:00
dca69afe97 feat: .archive/ folder for gitignored template setup history 2026-05-13 09:43:28 +02:00
c7ce0d9819 docs(work): scaffold template-reset-v1 epic 2026-05-13 09:43:09 +02:00
a3d076673a Merge branch 'worktree-sandcastle-subscription-auth-v1': sandcastle subscription auth as primary flow 2026-05-13 09:32:44 +02:00
9ca1022f9c docs(work): close sandcastle-subscription-auth-v1 epic 2026-05-13 09:32:14 +02:00
e734a9e7a1 docs: subscription auth is the primary sandcastle flow, API key is fallback 2026-05-13 09:31:33 +02:00
4e1167e390 test(scripts): resolveClaudeAuth — subscription/api-key/missing modes 2026-05-13 09:30:11 +02:00
936611ba62 feat(scripts): dispatch.mjs — subscription-first auth via ~/.claude mount 2026-05-13 09:28:20 +02:00
793772a34d feat(sandcastle): Dockerfile installs Claude Code CLI for subscription auth 2026-05-13 09:27:22 +02:00
b6948fa881 docs(work): scaffold sandcastle-subscription-auth-v1 epic 2026-05-13 09:27:02 +02:00
3f0d60e082 docs(adr): ADR-019 — Sandcastle for agent orchestration
Captures the decision to adopt @ai-hero/sandcastle as the orchestration
substrate for agent-driven development in this template. Records the
8-point decision (workspace dep, .sandcastle/ prompts, Dockerfile,
dispatch.mjs orchestrator, planning vs execute modes, generator-first
reviewer check, bring-your-own-key, per-task max-attempts), the four
alternatives considered (bare CLI / Copilot Workspace / custom-from-
scratch / no orchestrator), and four trade-offs (external dep, token
cost, Docker dependency, manual state mutation in v1).

Surfaces the decision at the top of README.md and AGENTS.md so new
contributors see the agent-driven framing before they hit the package
map or daily commands.
2026-05-13 09:15:13 +02:00
039079b64a docs(guides): runbook section on using Sandcastle for agent dispatch
Adds a "Using Sandcastle for agent dispatch" section between the gate
table and Troubleshooting. Covers when to use / not use sandcastle,
prerequisites (Docker + agent API key + .sandcastle/ config), the
dispatch flow, a worked end-to-end example (plan → execute → review →
manual state mutation), troubleshooting (env vars, Docker, timeouts,
rejection modes), and a cost-aware planning-only variant.
2026-05-13 09:09:56 +02:00
cae4d2c090 Merge branch 'worktree-docs-and-runbook-v1': runbook + post-Fallow doc sweep 2026-05-13 09:06:34 +02:00
244313c914 docs(work): close docs-and-runbook-v1 epic 2026-05-13 09:05:54 +02:00
88edde342e docs: README + CLAUDE.md + .env.example + quickref reflect latest gates 2026-05-13 09:05:10 +02:00
05ebbb4719 docs(guides): developer runbook — day-1 onboarding 2026-05-13 09:04:28 +02:00
cf8d69106e docs(work): scaffold docs-and-runbook-v1 epic + stories 2026-05-13 09:03:15 +02:00
e87e554a7c Merge branch 'worktree-fallow-integration-v1': fallow v1 — 5th gate (whole-codebase)
Some checks failed
CI / typecheck + lint + boundaries + test + build (push) Has been cancelled
CI / Playwright e2e (push) Has been cancelled
CI / Storybook smoke tests + visual regression (push) Has been cancelled
Sentry PII guard (R31) / pii-guard (push) Has been cancelled
2026-05-13 08:57:42 +02:00
072e08d855 docs(work): close fallow-integration-v1 epic 2026-05-13 08:55:50 +02:00
7ecb365e63 feat(sandcastle): implementer + reviewer prompts include fallow audit 2026-05-13 08:53:00 +02:00
d34b841256 docs(guides): conformance-quickref includes fallow row + audit usage 2026-05-13 08:52:37 +02:00
1655cd0879 docs: surface fallow as 5th conformance gate in CLAUDE.md 2026-05-13 08:52:09 +02:00
749938e48b ci: add fallow whole-codebase gate after pnpm conformance 2026-05-13 08:51:53 +02:00
7c7a65f7e3 feat: pnpm fallow + fallow:audit scripts, turbo task entry 2026-05-13 08:51:45 +02:00
e1d54a1f3e feat: install fallow + .fallowrc.json config 2026-05-13 08:48:08 +02:00
2722305398 docs(work): scaffold fallow-integration-v1 epic + stories 2026-05-13 08:47:30 +02:00
85fb050019 Merge branch 'worktree-visual-regression-v1': visual regression v1 infrastructure 2026-05-13 08:33:32 +02:00
10603bd250 docs(work): close visual-regression-v1 epic 2026-05-13 08:32:58 +02:00