Skip to content

Plan 3: Job & phase scaffold + KB foundation#1

Merged
Ryfter merged 24 commits into
masterfrom
plan3/job-scaffold
May 26, 2026
Merged

Plan 3: Job & phase scaffold + KB foundation#1
Ryfter merged 24 commits into
masterfrom
plan3/job-scaffold

Conversation

@Ryfter

@Ryfter Ryfter commented May 26, 2026

Copy link
Copy Markdown
Owner

Summary

Plan 3 of the coding-agent-orchestrator vision. Adds a persistent job lifecycle with phase tracking, lesson capture, a two-layer knowledge base, and a read-only Jobs panel on the Plan 2 dashboard. Foundation only — no multi-model dispatch yet (that's Plan 4+).

  • 7 new slash commands: /job-start, /job-status, /job-list, /job-phase, /job-resume, /job-lesson, /consolidate-lessons
  • Hook + OTel parser now tag every journal line with job: + phase: when a job is active (backward-compatible — Plan 1/2 lines still parse and still emit untagged when no job is active)
  • New ~/.claude/jobs/<id>/ and ~/.claude/knowledge/{universal,projects/<id>}/ directory structure
  • Plan 1's model-routing.md migrated into knowledge/universal/routing.md
  • Dashboard: new Jobs panel + drill-in route /jobs/<id> with per-phase cost breakdown
  • 21 commits, 5 PS1 test suites + 56 pytest tests all green

What this branch contains

Layer What changed
PowerShell New scripts/job-lib.ps1 (shared lib), new scripts/consolidate-lessons.ps1, extensions to scripts/hooks/log-tool-call.ps1, scripts/parse-otel.ps1, scripts/bootstrap.ps1
Slash commands 7 new .md files under commands/
Python (dashboard) New dashboard/readers/jobs.py, dashboard/routers/jobs.py, two new templates, extensions to dashboard/readers/journal.py, dashboard/models/events.py, dashboard/main.py, CSS additions
Docs Design spec, implementation plan, handoff notes
Tests 23 new PS1 assertions across 3 test scripts; 13 new pytest cases across 4 test files

Architectural decisions (and why)

  • Approach C (Claude Code IS the orchestrator, job files are persistence) was chosen over Approach A (slash-commands only, no persistence) and Approach B (Python state-machine daemon). B was rejected as overengineered duplication of what Claude Code already does well. Job files are designed so a daemon could pick them up later if needed.
  • State file at `~/.claude/current-job.json` instead of session env vars — slash-command subprocesses cannot mutate the parent process's env, so a file is the only reliable cross-process signal.
  • Four phases (`research`, `design`, `code.sprint-N`, `review`) instead of seven. An earlier seven-phase model (brainstorm.brain-dump → refine → research → alternatives → sanity-check → design → design-check) was rejected as too granular. Inner activities live INSIDE phases as dispatch patterns; analytics granularity at four phases is sufficient.
  • Two-layer knowledge base (universal + per-project) requested explicitly by Kevin. Per-project KB is identified by git-remote slug, with a cwd-folder fallback.
  • CLI-first fleet philosophy (deferred to Plan 4): we wrap CLIs (claude, codex, antigravity, gh copilot, opencode, ollama) rather than direct APIs. APIs may be added in Plan 4 as fleet expansions.
  • Backward compatibility is non-negotiable. Existing Plan 1/2 journal lines still parse correctly. The hook still works when no job is active. All Plan 2 dashboard tests still pass.

What's deliberately deferred

Capability Lands in
Fleet config + multi-machine local Ollama Plan 4
Research ensemble + 6-Hats / LLM Council primitives Plan 5
Decompose + parallel-worktree code phase Plan 6
Claude + Codex pair review on diff Plan 7
Cockpit interactivity (new-job form, phase buttons, minimizable cards, drill-into-live-commands) Plan 7
End-of-job analytics debrief (token-by-phase, model breakdown) Plan 7
Embedding-based KB retrieval, auto-injection at job/phase start Plan 8
Two concurrent jobs in one Claude Code session future (v1 limitation, single state file = single active job)

Known follow-ups (not blocking)

  • `dashboard/templates/job_detail.html` uses a JS `setTimeout(location.reload, 30000)` for drill-in polling. Plan 7 will replace with proper htmx-partial polling on a 5s/30s split.
  • Brief renders as `
    `, not Markdown. Plan 7 enhancement.
  • `'abandoned'` job status is in the manifest schema but no command sets it. Plan 7.
  • `parse-otel.ps1` and `/consolidate-routing` still default to the old `~/.claude/model-routing.md` path (which is renamed to `.migrated` by bootstrap). Cosmetic — both still work post-migration.

Test plan

Run all tests after merging:

```powershell
pwsh -NoProfile -File scripts/test-job-lib.ps1
pwsh -NoProfile -File scripts/test-jobs.ps1
pwsh -NoProfile -File scripts/test-hook.ps1
pwsh -NoProfile -File scripts/test-otel-parser.ps1
pwsh -NoProfile -File scripts/test-consolidate-lessons.ps1
python -m pytest dashboard/tests/ -v
```

All should be green (verified on the branch).

Manual smoke (from a Claude Code session in the repo):

  • `/job-start "smoke test plan 3"` creates the job folder + state file
  • Any subsequent tool call appears in `~/.claude/model-routing-log.md` with `| job:j-… | phase:research` trailing tags
  • Dashboard Jobs panel shows the new job within 30s
  • Drill-in view at `/jobs/` renders brief, phase timeline, cost, lessons
  • `/job-lesson knowledge "smoke test note"` appears in drill-in
  • `/job-phase next` flips to `design` atomically (manifest + state + phase-log)
  • `/job-phase done` clears state file
  • `/consolidate-lessons` writes the lesson to `~/.claude/knowledge/projects/coding-agent-orchestrator/topics/general.md`

Documents to read for context

  1. `docs/superpowers/specs/2026-05-26-plan3-job-scaffold-design.md` — full design with rationale
  2. `docs/superpowers/plans/2026-05-26-plan3-job-scaffold.md` — 19-task implementation plan
  3. `docs/superpowers/notes/plan3-handoff.md` — start here if you're picking this up cold — 30-second picture, key contracts, decisions, what's deferred, how to verify, hints for Plan 4

Bootstrap migration note

Existing Plan 1/2 users: running `scripts/bootstrap.ps1` after this merges will migrate `/.claude/model-routing.md` into `/.claude/knowledge/universal/routing.md` and leave a `.migrated` sentinel so re-runs are idempotent. The deploy of new slash commands + lib scripts is also idempotent. Safe to re-run.

🤖 Generated with Claude Code

Ryfter and others added 24 commits May 26, 2026 12:53
Adds the design document for Plan 3: a persistent job model (manifest, brief,
phase log, lessons) with phase-tagged journal entries, slash commands for
lifecycle and lesson capture, a two-layer knowledge base (universal +
per-project), and a read-only dashboard Jobs panel. Foundation for Plans 4-8
(fleet, research/code/review phases, learning loop retrieval).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bite-sized tasks covering: job-lib.ps1 (state-file R/W, slug, project detect,
manifest/phase-log/sequence, lesson taxonomy), 7 slash commands (job-start,
status, list, phase, resume, lesson, consolidate-lessons), hook + OTel-parser
extensions for phase tagging via current-job.json state file, dashboard journal
parser + models extensions, jobs reader + router + templates + integration,
bootstrap migration of model-routing.md into knowledge/universal/, full TDD
loop per task with PS1 + pytest tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends PostToolUse hook to read ~/.claude/current-job.json (overridable
via $env:CAO_STATE_PATH) and append trailing `| job:<id> | phase:<phase>`
fields to journal lines when both values are present. Backward-compatible:
missing/empty/corrupted state files leave the Plan 1 line format unchanged.
Adds three Plan 3 tagging tests (no-state, active-job, corrupted-state).
Also fixes a PowerShell scalar-vs-array indexing bug in the test helper
(@() wrapper on Where-Object result) that caused false failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds lesson taxonomy ($script:LessonCategories) to job-lib.ps1 with
Test-LessonCategory, Get-LessonDefaultScope, Get-LessonCategories, and
Append-LessonToJob helpers. Adds /job-lesson slash command that appends
to lessons.md and writes a `lesson` journal line. Tests verify all
category/scope mappings and bogus-category rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reads CAO_STATE_PATH (or ~/.claude/current-job.json) once at startup and
appends ' | job:<id> | phase:<phase>' to each api_request journal line when
a valid state file is present; falls back silently to untagged output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Walk every job's lessons.md, route entries to KB files by category+scope,
mark source lines consolidated. Idempotent (second run is a no-op).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends parse_journal_line to strip trailing job:/phase: pipe fields
from any line type, threads them into HookEntry/OtelEntry/NoteEntry,
and adds a new 'lesson' source dispatched to LessonEntry (stubbed until
Task 13 adds the model). Five new tests appended (import of LessonEntry
will fail until Task 13).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ummary,Detail}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hase cost)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds FastAPI jobs router with constructor pattern (build_router), partial
/partials/jobs list endpoint, /jobs/{job_id} detail endpoint with 404
handling, and minimal stub templates sufficient for the 3 router tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds JOBS_ROOT module-level constant, wires app.state.jobs_root, includes
build_jobs_router in the FastAPI app, and adds 3 integration tests verifying
the jobs partial, detail page, and index card are all reachable via the main app.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… migrate routing.md

Extends scripts/bootstrap.ps1 with Steps 5b-5d:
- Step 5: foreach now includes all 7 Plan 3 commands (job-start/status/list/phase/resume/lesson, consolidate-lessons)
- Step 5b: deploys job-lib.ps1 + consolidate-lessons.ps1 to ~/.claude/scripts/
- Step 5c: creates ~/.claude/jobs/ and knowledge/universal/{topics}/+projects/ dirs; seeds 5 KB stub files
- Step 5d: migrates ~/.claude/model-routing.md into knowledge/universal/routing.md (idempotent via .migrated sentinel)
- Summary updated to Plan 3 scope with job/KB next-step hints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e + drill-in auto-refresh

- bootstrap.ps1 Step 6: skip legacy catalog seed when .migrated sentinel exists (prevents resurrection after Plan 1 → Plan 3 migration)
- job-lib.ps1 Append-LessonToJob: add Mandatory $Scope param; write ts | cat | scope | "text" (new format)
- consolidate-lessons.ps1: extend $lessonLineRe to capture optional scope field; prefer explicit scope over Get-LessonDefaultScope (backward-compat: old lines without scope field still work)
- dashboard/readers/jobs.py _LESSON_LINE_RE: tolerate optional scope field between category and quoted text
- commands/job-lesson.md: pass -Scope $scope to Append-LessonToJob
- test-consolidate-lessons.ps1: update fake lessons.md to new format; assert universal override lands in universal/mistakes.md, not projects/<id>/mistakes.md
- job_detail.html: add 30s auto-refresh via setTimeout(() => location.reload(), 30000)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Captures the 30-second picture, key data contracts (state file, journal
format, KB layout), decisions and their rationale, what's deferred to Plans
4-8, known follow-ups, E2E verification recipe, and a starting hint for
Plan 4 (fleet config + multi-machine local).

Designed so any LLM or developer can pick up where this branch left off
without rereading the full spec/plan.
@Ryfter

Ryfter commented May 26, 2026

Copy link
Copy Markdown
Owner Author

Execution log

For the record of how this branch was built (relevant if you're auditing the process, not just the result):

Process

  1. Brainstorming (superpowers:brainstorming skill) — 8 clarifying-question exchanges over architecture, phase model, KB layout, lesson taxonomy.
  2. Spec written to docs/superpowers/specs/2026-05-26-plan3-job-scaffold-design.md and committed (503 lines).
  3. Plan written (superpowers:writing-plans skill) to docs/superpowers/plans/2026-05-26-plan3-job-scaffold.md — 19 bite-sized tasks, ~3,200 lines, with exact code per step.
  4. Execution (superpowers:subagent-driven-development skill, sonnet for all subagents): 19 sequential implementer subagents on this branch, each producing a focused commit. Tasks 12+13 deliberately ship in a chained pair (Task 12's imports fail until Task 13 adds LessonEntry).
  5. Review streamlining: Task 1 went through the full implementer → spec-reviewer → code-quality-reviewer flow (caught 2 Important + 1 Minor; fixed inline). For subsequent tasks I dropped per-task spec + code reviewers and did one comprehensive final review at the end (sonnet, ~76 tool uses) given the plan's prescriptiveness. The final reviewer caught 2 Important + 6 Minor cross-cutting issues; the Important ones plus one Minor were fixed in a follow-up commit (6a0f9f5).

What the final review caught

  • Important — bootstrap migration idempotency: Step 6's Copy-WithPrompt was resurrecting ~/.claude/model-routing.md after Step 5d's migration moved it. Fix: skip Step 6 when the .migrated sentinel exists.
  • Important — /job-lesson --scope was parsed but ignored: scope wasn't persisted in lessons.md, so /consolidate-lessons always re-derived it from the category default. Fix: extended lessons.md line format from ts | cat | "text" to ts | cat | scope | "text"; consolidator + dashboard reader tolerate both formats for backward compat.
  • Minor — drill-in view had no auto-refresh: added a JS setTimeout(location.reload, 30000). Plan 7 will replace with proper htmx polling.

Five Minor issues were accepted as known-deferred: brief rendered as <pre> not Markdown (Plan 7), 'abandoned' status unused (Plan 7), ConvertTo-JobSlug uses 5 tokens not 4 (deliberate — plan's own test cases required 5), test-jobs.ps1 done-transition cosmetic (done → done in phase-log), parse-otel.ps1//consolidate-routing still default to legacy model-routing.md path (cosmetic — migration sentinel handles it).

TDD discipline

Every task followed red → green → commit:

  1. Write failing test
  2. Run, confirm failure with predicted error message
  3. Implement minimal code
  4. Run, confirm pass
  5. Commit

This is reflected in the linear commit history — 19 implementation commits (one per plan task) + 1 quality-fix commit on Task 1 + 1 post-review-fix commit + 1 README commit + 1 handoff-doc commit = 21 commits total.

Documentation chain (for cold pickup)

README.mddocs/superpowers/specs/2026-05-26-plan3-job-scaffold-design.md (full design with rationale) → docs/superpowers/plans/2026-05-26-plan3-job-scaffold.md (19-task plan with exact code) → docs/superpowers/notes/plan3-handoff.md (30-second orientation + key contracts + Plan 4 starter hints).

Plan 4 (fleet config + multi-machine Ollama) is the next slice and unblocks the actual multi-model dispatch in Plans 5-7.

@Ryfter
Ryfter merged commit 1fc5b77 into master May 26, 2026
@Ryfter
Ryfter deleted the plan3/job-scaffold branch June 4, 2026 08:29
Ryfter added a commit that referenced this pull request Jun 20, 2026
…t worker (#61)

* docs(worker-adapter): Sprint 6 design spec + release-tag drift fix

Spec for the GitHub Models worker adapter — a self-metering, budget-aware
fleet worker that closes the dispatch->meter->forecast->route-around loop.
Decisions d-wa-1..5. Also corrects the next-session release note (Sprint 5
shipped in stable v1.2.0; rc line closed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(worker-adapter): Sprint 6 implementation plan (5 TDD tasks)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(worker): rate-limit parser + api-hit test (Sprint 6 Task 1)

* feat(worker): adapter registry + report (Sprint 6 Task 2)

* feat(worker): seamed Invoke-Worker + Get-WorkerStatus (Sprint 6 Task 3)

* feat(worker): fleet-worker CLI + /baton:worker + github-models seed (Sprint 6 Task 4)

* build(worker): deploy manifest + asserts + plugin 1.3.0-rc.1 (Sprint 6 Task 5)

* fix(worker): bare 429 needs HTTP/rate context to signal a limit (review Minor #1)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Ryfter added a commit that referenced this pull request Jul 11, 2026
…pus review d079)

- Replace U+00B7 middle-dots with ASCII '|' in run-rate + by-model lines
  (honors the function's own ASCII-only console-encoding contract; would
  mojibake on a non-UTF-8 Windows console). Finding #1 (Important).
- Classify 403 / 'not accessible' as insufficient-scope so the gh-auth hint
  fires for scope failures that return 403 not 404. Finding #2 (hardening).
- New asserts: C3b (403 -> insufficient-scope), P1b (panel body ASCII-only)
  so both guarantees can't regress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ryfter added a commit that referenced this pull request Jul 14, 2026
… + Grok tweaks

Kevin approved the split after Codex draft + Grok adversarial review converged:
the stakes->tier work is a real subsystem, not a defaults flip. Addendum records
PR-A/PR-B scope, the 5 locked open-question answers (Codex+Grok consensus), and
Grok's SHIP-WITH-TWEAKS punch-list for the implementer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ryfter added a commit that referenced this pull request Jul 16, 2026
…il-open'

Under -AcceptanceFailLoud, a diff-provider throw and a no-verdict gate both
degrade the run to acceptance-degraded and halt, but the event text still said
'(fail-open)' at Level warn — a misleading ops narrative in exactly the case
this node exists to make loud. Narrate 'acceptance-degraded — run halts' at
Level error when fail-loud; keep '(fail-open)' + warn only on the advisory path.
Narrative-only; terminal status unchanged. Grok review nit #1 (SHIP AS-IS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ryfter added a commit that referenced this pull request Jul 16, 2026
…ode #1, PR-A) (#99)

* node #1: Codex-drafted design for /baton:go --execute defaults flip + roadmap currency

- docs/superpowers/specs/2026-07-14-go-execute-defaults-flip-design.md: design
  proposal (Codex, fleet-farmed) for flipping --execute quality nodes opt-in ->
  opt-out, fail-loud on degraded gates, and depth-matched-to-stakes logged
  routing. DRAFT — pending Grok review + Kevin sign-off on 5 open questions.
- docs/roadmap.md: post-v1.16.0 currency — mark Review Named Panel (node #2)
  SHIPPED, bump header.

d086 spine now tracked as GitHub issues #89-#97 on Project #5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* node #1: split into PR-A (gates flip) + PR-B (stakes); lock 5 answers + Grok tweaks

Kevin approved the split after Codex draft + Grok adversarial review converged:
the stakes->tier work is a real subsystem, not a defaults flip. Addendum records
PR-A/PR-B scope, the 5 locked open-question answers (Codex+Grok consensus), and
Grok's SHIP-WITH-TWEAKS punch-list for the implementer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(plan-gate): fail loud on degraded reviewer rosters

* feat(gate): fail loud on unusable panel roles

* feat(go): make execute governance default and fail loud

* test(otel): isolate parser state fixture

* fix(conductor): fail-loud acceptance events narrate the halt, not 'fail-open'

Under -AcceptanceFailLoud, a diff-provider throw and a no-verdict gate both
degrade the run to acceptance-degraded and halt, but the event text still said
'(fail-open)' at Level warn — a misleading ops narrative in exactly the case
this node exists to make loud. Narrate 'acceptance-degraded — run halts' at
Level error when fail-loud; keep '(fail-open)' + warn only on the advisory path.
Narrative-only; terminal status unchanged. Grok review nit #1 (SHIP AS-IS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Ryfter added a commit that referenced this pull request Jul 16, 2026
, PR-B) (#100)

* feat(go): add task stakes schema and override

* wip(test): executor depth-tier tests (Codex partial, usage cap hit mid-build)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(go): route task depth by stakes and log policy

* test+docs: PR-B review tweaks — depth_applied wording, positional-ABI proof, decisions.jsonl e2e, RequireVerify prose

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant