Skip to content

Feat/task ac write surface - #144

Merged
andy-esch merged 4 commits into
mainfrom
feat/task-ac-write-surface
Aug 25, 2026
Merged

Feat/task ac write surface#144
andy-esch merged 4 commits into
mainfrom
feat/task-ac-write-surface

Conversation

@andy-esch

Copy link
Copy Markdown
Owner

No description provided.

…id itself off

audit-lint-fix-for-legacy-finding-status-debt is deprecated, not completed — the work
was never done, it stopped being needed. Its own criterion 2 said to measure before
repairing and to close if the answer was none. The answer is none: `audit lint` passes
on all 13 audits, and every odd-looking status token a raw grep finds sits in prose
ABOUT the parser rather than in a finding header.

The debt was real when the task was written and was paid off by other work:

  * the P2 abort that hid it is fixed, which is why measuring is possible at all;
  * the emoji half — its largest item — went obsolete when M2 made the parser
    decoration-tolerant, so `**Status:** ✅ fixed` reads correctly and lints clean;
  * the legacy words it wanted to normalise are gone (`landed`) or promoted
    (`tracked` is now a first-class status, not something to map away).

Criteria 3–5 are wontfix carrying that reason, which is the state vocabulary doing
exactly what it was built for: the task closes with its abandoned criteria explaining
themselves rather than as five silently unticked boxes.

H2 and L1 of 2026-08-17-finding-status-surface are superseded on the same evidence —
L1's own recommendation called it "mostly an argument for H1", and H1 shipped, so
agents now resolve findings through a validated write path. What remains of it (warn
rather than refuse on an $EDITOR save) is a deliberate choice for the human whole-file
path, not a fallback. That audit is 6/6 and closed.
Evolving a task's acceptance criteria was the one structure-aware write with no
surface at all, so doing it meant dumping the body to JSON, patching the markdown by
hand, and pushing it back with --body-file. Every criterion edit in the last few
sessions went through that round-trip, including adding the criterion that asked for
this.

    task ac <task> --add "Retries stop at the configured ceiling"
    task ac <task> --replace 3 --text "Backoff is jittered"
    task ac <task> --remove 4

Narrow operations over conventions the tool already owns, which is what M4 of
2026-07-24-ai-agent-cli-ergonomics asked for — explicitly not a general markdown
editor. Three decisions worth naming:

  * A reworded criterion KEEPS its checkbox and any state suffix. Rewording is not a
    change of mind, and silently dropping a `wontfix` and its reason because the
    wording changed would lose a decision — `--check`/`--defer`/… change that
    deliberately.
  * --add requires an existing `## Acceptance criteria` section. Creating one means
    guessing where it belongs in a body the tool did not write, and a heading in the
    wrong place is harder to notice than a refusal.
  * Added and reworded text is wrapped to match the corpus, measured in runes. The
    scanner learning that criteria wrap was a prerequisite: before it, appending after
    a wrapped criterion would have landed inside its continuation.

--add lands after the last criterion rather than at the end of the section, so it
cannot fall past a trailing note; --remove takes all of a wrapped criterion's lines;
and add→replace→remove round-trips the untouched criteria byte-for-byte, which the
CLI test asserts against the file on disk.
…ft behind

A lookback over this branch's own work.

**One wrapper, one margin.** Two sessions produced two hard-wrappers doing the same
job at different widths — wrapNote at 80 for a finding's resolution, wrapCriterion at
88 for a criterion — with the rune-counting and the never-break-before-`**` rule
duplicated in both. They are now one wrapProse at one proseWrapWidth, because the
corpus is written at one width by hand and two arbitrary margins show up as ragged
diffs between adjacent lines.

**Layout the tool writes should look like layout a person writes.** Adding the first
criterion to a section that had a heading and no criteria butted it straight against
the heading; removing the last one left the blank line above AND below it. Every
other block this tool writes is separated by exactly one blank line.

**A silent no-op.** `--text` without `--replace` fell through to the list view:
criteria printed, exit 0, nothing written. That is the shape a mistyped flag name
produces, and the same class as the empty `--status` fixed last session. It is now a
validation error, and `--list` is registered as mutually exclusive with every writing
flag rather than only with --check/--uncheck.

**Documented rather than changed:** rewording a criterion whose state suffix is
typo'd drops the typo, because an unrecognised suffix is part of the criterion's text
by design (splitCriterion leaves it for lint rather than guessing). Said out loud in
the doc comment so it is a decision rather than a surprise.

`schema task` now names `task ac` as the owner of acceptance criteria, for the reason
the audit conventions name `audit finding`: a criterion reachable only by hand-editing
markdown is one the tool cannot keep well-formed.
The one gap from this branch's lookback too big to fold in. The TUI now SHOWS a task's
acceptance criteria — the detail header carries a roll-up with the finding glyphs — but
cannot change one: `grep -rn SetCriterionState internal/tui/` returns nothing, so every
flip drops to the CLI, which is the one thing the browser exists to avoid.

The asymmetry is new. Before the vocabulary, a criterion was a checkbox in body prose
and reading it in the rendered markdown was the whole story. Now it carries a decision,
the header advertises it, and the surface that advertises a decision is the natural
place to make one.

Scoped with its open questions unanswered rather than guessed — in particular whether
it covers state changes only or criterion authoring too. Flipping a state is a decision
made while reading; adding or rewording is authoring, which `task edit` may serve
better, and that call belongs before the code rather than inside it.
@andy-esch
andy-esch merged commit 0459088 into main Aug 25, 2026
1 check passed
@andy-esch
andy-esch deleted the feat/task-ac-write-surface branch August 25, 2026 11:35
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