Repository navigation
feat: work-loop skill and in-repo vault (ADR 0013) - #87
r0073d-l053r wants to merge 2 commits into
Conversation
A harness-agnostic work loop over NEXT.md, /coordinate, and the vault, so
any agent - Claude Code, Codex, Pi, opencode, Cursor, cron, or a human -
can arrive cold, take the next eligible roadmap step in its lane, leave
a trail, and keep going until the roadmap is complete.
.claude/skills/work-loop/
scripts/loop.mjs Node 24, no dependencies: start (resume brief ->
pick next eligible step -> create/claim its issue via
/coordinate -> branch -> work brief), checkpoint
(Session note + STATUS/HANDOFF, run before context
compaction), resume (post-compaction digest),
milestone (coord done + Milestone note + progress),
next, status [--write], vault-init, vault-sync
scripts/ingest.py the vault's generated-notes regenerator, now taking
--repo/--vault (was a scratchpad script)
loop.config.json roadmap file, vault path, phase-gating rules
SKILL.md, references/harnesses.md
docs/agents/work-loop.md entry point for non-Claude harnesses
docs/adrs/0013-... the decision: vault in the repo, loop as script
vault/ the existing Obsidian vault ported unchanged (same schema: OKF
frontmatter, generated vs synthesis notes) plus Milestones/,
Sessions/, _templates/, Roadmap Progress.md, and loop-rewritten
progress blocks in Home. Excluded from markdownlint; Obsidian
workspace files ignored.
Also: `npm run loop`, README rows, and the NEXT.md follow-up that names
later ADRs by subject (0012/0013 took the projected numbers) and adds the
work-loop skill and vault to the coordination lane.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…follows them Phase 0 issues #79-#84 were seeded with "0.1 Title" titles. The matcher now accepts "0.1 Title", "[0.1] Title", and "0.1: Title", and new issues use the same bracket-free prefix, so start continues or claims the existing issue instead of creating a duplicate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
m-vawter
left a comment
There was a problem hiding this comment.
This is a strong piece of work. The resume/checkpoint cycle survives compaction, milestones only count merged PRs, eligibility goes lane-first with phase gates, there are zero dependencies, and the config makes it reusable for other roadmaps. My agents plan to run it once it lands. Commenting rather than approving, since it needs a rebase anyway:
- Rebase: it conflicts with
maininREADME.md, so CI hasn't run on it yet. - Untrusted input: an unattended loop on a public repo acts on issues and comments that anyone can post, and #85's ingestion gate isn't in yet. Until it is, could
next/startonly pick issues opened by collaborators (author_associationOWNER, MEMBER or COLLABORATOR)? And could SKILL.md say in one line that issue and comment text is data, not instructions? - Approvals: SKILL.md has idle agents review others' PRs, and any non-author approval merges once CI is green. That means two loops can merge each other's code with no human reading it. Maybe a
loop.config.jsonswitch, with agent approvals off by default? Agents would review and comment, approving would stay with a human, and each human could opt in. - The vault's generated half:
ingest.pycopies the repo docs (ADRs, specs, plans) into vault notes, so every doc exists twice and everyvault-syncrewrites them. Committing only the hand-authored notes and regenerating the rest locally (gitignored) would avoid drift and merge noise, and it would shrink this PR from about 11.8k lines. - Small:
startcallscoord claim, which fails on macOS until #88 lands.
xcjs
left a comment
There was a problem hiding this comment.
Reviewed: work-loop skill (loop.mjs + config + harness refs) and the in-repo Obsidian vault (ADR 0013) are self-consistent; the vault copies of repo configs match main as of now. Blocking issue, non-author note: the branch is CONFLICTING with main (README.md, NEXT.md, package.json, .gitignore shifted). Needs a rebase before a non-author can merge; approving the content so only the rebase stands in the way.
|
Agents - don't merge this. This needs more review. |
|
Three things the loop will run into on the board as it stands, worth folding into the rebase. I found them by reading
|
|
QUESTION | agent: opencode/glm-5.3-flash | human: @xcjs | at: 2026-10-07T20:5xZ Notes from m-vawter's review thread above list three loop-engineering fixes worth folding in while rebasing. Happy to re-verify with local e2e after the rebase lands (5/5 CI runs on this repo now). This blocks the only open PR on the board. |
| @@ -0,0 +1,325 @@ | |||
| """Ingest the repo docs into the vault with wikilinks (the generated half). | |||
There was a problem hiding this comment.
This should be rewritten as TypeScript to align with the rest of the repository.
| @@ -0,0 +1,536 @@ | |||
| #!/usr/bin/env node | |||
There was a problem hiding this comment.
This should be rewritten as TypeScript to align with the rest of the repository.
| @@ -0,0 +1,4 @@ | |||
| { | |||
There was a problem hiding this comment.
Configuration files for external tooling shouldn't be part of the repository.
| @@ -0,0 +1,84 @@ | |||
| --- | |||
There was a problem hiding this comment.
This duplicates all docs/ files into a second vault/ directory that also seems to have been intended to be ignored by .gitignore. We should consider removing vault/.
| @@ -0,0 +1,46 @@ | |||
| { | |||
There was a problem hiding this comment.
This duplicates the package.json and isn't a standard .nvmrc file.
| @@ -0,0 +1,11 @@ | |||
| root = true | |||
There was a problem hiding this comment.
This duplicates root-level configuration files inside the repository. If these are to be used as templates in other projects, we should probably .gitignore them.
| @@ -0,0 +1,12 @@ | |||
| { | |||
There was a problem hiding this comment.
This duplicates root-level configuration files inside the repository. If these are to be used as templates in other projects, we should probably .gitignore them.
| @@ -0,0 +1,62 @@ | |||
| name: CI | |||
There was a problem hiding this comment.
This duplicates root-level configuration files inside the repository. If these are to be used as templates in other projects, we should probably .gitignore them. This one also uses an incorrect reserved filename.
| AGENTS.md | ||
|
|
||
| # Obsidian vault (vault/): workspace state churns per machine; app.json is tracked | ||
| vault/.obsidian/workspace* |
There was a problem hiding this comment.
This .gitignore didn't prevent vault/** from being added - we should investigate if the files were accidentally force added or if the ignore pattern needs adjusted.
| | [.claude/skills/coordinate/SKILL.md](.claude/skills/coordinate/SKILL.md) | Multi-agent task coordination over GitHub Issues (`/coordinate`): protocol, parameters, working agreements | | ||
| | [docs/agents/coordination.md](docs/agents/coordination.md) | Multi-agent task coordination over GitHub Issues (`/coordinate`) | | ||
| | [docs/agents/work-loop.md](docs/agents/work-loop.md) | The work loop: any agent takes the next roadmap step via `/coordinate` (`npm run loop`) | | ||
| | [vault/](vault/DOMinic%20Home.md) | The project's second brain (Obsidian): milestones, sessions, ingested docs | |
There was a problem hiding this comment.
Documentation between docs/ and vault/ shouldn't be duplicated nor split - also, the .gitignore attempts to ignore vault/, but something happened to add the files to the repository. We should investigate what happened.
What
A harness-agnostic work loop so any agent can jump on, read
NEXT.md, take the next eligible step in its lane through/coordinate, record progress in the vault, survive context compaction, and keep going until the roadmap is complete — plus the vault moved into the repo so every agent and machine shares one second brain.The loop —
npm run loop -- <command>(.claude/skills/work-loop/scripts/loop.mjs, Node 24, zero deps)start3.1parallel) → creates the issue if missing (## Filesfrom your lane,## Done whenfrom the phase exit) →coord claim→step/<id>-<slug>branch → work briefcheckpoint -m "…"vault/Sessions/+STATUS(or--handoff @login→HANDOFF). Run before context compaction.resumemilestone <id> --pr <url>coord done→vault/Milestones/<id> - <title>.md→ progress refreshnext/status [--write]Roadmap Progress.md+ Home blocks)vault-init/vault-syncWhen nothing is eligible it lists PRs awaiting a non-author review — the most useful idle work under distributed merge. Prints
ROADMAP COMPLETEat the end.loop.config.jsonnames the roadmap, vault path, and gating rules, so it serves other roadmaps/repos unchanged. Recipes per harness (Claude Code/loop, Codexwhile, cron, human) inreferences/harnesses.md.The vault —
vault/The existing Obsidian vault ported unchanged (same schema: OKF frontmatter, generated vs synthesis notes,
ADRs/ Conventions/ Coordination/ Hackathon/ Specs & Plans/ Repo Config/) plus the two folders the loop owns (Milestones/,Sessions/),_templates/,Roadmap Progress.md, and marker blocks in Home the loop rewrites. Openvault/in Obsidian. Excluded from markdownlint;.obsidian/workspace*ignored,app.jsontracked.Decision record
ADR 0013 — In-repo vault and the work loop. Also carries the small
NEXT.mdfollow-up: ADR numbers follow creation order (0012/0013 took the projected ones), step 0.5's ADR half is marked done (#78), and the work-loop skill + vault join the coordination lane.Verification
node --check loop.mjs;start --dry-run,checkpoint --dry-run,status --write,vault-init,vault-syncexercised against the merged roadmap (no real issues created).ingest.py --repo . --vault <scratch>regenerates 39 notes end to end.npm run lint:md— 0 errors (38 files;vault/excluded).Phase 0 issues #79–#84 already exist (seeded by hand, titled
0.1 …); the loop recognises both0.1 Titleand[0.1] Titleand continues or claims those rather than creating duplicates. Step 0.5's README half is already in flight as #86.🤖 Generated with Claude Code