{
  "version": "act 2.5.1",
  "slug": "run-work-loop",
  "name": "run-work-loop",
  "description": "Use to run, create, resume, or continue a work loop, in any phrasing (\"run the work loop\", \"resume the tracker\", \"continue the remediation loop\", \"create a work loop for this spec\", \"make this resumable\", \"work through this spec item by item\") and the quality loop (\"run the quality loop\", \"continuous quality\", \"quality ratchet\", \"architecture ratchet\", \"keep auditing and refactoring\"). Given a tracker, it resumes that tracker; otherwise it creates the requested one and starts it.",
  "url": "https://act101.ai/docs/skills/run-work-loop",
  "body_md": "# Run Work Loop\n\nA work loop is one markdown file that is the **entire resumable state** of an\nimplementation program. Any session, tomorrow, after a crash, or a different agent,\ncontinues the program with one instruction: *\"resume the work in `<tracker path>`\"*.\nProgress lives in the tracker or in a plan file the tracker points to, never in\nconversation memory.\n\nThe design rests on one separation of powers:\n\n- **Specs own acceptance.** What \"done\" means for every item lives in the spec\n  documents. The tracker points at spec sections and never restates them; two\n  sources of truth drift.\n- **The tracker owns ordering and state.** Which item is next, what state each is\n  in, where its plan lives, which commits closed it.\n- **Plan files own fine-grained progress.** Checkboxes inside an item's plan are the\n  resume state within the item; the tracker is the coarse state across items.\n\n## Entry: resume or create\n\nEvery invocation, whatever the verb, starts by locating the tracker:\n\n1. An explicit path in the request wins. Otherwise a named program (\"the\n   remediation loop\") maps to `<program>-work-loop.md`, and with neither, look for\n   `*-work-loop.md` at the repo root and under `docs/specs/`; one match is the\n   tracker, several means ask which.\n2. **The tracker exists: resume it.** Read its snapshot and its own resume protocol,\n   then execute that protocol from its first step (integrity check, hygiene, sync\n   gate, first open row). The tracker's protocol is authoritative over this skill\n   wherever they differ; it was written for that program. Never re-create, re-seed,\n   or reformat an existing tracker on a resume; reconcile only when the request is\n   to update it (see Idempotency).\n3. **No tracker: create it** with the process below, commit it, and then resume it\n   immediately unless the request was only to set it up.\n\n## Process (create)\n\n### 1. Gather inputs\n\nMost inputs are already in the conversation or the repo. Derive what you can and\nask only for what is missing, one question at a time.\n\n| Input | Source | Notes |\n|---|---|---|\n| Authority spec(s) | The approved spec docs this program implements | Required. Several are fine; the tracker lists the authority chain. |\n| Tracker path | User preference or project convention | Default `<program>-work-loop.md` at the repo root, a persistent ledger per the protocol's File-Location Convention (`../analysis-protocol/references/protocol.md`). Match any existing work-loop files. Its history ledger is `<program>-work-loop-history.md` beside it. |\n| Queue items | Spec sections or items, in execution order | One row per independently closeable unit. Reuse the spec's IDs (E1, R3, \u2026) when it has them; otherwise mint a short prefix per phase. |\n| Ordering and dependencies | Spec dependency notes, user decisions | Record as a note under the queue, not as prose scattered through rows. |\n| Verification floor | Project test, lint, and build commands (CLAUDE.md, CI config, justfile) | Per surface when the program spans surfaces (cargo for crates, vitest for a worker, repo checks for an action). Record each gate's measured wall time beside it. |\n| Hygiene check | The project's machine-hygiene command, if it has one (this repo: `scripts/loop_hygiene.sh check`) | Runs before every gate and at every close. Leaked temp files, orphaned tool processes, and stale build artifacts are the loop's own exhaust; they must be pruned by tooling, not noticed by the operator. |\n| Project hard rules | The project's CLAUDE.md | Inherit verbatim: no rules the project lacks, none of its rules dropped. |\n| Exclusions | Anything from a sibling work loop that does not apply here | Name them (\"scan-score tracking excluded: specific to the remediation loop\"). A named exclusion is a decision; a silent omission looks like an oversight. |\n| Workspace rules | Branch, worktree, concurrency, and push-cadence facts | E.g. \"a concurrent agent shares this checkout; wait out lock contention.\" Push cadence is an operator decision: a branch that is never pushed meets CI only at reconciliation, and local hooks are not CI. |\n\n**Branch and PR rules** (defaults; an operator instruction always wins):\n\n1. An explicit operator instruction about branches, merges, or PRs overrides\n   everything below.\n2. Absent instructions: on the default branch, create a work branch before the\n   first commit; on a non-default branch, keep working in it.\n3. At completion, open a PR for operator review. Merge only on explicit operator\n   request.\n\nThroughout: operator instruction > project convention > skill default.\n\n### 2. Generate the tracker\n\nRead `references/tracker-template.md` and instantiate it with the gathered inputs.\nThe template is the contract: every section exists because a failure mode demanded\nit (the template says which). Keep every section; tailor the contents.\n\nSeed the queue completely: every item from the authority specs gets a row at\ncreation, including far-future ones. A complete queue makes \"find the first\nnon-DONE row\" a total resume algorithm; a gap forces the resuming session to\nre-derive scope from the specs.\n\n### 3. Commit\n\nCommit the tracker as its own change, or together with the state change it records,\nnever apart from one. The tracker's credibility rests on one invariant: it is never\nstale relative to committed work. That starts at the first commit.\n\n## Idempotency\n\nRunning the create path against a program whose tracker already exists must be\nsafe. Reconcile instead of clobbering:\n\n1. Read the existing tracker fully.\n2. A row's state only moves forward here; only the resume protocol (doing real\n   work) moves states.\n3. Add rows for spec items that have none (amendments since creation), appended in\n   spec order with a dated Log entry saying what was added and why.\n4. A row that no longer applies becomes `DROPPED(evidence)`; rows are never\n   deleted, only archived (see the cap below).\n5. Report drift you noticed but did not change (a row whose plan file is missing)\n   rather than silently fixing it.\n\n## What the generated protocol guarantees\n\nThe load-bearing behaviors the template encodes. Understand them so wording can be\nadapted without breaking them:\n\n- **Plan \u2192 implement \u2192 review per item.** A `TODO` row gets a written plan (via the\n  project's planning skill if present, else per \"Planning an item\") before any\n  code; a `PLANNED` row executes the plan (via the project's execution skills if\n  present, else per \"Executing an item\") with checkboxes ticked as steps complete;\n  before an item closes, its changes get a review pass, and every review finding is\n  fixed in-item or captured as an F-row.\n- **Premise re-verification.** Specs record a baseline that drifts. A resuming\n  session verifies the spec's premises against live code before acting and records\n  drift as a dated spec amendment.\n- **Found-issue discipline.** Any defect discovered mid-item is in scope: nothing\n  is \"pre-existing\", nothing is parked in a follow-ups list. A blocking issue is\n  fixed inside the item; a non-blocking one gets a dated spec amendment plus an\n  `F-n` queue row with the same closing discipline as planned rows.\n- **Evidence-gated closing.** A row reaches `DONE` only when every acceptance\n  criterion in its spec section passes with shown output from the verification\n  floor. \"It should pass\" closes nothing.\n- **Same-commit state updates.** The queue row changes in the same commit as the\n  work it records, so any interruption leaves the tracker describing the last\n  committed state.\n- **One item at a time.** An item fully closes before the next begins. Parallelism\n  is a user decision recorded in the tracker's ordering notes.\n- **A hard cap on defunct rows, with a rolling archive.** An active tracker carries\n  at most **25 closed rows** (`DONE` / `DROPPED`) and no Log entry older than\n  **14 days**; everything beyond moves verbatim to `<program>-work-loop-history.md`\n  at every close and every sync, by a mechanical archive step, never a hand edit.\n  The tracker's integrity check **refuses** a tracker over either cap, so the cap\n  is met by tooling and a skipped archive shows up as a red check, not as a slowly\n  growing file. Archived rows stay allocated: IDs are never reused, cross-references\n  still resolve into the history ledger, and the integrity check counts archived IDs\n  in its uniqueness and contiguity checks. A re-opened finding gets a new row citing\n  the archived one; archived rows are never edited. Log rows are one line pointing\n  at commits and the row; detail lives in the row, the plan, or the commit.\n- **Machine hygiene is part of the floor.** The hygiene check runs before every\n  gate and at every close; on failure the loop prunes and re-checks. A gate that\n  stalls is diagnosed and killed, never waited out.\n- **Gates are inputs, never outputs.** The loop never adds a hook stage, a coverage\n  pass, or a CI job, and never lengthens a gate; the cost of every gate is the\n  operator's decision, cited in the tracker when it changes.\n- **Operator-owned branch and PR flow**, as in the rules above.\n\n## Planning an item (`TODO` \u2192 `PLANNED`)\n\nIf the project has its own planning skill, use it. Otherwise the plan must stand\nalone for an implementer with zero project context:\n\n- **One plan file per queue item** at the tracker's plans path (default\n  `.act/plans/YYYY-MM-DD-<id>-<slug>.md`, committed: plans are resume state).\n- **Header:** the goal in one sentence, the spec section it implements, and the\n  global constraints binding every task (verification floor, project hard rules),\n  copied exactly.\n- **Bite-sized tasks:** each task is the smallest unit with its own verify cycle:\n  write the failing check, show it fail, implement, show it pass, commit. Every\n  step names exact file paths and complete content or commands, with the expected\n  verification output. \"Add appropriate handling\", \"similar to task N\", and TBD\n  placeholders are plan failures.\n- **Interfaces between tasks:** when a later task consumes what an earlier one\n  produces, both state the exact names and signatures; an implementer sees only\n  their own task.\n- **Self-review before committing:** every requirement in the spec section maps to\n  a task; no placeholder survives; names used later match their definitions.\n\n## Executing an item (`PLANNED` \u2192 `DONE`)\n\nIf the project has its own execution skills, use them. Otherwise:\n\n- **Follow the plan exactly**, ticking checkboxes in the plan file as steps\n  complete.\n- **Run every verification as written and read its output.** A step is done when\n  its check passed, not when its code is written.\n- **Stop when blocked.** An unclear instruction, a missing dependency, a repeatedly\n  failing verification, or a plan that contradicts live code sets `BLOCKED(reason)`\n  on the row, records what is needed, and surfaces it. Pushing through a broken\n  premise creates work that must be undone.\n- **Subagent execution** (when the session runs subagents): one fresh subagent per\n  task, dispatched sequentially, never in parallel on one checkout. Each dispatch\n  carries the task's full text, the interfaces it touches, the global constraints,\n  and an output contract (status, commits, verification output). Review each task's\n  diff against its task text before dispatching the next; run one whole-item\n  review before closing the row.\n- **Review before closing**: findings are fixed in-item or captured as F-rows.\n- **Archive before closing**: run the archive step, then commit the close and the\n  moves together.\n\n## Variant: the quality loop (the architecture ratchet)\n\nWhen the request is a quality loop or continuous quality, the program is not a\nwritten spec but the **architecture ratchet**: a continuous `architecture-audit` \u2192\n`architectural-refactoring` \u2192 `verify-refactor` cycle that lifts structural health\none notch per pass and never lets it slide back. Everything above still applies;\nonly the source of acceptance and the queue lifecycle change.\n\n**Required sub-skills**, invoked, not reimplemented:\n\n- `architecture-audit` produces `report.md` and `project-map.md`, and owns the\n  Refuted ledger and the improving / stable / degrading trend verdict.\n- `architectural-refactoring` executes confirmed findings, commits each step, and\n  appends to `remediation-log.md`.\n- `verify-refactor` is the per-change behavior-preservation gate (SAFE / REVIEW /\n  UNSAFE / UNKNOWN).\n\n### Same separation of powers, different sources\n\n| Generic work loop | Quality-loop instance |\n|---|---|\n| Specs own acceptance | The audit `report.md` and `project-map.md` own acceptance. A finding is done only when a re-audit's fresh structural evidence confirms it resolved, never on an agent's assertion. The tracker points to finding IDs and never restates the finding. |\n| Tracker owns ordering and state | The tracker owns the cycle number, the current phase (AUDIT \u2192 REMEDIATE \u2192 RE-AUDIT), and which findings are open this cycle. |\n| Plan files own fine-grained progress | `remediation-log.md` owns per-finding progress; its append-only rows keyed to finding IDs are the equivalent of a plan file's checkboxes. |\n\nThe durable state is three artifacts: `project-map.md` (current structure),\n`remediation-log.md` (actions taken), and the tracker (which cycle and phase).\n*\"Resume the quality loop in `<tracker>`\"* rehydrates entirely from these.\n\n### The queue is regenerated, not seeded upfront\n\nEach audit pass produces the queue: one row per confirmed actionable finding in the latest `report.md`, in remediation priority order (cycles > god classes > high coupling > dead code). The generic `Spec \u00a7` column becomes **`Finding ID + report ref`**. Refuted and re-characterized entries never become rows; a smell investigated and disproven is recorded in the map's Refuted ledger and stays there.\n\n### Running it\n\nIf no quality-loop tracker exists, generate one (specialized per the table above)\nbefore driving the cycle. Then:\n\n1. **AUDIT.** Invoke `architecture-audit`. Record the cycle number and seed the\n   queue with its confirmed findings by ID. If the audit surfaces no confirmed\n   actionable findings and the trend is stable, the ratchet is at its floor: stop\n   and report.\n2. **REMEDIATE.** For each finding row, in priority order: invoke\n   `architectural-refactoring` for that finding (it plans along seams, executes,\n   re-runs the specific analysis, commits, and appends a `remediation-log.md`\n   row), then run `verify-refactor` on the touched functions. Close the row to\n   `DONE` only on a SAFE verdict and the finding's own analysis confirming it\n   resolved. UNSAFE or UNKNOWN blocks the row.\n3. **RE-AUDIT.** Invoke `architecture-audit` again. It folds the log into the map,\n   re-verifies each claimed fix against fresh structure, and surfaces the next\n   layer. A claimed-RESOLVED finding the structure contradicts is a regression and\n   re-enters the queue as a new finding. Increment the cycle and return to step 2.\n4. Repeat until an AUDIT pass hits the step-1 stop condition.\n\n### Found-issue discipline in the loop\n\nEvery issue surfaced during the loop is in scope, exactly as in the generic loop.\nThe audit is structural-only, so anything outside the dependency graph is\ninvisible to it and the tracker is its only durable home. During REMEDIATE:\n\n- **Blocking** (prevents closing the current finding correctly): fix it inside that\n  finding's remediation before its row reaches `DONE`.\n- **Non-blocking structural** (a new cycle, a fresh god object the audit will\n  re-confirm): append an `F-n` row now so it is tracked.\n- **Non-blocking non-structural** (a logic bug spotted while reading, a\n  `verify-refactor` `dropped_cleanup`, a missing test, any REVIEW / UNSAFE /\n  UNKNOWN verdict): an `F-n` row is mandatory, because no future audit will\n  recover it. A non-SAFE `verify-refactor` verdict is a found issue.\n\n`F-n` rows live in the tracker's Findings table with the same closing discipline as\naudit-derived rows.\n\n### Ratchet invariants\n\n- The Refuted ledger is carried forward, never dropped.\n- `remediation-log.md` is append-only: one row per verified step, keyed to a\n  finding ID, never rewritten or reordered.\n- The trend is monotonic by construction: a degrade becomes a finding and the loop\n  pulls it back.\n- Same-commit state updates still hold for the tracker's cycle and phase row.\n- The closed-row cap and rolling archive apply to the quality-loop tracker too;\n  the history ledger keeps every closed cycle's rows.\n\n### Named exclusions for the generated tracker\n\nA quality-loop tracker has no authority-spec chain, no per-item spec premise\nre-verification (the audit is the premise check), and no static far-future queue\n(each audit regenerates it). Name these exclusions in the generated file."
}