Context
stale-directives reports an acknowledgement that answers for no site.
Since ADR-119 and ack.trim_settled, luria repair removes one class of
these, a code in an inactive-ok whose document is in force. It leaves the
rest. Its stated reason is that a retired code nothing cites any more may
mean the citation moved, and whether the directive should move with it is
a judgement. ADR-136 keeps judgements out of repair.
On a large record the rest is most of them. Nucleation’s lint listed 282
such directives in 267 files (dmarx/nucleation#357), cleared by a script that
parsed the report’s text and misread a whole-directive finding as a per-code
one, so it had to be run twice. After luria 1.7.0’s trim, 69 more remained
(dmarx/nucleation#391). A further 275 directives that were still in use
named 336 codes that answered for nothing. The lint did not report those,
because Scan.used asks whether a directive answers for anything, not
whether each of its codes does.
Decision
luria repair --prune_stale removes every acknowledgement code that answers
for no site, and deletes a directive left naming nothing. The default
luria repair, and so the generate action, are unchanged.
-
The config can set it, like every repair flag.
luria.yaml’srepair:table holds the standing value of each flag ofrepair.run, all off by default. The command line overrides a key for one run (--noprune_stale). A record that setsprune_stale: truehas made the judgement once, where everyone reading its config can see it, and the CI repair then prunes on every pull request. A test holds the rule that every flag has a key, so a flag added later is configurable too. An unknown key or a value that is not true or false is refused at load. -
What “answers for no site” means depends on the kind.
inactive-okandunresolved-okclaim a state, so a code is idle when no citation in this scan has the directive as itsexcused_by. That coverstrim_settled’s case, and also a code made redundant by an earlier directive that answers first.mention-okclaims nothing about state and must survive a status change that hands its site to another directive (ADR-105). So amention-okcode is idle only when no site in its scope cites it at all. -
The guard is a re-scan, not an argument. Before writing, the repair counts the citations no directive answers for, by file and code. It counts by file and not by line, because deleting a directive’s line moves the lines below it. After writing it counts again. If the counts differ, every file is restored and the repair raises
PruneChangedFindings, naming the citations that moved (DP-001). -
Out of reach: a malformed directive, whose problem is already the finding; an expired one, which the scan does not see; and every other directive kind.
Alternatives considered
- Prune in the default repair, as #385 proposed. The guard makes it safe for the findings, but not for intent. A directive whose citation moved a line is best moved, not deleted, and the default repair runs in CI on every pull request, where nobody chose that. DP-010: this is a write a person turns on, not a guard they turn off.
- A lint check that relation-field citations need no excuse.
relations. relation_spansalready blanksuses:,rests_on:and the other relation fields before citations are read. So a directive excusing only those already answers for nothing and is already reported. - Report idle codes in the lint and leave removal to people. That was the status quo for whole directives, and it produced the hand-written scripts.
- Flags on the command line only. The CI repair is a shared action, and
a record would have to fork its workflow to pass a flag. The config is
where a record already states its standing choices, such as
lint.fail_on. - Compare the findings by line. Every deleted line would then register as a change.
Consequences
- A record can clear its stale acknowledgements in one command. Fired on a
copy of Nucleation after dmarx/nucleation#391: 336 codes in 262 files, the guard passed,
stale_annotations()stayed at 0, and a second run changed nothing. It took about 100 seconds, two full scans. - A directive’s reason may still name a code the prune removed. The reason
is the person’s prose, and the repair does not edit it, as
trim_settleddoes not. - The lint still does not report a single idle code in a directive that is in use, apart from a settled one. Reporting them would make this flag the remedy for a finding on every large record, which is a separate decision.