diff --git a/docs/branch-review-records/269a4c69830c7ffd8a6d203682b0cd105930d5e867594660bba2701f4b6e5536.record.md b/docs/branch-review-records/269a4c69830c7ffd8a6d203682b0cd105930d5e867594660bba2701f4b6e5536.record.md new file mode 100644 index 000000000..01c5e34d6 --- /dev/null +++ b/docs/branch-review-records/269a4c69830c7ffd8a6d203682b0cd105930d5e867594660bba2701f4b6e5536.record.md @@ -0,0 +1 @@ +| 2026-08-22 | PR #2292 / claude/dev-hub-phase-2-plan | bda501b62c85ba90f0ee3125d6b1fc006b24f15f | PR #2292 CI repair after unit coverage failure | Fixed CI run 32594149250: PanelPageShell now uses contextual history for its page-level back arrow; recursive repository-awareness test cleanup uses the retryable helper; and the panel DOM test mocks the App Router required by ContextualBackLink. | CI log inspected: Unit coverage 2 failed/8442 passed; focused Vitest contextual-back-navigation + test-runner-safety + repo-awareness + panel DOM 77/77; tsc --noEmit; Prettier --check; git diff --check | diff --git a/docs/branch-review-records/70c18c299fd7b0dde7d7cf053ebfb9b9726dfa286516d07ae9cdd5e15a8989be.record.md b/docs/branch-review-records/70c18c299fd7b0dde7d7cf053ebfb9b9726dfa286516d07ae9cdd5e15a8989be.record.md new file mode 100644 index 000000000..cab262c44 --- /dev/null +++ b/docs/branch-review-records/70c18c299fd7b0dde7d7cf053ebfb9b9726dfa286516d07ae9cdd5e15a8989be.record.md @@ -0,0 +1 @@ +| 2026-08-22 | PR #2292 / claude/dev-hub-phase-2-plan | 73477b2a9b3aa92c351f6e3a9a15cced0f2f3859 | PR #2292 CI repair for ledger page router harness | Fixed the second CI failure: the developer-ledger DOM suite renders PanelPageShell after its back link became contextual, so the test now supplies the App Router mock required by ContextualBackLink. The 14 reported failures were all cascading mount errors. | CI run 32595099042 log inspected; focused developer-ledger + panel + back-navigation + cleanup + repo-awareness Vitest 91/91; tsc --noEmit; Prettier --check; git diff --check | diff --git a/docs/branch-review-records/9e74aa49d3e5b822a78bf81bcc90837d009fb026f0b49ded2b7cde9358f311c8.record.md b/docs/branch-review-records/9e74aa49d3e5b822a78bf81bcc90837d009fb026f0b49ded2b7cde9358f311c8.record.md new file mode 100644 index 000000000..c53a526a7 --- /dev/null +++ b/docs/branch-review-records/9e74aa49d3e5b822a78bf81bcc90837d009fb026f0b49ded2b7cde9358f311c8.record.md @@ -0,0 +1 @@ +| 2026-08-22 | PR #2292 / claude/dev-hub-phase-2-plan | 13c20de02e90919008c9e8a8ab5c338c2a987a84 | PR #2292 developer-hub review and P2 fixes | Merged current main; confirmed the external Markdown URL guard and added a fail-closed staging requirement for non-ignored untracked Markdown docs. Both actionable review findings are covered by focused regressions; ignored scratch notes remain excluded. | Vitest repo-awareness-generator 31/31; tsc -p tsconfig.typecheck.json --noEmit; Prettier --check; git diff --check; coordinated typecheck wrapper interrupted by environment but underlying tsc passed | diff --git a/docs/branch-review-records/c098126cd910731212bdd8aa2bbe0b34a993d3661e387d907f5eb3dc00ba08ba.record.md b/docs/branch-review-records/c098126cd910731212bdd8aa2bbe0b34a993d3661e387d907f5eb3dc00ba08ba.record.md new file mode 100644 index 000000000..3155d1d08 --- /dev/null +++ b/docs/branch-review-records/c098126cd910731212bdd8aa2bbe0b34a993d3661e387d907f5eb3dc00ba08ba.record.md @@ -0,0 +1 @@ +| 2026-08-22 | PR #2292 / claude/dev-hub-phase-2-plan | b7261793e97e5f385e2ea3537a52182d7cf517f9 | PR #2292 developer-hub review and P2 fixes after main sync | Merged latest main 3e5c2234 cleanly after the P2 fixes. The merged tree preserves the external-URL guard, fail-closed untracked-document staging requirement, ignored scratch-note exclusion, and prior immutable review record. | Vitest repo-awareness-generator 31/31; tsc -p tsconfig.typecheck.json --noEmit; Prettier --check; git diff --check; merge-tree --write-tree 60ef8b9 3e5c223 returned fc385e66 without conflicts | diff --git a/docs/scripts-index.md b/docs/scripts-index.md index 6bcf50ac3..df3da438b 100644 --- a/docs/scripts-index.md +++ b/docs/scripts-index.md @@ -1,6 +1,6 @@ # Scripts index -Curated map of `scripts/` (265 files) and the `package.json` script surface (267 entries), +Curated map of `scripts/` (266 files) and the `package.json` script surface (267 entries), grouped by purpose. This is orientation, not an exhaustive per-file listing — the authoritative command list is `package.json`, and `npm run docs:check-scripts` verifies every `npm run ` referenced in docs resolves to a real script. `npm run docs:update` refreshes the exact counts above. diff --git a/docs/superpowers/plans/2026-08-22-developer-hub-phase-2-HANDOFF.md b/docs/superpowers/plans/2026-08-22-developer-hub-phase-2-HANDOFF.md new file mode 100644 index 000000000..d4450a158 --- /dev/null +++ b/docs/superpowers/plans/2026-08-22-developer-hub-phase-2-HANDOFF.md @@ -0,0 +1,129 @@ +# Developer hub Phase 2 — handoff + +Companion to the plan (`2026-08-22-developer-hub-phase-2.md`) and the approved spec +(`docs/superpowers/specs/2026-08-22-developer-hub-phase-2-design.md`). This file exists so a +fresh session can resume without the session that wrote it. + +**Read this, then the plan, then the spec. In that order.** + +Written 2026-08-23 at Task 5 of 13, a deliberate stopping point: Tasks 1–5 complete the entire +data layer bar its assembly, and nothing is half-built. + +--- + +## 1. Where the work is + +| | | +| ------------ | ------------------------------------------------------------------------------------------------------------------ | +| Worktree | `D:/Worktrees/Database/dev-hub-phase-1` — **not** `.claude/worktrees`, which has been wiped repeatedly | +| Branch | `claude/dev-hub-phase-2-plan`, cut from `origin/main` at `83a8ffb37` | +| Remote | Pushed. `origin/claude/dev-hub-phase-2-plan` tracks it — the work does not live only on this machine | +| PR | None yet, by design. Phase 2 is not finished | +| Dependencies | Installed. Do **not** run `npm ci`; if a fresh worktree is ever needed use `node scripts/setup-codex-worktree.mjs` | + +**Verify the branch before every commit** (`git rev-parse --abbrev-ref HEAD`). Two worktrees were +destroyed mid-session during Phase 1 and git silently resolved to the main checkout on another +branch. + +## 2. What is done + +| Task | What | Commits | +| ---- | --------------------------------------------------------- | --------------------------------------------------------------------- | +| — | Spec decision + plan | `c1f5259ff` | +| 1 | Shared freshness helper, labelled stamp, `PanelPageShell` | `3ce47a487` | +| 2 | Shared types module + routes section | `bc340bcf9` | +| 3 | Documentation section | `643fbae2e`, fix `ec68283b1`, plan `cd7194c21`, docstring `1ed5c2b5e` | +| 4 | Test-health section | `06676a55b`, fix `f986684a0` | +| 5 | Review-state section | `4737541a8`, fix `eb95080ae`, plan `d97f9fd06` | + +Every task had its own review; Tasks 3, 4 and 5 each needed a fix round, and each fix round had a +scoped re-review. **28 tests pass** in `tests/repo-awareness-generator.test.ts`; +`typecheck:source` is green. + +**All three gates are green as of this handoff.** The batched `npm run lint` covering Tasks 4 and 5 +finally got a turn on the run coordinator and passed clean — ESLint emitted no findings at all +(`--max-warnings 0`, exit 0). That matters because lint caught this branch's only Critical finding +(an unused constant in Task 3), so it is the gate least safe to infer from green tests. + +Nothing is outstanding. Task 6 is a clean start. + +## 3. What is next — Tasks 6 to 13 + +The plan carries the full code. In order: + +| Task | What | +| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 6 | Assemble the snapshot, resolve the captured revision, write `data/repo-awareness-snapshot.json`, wire `snapshot:repo-awareness` into `docs:update` (**not** `prebuild` — ruling R5) | +| 7 | The staleness gate, registered in three places: `verify:cheap:internal`, `scripts/verify-pr-local.mjs`, and `.github/workflows/ci.yml` | +| 8 | The typed reader with its version guard | +| 9 to 12 | The four pages: routes, documentation, test health, review state. Each adds a route, so each must regenerate and commit the snapshot (ruling S1) | +| 13 | Flip the four registry entries to `phase: 1`, rename `work-in-flight` to "Review state" keeping its id, update `docs/codebase-index.md`, run `npm run docs:update` | + +Then the controller-only acceptance in the plan's final section — `npm run build`, a live render of +all five developer routes, `verify:pr-local`, `verify:phone-chrome`, and a determinism check. + +**Regenerate a task brief** (the git-ignored ones will be gone): + +```bash +node -e "const fs=require('fs');const L=fs.readFileSync('docs/superpowers/plans/2026-08-22-developer-hub-phase-2.md','utf8').split('\n');const gs=L.indexOf('## Global Constraints');const ge=L.indexOf('---',gs);const n=process.argv[1];const s=L.findIndex(l=>l.startsWith('### Task '+n+':'));let e=L.length;for(let i=s+1;i brief-6.md +``` + +## 4. Decisions already made — do not re-open these + +Full reasoning is in the plan's "Rulings" table. The load-bearing ones: + +- **R1** The hub shows only facts no green gate already guarantees. This is why the routes panel does not flag orphan routes and the documentation panel does not list broken links — CI already guarantees both are zero. +- **R3** Document age is deliberately absent. It needed a per-row git-preservation mechanism and an 8.7-second `git log` walk on every generate _and_ every gate run, to show a number no staleness policy backs. +- **R5** The generator runs from `docs:update` only, never `prebuild`. `docs/site-map.md` is the precedent. This keeps `tsx` off the Docker build path, which is why git can be a hard requirement of the generator rather than something to degrade around. +- **R9** The registry entry keeps `id: "work-in-flight"` while its name becomes "Review state". The id is Phase 1's extension mechanism. +- **Owner's decision, spec §4.1** The panel shows the repository's own review history, not live pull-request state. The page says so in its own words so nobody infers otherwise. + +## 5. Traps this branch has already paid for + +**Dispatching implementers.** Every dispatch must carry: an explicit Bash `timeout` of 600000; use +`npm run test`, never `test:focused`; never pipe a gate through `tail`/`head`/`grep`; run +`typecheck:source` too; never force the run-coordinator lock; verify the branch before committing. +Add one more, learned here: **retry the lock inline within your own turn — never hand waiting to a +background job, monitor or scheduled wake-up.** A subagent's background work dies with its turn. One +agent wrote four correct fixes, scheduled the verification, ended its turn, and nothing ran; the task +looked finished and was not. + +**Checks that cannot fail.** Eight assertions on this programme have turned out to assert nothing — +two of them on this branch, both originating in the plan's own snippets. Before accepting any test, +name the concrete source edit that turns it red, and where it matters, _watch it fail_. Both fixes +here were mutation-proved: red output pasted, then green. + +**Exit codes are not evidence.** My own verification script restored a backup that already contained +the fault it had injected, so a good build looked broken. Reading the actual failure output is what +identified it as my bug, not the implementer's. + +**Line endings.** Controller-side edits through Python's text mode silently wrote CRLF; this repo is +`eol=lf`. Use binary-mode writes or the editor tooling. Committed blobs were unaffected because git +normalises on `add`, but the working tree warned on every diff. + +**Lock contention is the dominant cost.** Other sessions on this machine hold the exclusive +Playwright/typecheck lease; single gate acquisitions have taken up to 28 minutes. Ruling T3-3: from +Task 4 on, implementers run tests + `typecheck:source` only, and the controller runs `lint` batched +every second or third task. + +**An instruction can be wrong.** In Task 5 I specified an assertion that refs never contain a space. +The implementer refused it with evidence — 106 of 454 refs legitimately do, in forms like +`PR #1888 (claude/...)` — and was right. The rejected idea and its reason are recorded in the plan so +it is not retried. Expect and welcome that kind of refusal. + +## 6. Known-failing baseline — do not chase + +`tests/codex-cloud-setup.test.ts` (2 failures) and `tests/design-sync-contract.test.ts` (1 failure) +fail in this environment for reasons unrelated to this work. + +## 7. Working notes + +The session ledger, task briefs and reviewer reports live in the git-ignored +`.superpowers/sdd/2026-08-22-developer-hub-phase-2/`, with a copy outside the worktree at +`…/scratchpad/sdd-backup/`. They are working artifacts: everything a resuming session actually needs +is in this file, the plan, and the spec. + +## 8. Outstanding for the owner, unrelated to this phase + +Point-in-time recovery is still **off** on the live Supabase database (`#1K6T35`). Only the owner can +turn it on, from the Supabase dashboard. diff --git a/docs/superpowers/plans/2026-08-22-developer-hub-phase-2.md b/docs/superpowers/plans/2026-08-22-developer-hub-phase-2.md new file mode 100644 index 000000000..82d7e4e0d --- /dev/null +++ b/docs/superpowers/plans/2026-08-22-developer-hub-phase-2.md @@ -0,0 +1,3127 @@ +# Developer hub Phase 2 (repo awareness) Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Fill the developer hub's four `phase: 2` panels — routes, documentation, test health, and review state — from one build-time snapshot of data the repository already keeps on disk. + +**Architecture:** One TypeScript generator reads four existing sources (the site-map route walker plus `src/lib/app-modes.ts`, the `docs/` tree, `tests/flake-ledger.json`, and `docs/branch-review-records/`) and writes a single committed `data/repo-awareness-snapshot.json`. One staleness gate regenerates it in memory and fails with the fix command on any content difference. One typed reader imports that JSON so the bundler inlines it, and four Server Component routes render it under the existing `DeveloperAreaGate`. Nothing reads a file at request time, and nothing calls a network. + +**Tech Stack:** Next.js 16 App Router (React 19 Server Components), TypeScript 6 strict, Vitest (`node` + `jsdom` projects), Tailwind 4 `@theme` tokens, `tsx` via `scripts/run-tsx.mjs`. + +**Spec:** `docs/superpowers/specs/2026-08-22-developer-hub-phase-2-design.md` + +**Phase 1 record** (context, not requirements): `docs/superpowers/plans/2026-08-21-developer-hub-phase-1-COMPLETION.md` + +## Global Constraints + +Every task's requirements implicitly include this section. + +- **Never read a file at request time.** The runtime Docker stage copies only `.next`, `public`, `node_modules`, four named source files, `package.json` and `next.config.ts`. `docs/` and `data/` are absent in production. Data reaches a page by `import`ing a JSON file so the bundler inlines it — never by `readFile`. +- **Pages under the development route tree are Server Components.** No `"use client"` on a page. A component that attaches an event handler needs `"use client"` as its own first line; a Server Component must never import _data_ from a `"use client"` module, because Next replaces such an export with a client-reference proxy that has no array methods. Both classes shipped past every gate in Phase 1. +- **`npm run build` is a mandatory acceptance gate, not an optional extra.** It is the only gate that catches a Server Component reading data from a client module. These routes are Dynamic, so the build does _not_ catch a serialised handler — that needs a live request. +- **The snapshot must be byte-deterministic.** No `generated_at`, no `Date.now()`, no value derived from the current time. Anything time-relative (has a quarantine expired?) is computed at render time, never stored. A non-deterministic field makes the staleness gate fail on every run, and a gate that cries wolf stops being a gate. +- **No silent row-dropping.** A malformed input fails the generator loudly and names the file. A value the renderer does not recognise is rendered as it stands under its own heading, never discarded — a page that quietly under-reports is the `#338` failure this feature exists to prevent. +- **An empty section says so in words.** "No tests are quarantined" — never a blank container, which is indistinguishable from a load failure. +- **Counts are computed once by the generator** and rendered as given, so a count and its own list cannot disagree. +- **Design tokens only.** `text-[color:var(--text-heading)]`, `border-[color:var(--border)]`, and friends. No hex literals — `eslint-rules/no-hardcoded-hex.mjs` fails the build. Tap targets are `min-h-12`; never "fix" them down to `min-h-11`. +- **Every `