Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/coding-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ reappears in a new location, that is the signal to stop fixing instances one at
time. Instead, audit the whole surface for that class in a single pass, fix every
instance together, and — if the pattern is mechanically detectable — add a
linter or static-analysis rule so it can never silently return. The ledger is
strictly append-only: history is never rewritten, and a resolution is a *new*
entry that references the one it closes.
strictly append-only: a **row** is never edited, a resolution is a *new row*
that references the row it closes, and a row whose text is later found wrong
is corrected by appending a supersession **entry** rather than by editing it.
(*Row* and *entry* are distinct: rows are the ledger's records, entries are
the supersession markers that correct them.)

### Cross-cutting disciplines

Expand Down
66 changes: 66 additions & 0 deletions docs/hardening-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,72 @@ this project's `docs/hardening-taxonomy.md`; column 2 is the recurrence-grep tar
Never edit a row; resolve a `pending` row by appending a new row (same fingerprint,
`ref` naming the prior row's date + anchor).

A row records a hardening claim as of its date, and its narration may be found wrong or
made stale later. When a row's text no longer describes reality — falsified by a
later change, or wrong when it was written — append a `Superseded rows` entry rather
than editing it. One later change is **excluded**: a hardening that is itself removed,
for which this convention supplies no move at all (see the end of this paragraph). This
holds for every row without exception: the existing `Never edit a row` rule is
absolute, and correcting a row is always an append. The rule is bound to rows, not to
commits: once text exists as a row it is never edited, committed or not. Drafting
before a row exists — an editor buffer, a line not yet written — is below the
rule's resolution, and nothing checks one. Resolving a `pending` row also appends —
that is a new hardening, not a correction to a row's text. Supersession marks a row's
**text** and never alters mechanical behaviour, including when the entry records that
the row's hardening claim was itself false: the row keeps its fingerprint, keeps
matching the column-2 grep, and keeps counting. A hardening later removed is out of
scope.

**Correcting a row.** Corrections live in a `Superseded rows` block above the
`Columns:` paragraph — a `**Superseded rows:**` label carrying one appended line per
supersession, present only once at least one entry exists:

- <date> · supersedes <row date> `<fingerprint>` "<row fragment>" · what is false · where the current answer is

`<date>` is the day the entry is written, in `YYYY-MM-DD`. A row is located by date +
fingerprint. **An entry applies to every row its locator matches** — uniqueness is
not a requirement, and an entry that matches two rows says the same thing about both.
To narrow the match, add `"<row fragment>"`, a quoted fragment of that row's `finding`
carrying no double quote, in the position shown immediately after the fingerprint. **A
fragment narrows the match set; it singles out one row only where that row has one no
sibling shares** — a sibling being another row the same date and fingerprint match.
Where it has none — an identical `finding`, one that is a substring of a sibling's,
or one whose every unique fragment carries a double quote — the entry marks every
matching row, its accurate siblings included, and no fragment prevents that. Omit it,
quotes included, when you mean every row the pair matches — including when the pair
matches only one. Name the claim that does not hold — saying whether it stopped
holding or was never true — and cite where the current answer lives; restating that
answer here only makes the entry the next stale narration. Neither of those two fields
may contain ` · `: that separator is what divides them, and free text carrying it
makes an entry parse two ways. A fragment is matched **literally and case-sensitively
against the row's `finding` as written in the file**, escapes and markup included —
what you quote is what is in the table, not what a renderer shows you. **An entry
applies only to matching rows dated on or before the entry's own date** —
supersession marks the past, so a row dated later never comes under an entry written
before it. **A row's date is the day it is appended**, and the table is chronological:
backdating a row is forbidden, which is what makes the date bound mean what it says.
Nothing can verify the append day itself, and nothing checks that dates never decrease;
the rule is stated and read. An entry whose locator matches no such row is **inert**:
it governs nothing and is not an error to repair in place — append a new entry with a
locator that matches, and leave the inert one standing as history, like every other
entry. **An entry marks a row, and the last entry for a row is the one that governs**
— where a row carries more than one, later in the file wins and the earlier ones are
history. **A later entry must therefore describe the row as it now stands, not only the
newly found fault**, or it retires a still-accurate earlier entry from a reader's view.
Entries are never edited, never removed, and never reference one another — and they
take the same floor as rows: once a line exists as a complete entry it is protected,
committed or not, while a line that is partial or does not yet carry the shape above is
still drafting and may be fixed. A mistyped locator in a complete entry is corrected
the same way everything else is, by appending. If a union merge leaves two `Superseded
rows:` labels, keep one and keep every entry under it. No standing tool reads this
block — to every grep and skill scanning the table a superseded row is unchanged,
including one whose entry says its fingerprint is wrong; prose readers get the
correction, mechanical readers do not, and nothing checks the difference.

**Superseded rows:**

- 2026-08-12 · supersedes 2026-07-20 `truncated-tool-output-read-as-complete` · its `ref` states that an incomplete pass still increments the counter, including a failed review returning `{success: false}`; true when written, and it no longer holds for every pass · CLAUDE.md §5, the paragraph opening `` **What this does not do.** The hook counts on `PostToolUse` ``
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Columns: `date` (YYYY-MM-DD), `fingerprint` (canonical class), `finding` (short,
escape `\|`, one line), `source` (gate-a|gate-b|bot|manual),
`severity` (blocker|major|minor|nit), `rung` (e.g. `2 lint`, `4 test`, `1 prose`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Hardening round — the 0.8.0 cycle and PR #21 — Implementation Plan

> **Historical snapshot — executed and merged.** This plan records the state of things as they
> stood when it ran. It is **not** maintained against later changes and must not be read as
> current guidance. Its `never edit an existing row` / `Never edit a row` statements are **still
> accurate**: `2026-08-05-hardening-ledger-supersession-design.md` briefly narrowed that rule and
> then restored it, so the absolute wording stands and nothing here contradicts it. What *is*
> historical is narrower — the plan's desired-outcome wording predates that story's amended
> acceptance criterion 4, and its treatment of the row-D amend-during-authoring precedent is
> superseded: under the convention that row's correct move was an entry. Executed plans are
> deliberately left as written — a plan is a record of what was done, and editing one to match
> later rules would destroy that record — so this note is how the standing falsification sweep
> resolves them, rather than by rewriting.

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Land four hardenings from the 0.8.0 cycle and PR #21 as text, record them in four ledger rows, park what has no repair, and open five split stories — without changing any skill file.
Expand Down
Loading