task_fix · v1.3.14 · 2026-09-05 · sha256 f3955edc732fb829

task_fix v1.3.14B

Immutable. This exact content is served forever at /api/v1/blob/f3955edc732fb829.

---
name: task_fix
description: Repair the whole tasks backlog tree in one pass and assess its backlog-coherence by default. Use when the user asks to health check, clean up, audit, or lint the backlog, to check backlog coherence or consistency, to say whether selected tasks ship together, or to autonomously resolve backlog judgement calls. Run the archive inclusive linter, fix mechanical frontmatter, status, location, link, datetime, and provenance issues inline, and gate coherence repairs on acceptance or escalate.
version: 1.3.14
author: Andreas F. Hoffmann
license: MIT
---

# task_fix

<task_fix_skill>

<role>
task_fix health-checks the whole `tasks/` tree and repairs what it safely can. It is the task-backlog analogue of `wiki_fix`. It runs a four-phase loop (orient → assess → remediate → verify), auto-fixes the mechanical findings the linter reports, surfaces judgement calls for review by default, and ends with a concise report. Its assess phase also runs the base `task` skill's `<backlog_coherence>` joint assessment on every invocation, default-on: it reads the selected live tasks together with the artifacts they target, judges them against each other and against the code as it stands, and reports a per-task verdict plus a ship order. Coherence writes stay gated: the assessment reports, and reconcile runs only on the user's acceptance or through the escalate path. On explicit autonomous-resolution opt-in, or on a scale trigger the user confirms, it escalates those judgement calls to `auto_shaper_task`, which becomes the single serialized writer for that run. It operates on the *whole tree* (distinct from `task_audit`, which verifies *one task* against the codebase, and `task_check`, which judges *one task's* readiness before building).
</role>

<when_to_activate>
Activate when the user wants the task backlog as a whole audited, tidied, or judged for backlog-coherence:

- "Health-check my tasks" / "clean up the backlog" / "audit the task list" / "lint and fix the tasks tree."
- "Do these ship together?" / "check backlog coherence" / "is the backlog consistent?" / "should some of these be altered or deferred to stay coherent with each other and the current code?"
- "Resolve the backlog judgement calls autonomously" / "run the autonomous task tree shaper" / "let task_fix handle the splits."

Ordinary backlog phrasing is enough for the second group: coherence, consistency, or whether the selected tasks ship together. No special jargon is required, because every everyday invocation already runs the assessment; that phrasing emphasizes or narrows the run rather than switching it on.

Route elsewhere when the user wants to judge a single task's readiness before building (`task_check`), automatically repair one task until it is ready (`task_auto_check`), choose what to work on next (`task_select`), verify one believed-done task against the codebase (`task_audit`), create a task (`task_create`), implement one (`task_implement`), or close one out (`task_finish`).
</when_to_activate>

<design_note>
task_fix runs inline by default because most `tasks/` trees are small and the common fixes are mechanical. The autonomous path is an escalation inside this skill, not a second user-facing skill: `auto_shaper_task` is spawned only when the user asks for autonomous judgement-call resolution or confirms that the tree is large enough to justify the read fan-out. Backlog-coherence reconcile is assess-then-one-writer under that same exclusive-writer rule: the assessment always reports and never writes, and a run that reconciles picks exactly one writer for its accepted set: either task_fix writes inline, or `auto_shaper_task` writes serially as the sole writer, never both in one run. The spawned assess agents provide read-side proposals and verification; file-creating splits, task moves, cross-reference rewrites, and frontmatter stamps stay with the single writer so parallel writers never race on the shared link graph.
</design_note>

<authority>
The base `task` skill's `SKILL.md` is the single source of truth; read it and follow it rather than copying its rules. Its `<discover>` step locates `tasks/`, its bundled `lint.py --include-archive` is task_fix's archive-inclusive mechanical oracle (`<lint>`), its `<lint>` mechanically fixable finding set owns the shared auto-repair type list, and its `<archive>` workflow defines a status/location move (set `status`, bump `updated` from `date`, `git mv`, re-point cross-references, re-lint). These assets ship in the same plugin as task_fix.
</authority>

<path_resolution>
The bundled scripts (`discover_tasks.sh`, `lint.py`) ship in `scripts/` next to the base `task` skill's `SKILL.md`, not next to this one. After reading that base `SKILL.md` (per `<authority>`), resolve each script's absolute path by combining the directory you loaded it from with `scripts/<script-name>` and invoke that absolute path, never a bare `scripts/...`, which resolves against the current working directory (the target project) rather than the skill, and so finds the project's own `scripts/` or nothing. If the first invocation reports a missing file, re-resolve the absolute path once before treating the script as failed.

Resolve `auto_shaper_task`, `auto_reviewer_task`, `auto_verifier_task`, and `auto_gate_task` by their published names through the current harness's normal agent mechanism. When a harness exposes only file paths, those agents live in the same plugin at `../../agents/` relative to this skill directory.
</path_resolution>

<workflow>
Run all four phases in order.

1. **Orient.** Read the base `task` skill's rules once: naming, frontmatter, the `<body>` anatomy, the standard-markdown policy, the 300-line split rule, and the `<lint>` / `<archive>` workflows. These are the bar every fix honors.
2. **Assess.** Resolve `tasks/` via `<discover>`, run `lint.py --include-archive` over the tree, and bucket its findings (blocking / warn / info). Then walk every task applying the **best-effort advisory** checks the linter can't: *topic mixing* (one file covering two unrelated units of work; flag for a split), *single-shot-readiness* (a body that has fallen below the base skill's self-sufficiency bar: an empty section, a dangling "TBD", context that assumes the vanished original chat), *cross-link value* (a cross-reference to another task that does no work, judged against the cross-link discipline in the base `task` skill's `<markdown_policy>`), *body framing* (load-bearing content carried mainly by negatives, judged against the base `<body>` authoring rule. A genuine out-of-scope entry, deferred-alternative note, guardrail, or expected-state acceptance check is compliant and draws no finding), *artifact-edit placement* (a body that frames an existing-artifact edit as an append where the base `<body>` rewrite-in-place rule calls for superseding the affected passage; surface and propose rather than auto-fix, respecting its carve-outs and the instruct-vs-narrate line), *restated standing rules* (a body passage that instructs the implementer with a copy of a rule that the project's standing instruction documents, such as `CLAUDE.md` / `AGENTS.md` and equivalents, already own: read those documents and compare; the base `<body>`'s cite-don't-restate corollary is the rule source), and *count-stable references* (a body that refers to a mutable set by a frozen count or by an enumeration snapshot of the set's current members, judged against the base `task` skill's `<markdown_policy>` count-stable rule, whose legal subject-matter quantities draw no finding; surface it with the selector rewrite proposed rather than auto-fixing it).

   Then run the base `task` skill's `<backlog_coherence>` assessment over the selected live set in the same pass. It is default-on rather than a separate mode, so every everyday invocation produces both the mechanical findings and the joint assessment in one report. Take the selector from the user's request (a scope filter, an explicit list, or the whole live tree, defaulting to the whole live tree when they name no filter) and hand it to that block, which defines the selected live set C and the shared target-artifact set T from it, including which live tasks a named scope leaves out. Follow the block's own method rather than a task-by-task walk: read C in full, read T once, and write both of that block's indexes into the report as their own sections before judging anything: the shared-surface map keyed by artifact, and the design-question grouping keyed by the question each task answers. Naming them as sections the report owes is what forces the pairwise work; an assessment that goes straight to per-task verdicts reverts to the task-by-task walk without ever announcing it, and returns premise findings while the ownership, contradiction, and posture lenses quietly find nothing. Then apply the seven lenses and give each task the verdict its class requires, with the fields that verdict owes. Report the ship-order waves those verdicts imply, and name any unselected task the run touched only as context. The assessment is the phase-one deliverable for coherence findings: it writes nothing, and **Gated coherence reconcile** below owns the write half.

   When the user requested autonomous judgement-call resolution, or when the tree is large enough that the assess list will strain one context, present that escalation scope and continue only after the opt-in or confirmation is explicit.
3. **Remediate.** In the inline default, auto-fix the safe mechanical findings in place by applying the base `<lint>` mechanically fixable finding set across the whole tree. Use task_fix's archive-inclusive mechanics for tree-wide cases: status/location mismatch moves via the base `<archive>` workflow including cross-reference re-pointing; legacy archived non-terminal status becomes `status: finished`; provenance backfill writes the linter's git-history-derived value and falls back to the base `<user_name_chain>` when history yields nothing. For soft-pointer warnings, apply the base `<lint>` triage rule first, reading the hit's surrounding context and stripping only a confirmed line-number position claim; when the hit is a false positive such as a size, version, count, or quoted claim-shape, leave it untouched. For task_fix-only advisory repairs outside linter output, remove an unambiguous reverse-duplicate cross-link and reframe a negation-framed body finding only when the positive rewrite is mechanical and meaning-preserving. Bump `updated` from `date` on every changed file except when the only changes are the legacy provenance/status retrofit covered by the base `<bump_updated>` exception. Leave the judgement calls below untouched in the inline path: a cross-link whose value is a genuine call belongs in `<surface_for_review>`, never an auto-delete. Hold the coherence line here too: backlog-coherence findings from assess never enter the inline mechanical auto-fix set, so this phase auto-fixes only lint and other mechanical findings until the user accepts coherence findings or opts into escalate. In the escalated path, hand the full assessed defect set to `auto_shaper_task` and perform no inline writes for that run; the agent owns serial remediation and returns its verification report.

   **Gated coherence reconcile.** Coherence repairs land only on the user's acceptance of named findings or through the escalate opt-in, and the accepted set gets exactly one writer for that run. When every accepted repair is an anchor refresh, a premise-drift staleness fix, or a semantics-preserving additive `**Out of scope:**` note, apply them inline. When any accepted repair is a judgement reconciliation (a single-owner decision, a severity or posture change, a completed enumeration), hand the *full* accepted set to `auto_shaper_task` so the staleness items ride that same escalated write rather than a parallel inline path. Reconcile each accepted finding under the base `<body>` **Decide or label** procedure, preserve every edited task's frozen `## Goal`, honour the `<backlog_coherence>` **Status discipline** rule (leave a semantics-preserving repair's `status` standing and flag a contract-altering repair for re-check, never stamping `ready`), bump `updated` on every changed file, and re-lint archive-inclusive. Reconcile may run in the same invocation when the user accepts findings before this phase begins, or on a follow-up invocation that carries the accepted finding set.
4. **Verify.** For the inline path, re-lint and triage rather than chase zero-warn: drive blocking findings to zero and confirm the mechanical warns are resolved, while leaving the judgement-call warns (an oversized page that needs a split) surfaced-and-accepted for the user. The inline clean bar is **0 blocking, mechanical warns resolved, judgement-call warns reported**, not zero-warn. For the escalated path, require `auto_shaper_task` to re-run `lint.py --include-archive`, report each applied fix and surfaced issue, and stop only when the linter is clean for the verified defect set or no verifier-approved change remains.
</workflow>

<surface_for_review>
Surface these for human review in the inline path. When the user opted into autonomous resolution, route these to `auto_shaper_task` for verifier-gated repair unless the item says it remains human-owned. Coherence carries its own disposition on top of that split: user-accepted backlog-coherence findings from the assess-phase report reconcile under **Decide or label** through **Gated coherence reconcile**, while every unaccepted item on this list stays a surfaced judgement call the user decides.

- Oversized pages (>300 lines) that need a split.
- Scope ambiguity that needs a human call on the right `scope:` value.
- **Cross-links whose value is a judgement call**: a relatedness-only reference that might still be load-bearing. Flag it for the user; auto-removing on a value judgement risks stripping a genuinely organising link, so reserve the auto-fix for the unambiguous reverse-duplicate case.
- **Body-framing findings past the mechanical case**: surface every body whose load-bearing content is carried mainly by negatives; the auto-reframe covers only the direct, meaning-preserving inversion, so any rewrite involving a judgement call lands here for the user.
- **Artifact-edit placement**: surface a body that frames an existing-artifact edit as an append where the base `<body>` rewrite-in-place rule calls for superseding the affected passage. Propose the in-place rewrite, cite the base rule, respect its carve-outs, and apply the same instruct-vs-narrate boundary used for restated standing rules.
- **Restated standing rules**: surface every passage that instructs the implementer with a copied standing rule, quoting the matched rule from the standing instruction document and proposing the fix: replace the copy with a citation, or drop it when the surrounding text carries nothing else. The user's explicit go-ahead decides. Drift between copy and source is exactly the risk. In `## Acceptance`, the base contract's task-specific-gates clause draws the boundary: a generic project-gate item is such a restatement, while a task-specific executable check draws no finding. A body that merely narrates a rule's history (changelog-style context) draws no finding either; the check targets passages that instruct.
- **Contradictions between tasks**: name both sides and the dimension they disagree on, drawn from the `<backlog_coherence>` emergent-contradiction and posture-consistency lenses. The disposition is dual: user-accepted backlog-coherence findings reconcile under **Decide or label**, while findings outside the selected live set stay human-owned and surfaced.
- **Count-stable references**: surface a body that refers to a mutable set by a frozen count or by an enumeration snapshot of the set's current members, cite the base `task` skill's `<markdown_policy>` count-stable rule, and propose the selector rewrite as the fix: "all N live `task-family_*` tasks" becomes "every live `task-family_*` task". This entry remains human-owned on the escalated path as well, so it stays with the user rather than routing to `auto_shaper_task`: the rewrite widens a scope the frozen number had pinned, and confirming that the widened set is the one the task means is the user's call. A quantity the base rule keeps legal (a measurement protocol's run count or fixed denominator, a size extent, a number that is itself the artifact under edit) draws no finding.
- **Repeated-link findings**: surface each `repeated-link` warn for the user to decide, citing the base `task` skill's `<markdown_policy>` grouping rule rather than restating the grouping test. Apply the base `<lint>` repeated-link react protocol's read-only path: report the finding with the sections that link the named target and leave the regroup to the writer. This entry remains human-owned on the escalated path as well, because deciding whether to gather or keep a repeat is a prose judgement.
</surface_for_review>

<output_contract>
End with a concise report: the mode used (`inline` or `escalated`), a backlog-coherence assessment section, the per-file changes made, the final lint outcome (triaged as above for inline, agent-verified for escalation), and a closing line in the shape `audit complete — N issues resolved, K flagged for review`. Name every judgement call left for the user and include the `auto_shaper_task` report when escalation ran.

The backlog-coherence assessment section appears on every run, since the assessment is default-on. It names the selected live set and how the selector picked it, carries both indexes the assess phase wrote (the shared-surface map and the design-question grouping), gives each selected task its verdict with the evidence behind it and the fields that verdict class owes, names the ship-order waves, and states plainly that the joint read found nothing when the set is coherent. Keep the map in the report rather than dropping it after use: it is the evidence a shared-surface or contradiction verdict rests on, and a reader checking such a verdict needs the ownership rows it came from.

A surfaced fork is the one verdict class whose fields are written out as named elements, because it is the class most often reported half-finished. Its entry carries the options it is choosing between and, labelled as its own element, the suggested path this pass would take with the reason for it. Write that element even when the task already labels the fork itself, since the pass still owes the path it would take; a fork entry that lists options and stops has left the decision exactly where it found it, which is the failure this naming exists to prevent. `inline` and `escalated` stay the only two writer modes. Backlog coherence is an assess-phase section rather than a third mode token, so a run that only assesses reports the mode its mechanical remediation used.
</output_contract>

<family>
In the `task_*` family, each sibling does one job, then points to the next, and the base `task` skill is the hub that can do all of it:

- `task_create`: write one task file
- `task_check`: readiness gate before building (read-only)
- `task_auto_check`: autonomously repair one task until `task_check` reports ready
- `task_explain`: explain one task at a high level (read-only)
- `task_select`: choose and rank the next eligible task/action (read-only)
- `task_implement`: do the work
- `task_audit`: verify a believed-done task against the codebase (read-only)
- `task_finish`: close out (set status, bump `updated`, archive)
- `task_fix`: audit and repair the whole tasks tree **(this skill)**

These ship together as a family; any sibling may be absent if a deployment excluded it. The default manual chain is create → check → implement → audit → finish, with `task_auto_check` as an opt-in readiness repair loop, `task_select` a read-only chooser for what to work on next, and `task_fix` maintaining the tree.
</family>

</task_fix_skill>