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
13 changes: 7 additions & 6 deletions .abcd/development/intents/planned/itd-82-drain-ledger-triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ We expect a rule-first eligibility filter, a lane that hands back on discovering

## What's In Scope

- **Eligibility, by field**: open; nothing unshipped in `blocked_by`; a `remedy:` field present; category one of `bug`, `documentation`, `drift`, `inconsistency`, `tech-debt`, `ux` (the fixable set); severity `minor` or `nitpick`. Excluded by field: `security` (always a person's), `major` and `critical` (the hand-back by default), and the decision categories `process`, `observation`, `architectural-insight`, `future-work-seed`, `lapse` (the run file's merits set). A host-delegated judgement (adr-25) reads the remedy for a user-visible or trust-boundary change and may only hand back.
- **Eligibility, by field**: open; nothing unshipped in `blocked_by`; a `remedy:` field present; category one of `bug`, `documentation`, `drift`, `inconsistency`, `tech-debt`, `ux` (the fixable set); severity `minor` or `nitpick`. Excluded by field: `security` (always a person's), `major` and `critical` (the hand-back unless the repository's drain record loosens it; no run flag does, decision 11), and the decision categories `process`, `observation`, `architectural-insight`, `future-work-seed`, `lapse` (the run file's merits set). A host-delegated judgement (adr-25) reads the remedy for a user-visible or trust-boundary change and may only hand back.
- **The `remedy:` field**: `capture` gains it (the older `suggested_fix` made first-class under the name the eligibility reads) and requires it of every new issue (ruling BX3 of 2026-09-29); an automatic filer with no fix writes `none (filed automatically)` (ruling H12 of the same day), which is ineligible until a person writes a real remedy with `capture remedy`; a record filed before the rule carries none, and is ineligible and listed as such.
- **The lane**: the implement loop keyed by the issue (decision 10 on `itd-2609201916151817`: the brief is the record and its remedy, the checks are this record's eligibility, the landing is `capture resolve --commit`), one lane per issue, one pull request per issue with the repository's merge rule applied, the run's identity never an approver, nothing pushed to a pull request after its merge is armed.
- **Reproduce, then fix**: the issue-keyed lane's definition of done, owned by the loop (decision 10 on `itd-2609201916151817`): a detector fails before the fix and passes after, and the adversarial reviewer stays the oracle with the detector as evidence for it.
- **The hand-back, routed by kind**: a user-moment issue is promoted to an intent draft (`capture promote`, `itd-119`'s verb, on `main` with its spec open; seeded from the issue; the issue gains the intent in `related_intents` and nothing else); a trust or safety rule is flagged as needing a decision record with the question stated, and nothing is minted; an issue above the run's severity, or in a category the run does not fix, is flagged as a person's with that reason; anything else is flagged with the proposed home named. The lane's partial work is discarded.
- **The hand-back, routed by kind**: a user-moment issue is promoted to an intent draft (`capture promote`, `itd-119`'s verb, on `main` with its spec open; seeded from the issue; the issue gains the intent in `related_intents` and nothing else); a trust or safety rule is flagged as needing a decision record with the question stated, in the summary and as a marker on the issue (decision 10), and nothing is minted; an issue above the run's severity, or in a category the run does not fix, is flagged as a person's with that reason; anything else is flagged with the proposed home named. The lane's partial work is discarded.
- **The mid-lane stop**: a lane that meets a decision stops, discards, and hands back with the reason, as a first-class outcome; the `handback:` field on the lane report is the loop's (decision 10 on the parent), and this record names the values drain reads from it (a reviewer's design finding, a second package, a user-visible change).
- **Order**: by category in the declared order `tech-debt`, `documentation`, `inconsistency`, `drift`, `bug`, `ux` (clean-ups and text first, on the evidence that they merge most often; behaviour changes last), then `nitpick` before `minor`, then oldest first; the run's summary states the rule.
- **Ceilings**: the pace rule bounds the run (at a window's end it writes `next_eligible_at` and exits; the next invocation continues); `--max <n>` caps issues attempted and `--until-empty` is the default's own name; the pull requests opened, the promotions made and the spend are counted in the summary, and a cap hit is named.
Expand All @@ -56,7 +56,7 @@ We expect a rule-first eligibility filter, a lane that hands back on discovering
- The lane, the validators and the landing: `itd-2609201916151817`; the pace: `itd-2609201925079472`.
- Picking among intents: `abcd build next` (`itd-2609211116005482`), the sibling run.
- Merging pull requests, planning promoted drafts, writing decision records: human gates by design.
- Any change to the ledger schema beyond the `remedy:` field; the run consumes `list`, `resolve` and `promote`.
- Any change to the ledger schema beyond the `remedy:` field and the decision-record marker (decision 10); the run consumes `list`, `resolve` and `promote`.
- Any estimate the agent makes of its own confidence as a reason to let an issue through.

## Decisions
Expand All @@ -72,6 +72,8 @@ Ruled by the product thinker on 2026-09-21, in the interview that revived this d
7. **Order and categories declared** over the ledger's own enum (scope above), so no implementer decides them alone.
8. **The classification is re-derived every run** and recorded with each disposition in the summary; nothing is written onto the issue for it (ruled 2026-09-21; the durable-field alternative is left for a ledger that outgrows re-derivation).
9. **The drain's remaining work is one plan** (ruled 2026-10-09): the product thinker grouped what the drain still needs to run end to end into this intent's plan: the judgement before a lane opens and the summary's remaining counts, plus three steps from issues (merged lanes finished, iss-2610090936460789; one issue or package held back for now, iss-2610090642385898; a pull request that leaves the merge queue put back, iss-2610090642376032). Pacing stays its own intent (itd-2609201925079472), built alongside; this intent builds on it. The drain joins the person's command list when this intent ships (ruling BX1 kept). Answer verbatim: "Group as proposed".
10. **The decision-record flag is also a marker on the issue** (ruled 2026-10-10, the first open question): a trust-rule hand-back writes a marker onto the open issue, naming the decision record it needs and stating the question, as well as the line in the summary, so a person finds it without the summary. It is a write to a record the run otherwise never edits, chosen knowing that; it is not the classification, which decision 8 keeps re-derived every run. Answer verbatim: "Marker on the issue too".
11. **`major` is let through by the repository's drain record, never by a flag** (ruled 2026-10-10, the second open question): invariant 19 already lets a repository's record loosen its rule to `major`, and a drain never runs looser than its record, so there is no `--allow-major`; abcd's own record keeps `nitpick` and `minor`. Answer verbatim: "Record only, no flag", given when the first answer, "Opt in with --allow-major", was put beside invariant 19.

## Prior Art

Expand All @@ -96,16 +98,15 @@ Surveyed 2026-09-21 by an independent research pass, primary sources where they

## Open Questions

- **The decision-record flag's home.** A line in the summary only, or a marker on the issue the person finds without the summary; the marker is a write to a record the run otherwise never edits.
- **Whether `major` may ever be let through.** The default sends it to the hand-back; a `--allow-major` flag is the obvious opt-in, and whether a person wants it is not yet known.
_All resolved: the decision-record flag's home by decision 10, and whether `major` may ever be let through by decision 11 (both ruled 2026-10-10)._

## Acceptance Criteria

- **Given** an open ledger holding a `minor` `bug` with a `remedy:` field, a `minor` `bug` without one, a `major` issue, an issue in category `security`, a `process` issue, and an issue blocked by an open record, **when** `abcd drain` runs, **then** only the first goes to a lane; the one without a remedy is listed as ineligible; the `major`, the `security` and the `process` issues are handed back with the kind named; the blocked one is skipped naming its blocker; and every open issue receives exactly one recorded disposition.
- **Given** an eligible issue whose remedy the host judgement reads as a user-visible or trust-boundary change, **when** the pass classifies it, **then** it is handed back with that reason, and the judgement never makes an ineligible issue eligible.
- **Given** an eligible issue, **when** its lane runs, **then** it is the implement loop's issue-keyed lane: the brief is the record and its remedy, the loop's definition of done holds (a detector fails before the fix and passes after), the record is resolved with the fix commit in the same change, one pull request is opened with the repository's merge rule applied, and nothing is pushed to it afterwards.
- **Given** a decision-shaped issue that describes a user moment, **when** it is handed back, **then** an intent draft exists seeded from the issue, the issue gains the intent in `related_intents` and nothing else, and no design or adoption verdict is recorded.
- **Given** a decision-shaped issue that turns on a trust or safety rule, **when** it is handed back, **then** it is flagged as needing a decision record with the question stated, and nothing is minted.
- **Given** a decision-shaped issue that turns on a trust or safety rule, **when** it is handed back, **then** it is flagged as needing a decision record with the question stated, in the summary and as a marker on the open issue, and nothing is minted.
- **Given** a lane whose report carries `handback:` (a reviewer's design finding, a second package or a user-visible change the remedy did not name), **when** the loop reads it, **then** the lane stops, its work is discarded, the issue is handed back with the reason, and the summary records the stop as its own outcome.
- **Given** the default run, **when** eligible issues remain at a window's end, **then** the run writes `next_eligible_at`, exits, and the next invocation after it continues; **given** `--max <n>`, **then** it stops at the cap and names it.
- **Given** the command page, **when** it is read, **then** it states what `drain` does, its flags, the category order, the hand-back kinds and every refusal.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ under the pace rule.
done, resolve and pull request apply (criterion 3).
5. **The hand-back, by kind**: user moment → `capture promote <iss-N>`
(itd-119's verb) and nothing else written; trust rule → a flag in the
summary with the question; above severity or outside the fixable set →
summary with the question and the decision-record marker on the open
issue (decision 10); above severity or outside the fixable set →
a flag naming the rule; other → a flag with the proposed home; a
`handback:` on a lane report → the lane discarded and the same routing
(criteria 4, 5, 6).
Expand All @@ -57,7 +58,10 @@ under the pace rule.
## Out of scope

- The lane's internals (the parent); picking among intents (the sibling).
- Writing a classification onto the issue (decision 8).
- Writing a classification onto the issue (decision 8); the decision-record
marker is a hand-back's flag, not a classification (decision 10).
- A run flag that lets `major` through (decision 11): a repository's drain
record loosens its own rule.

## Approach

Expand Down Expand Up @@ -92,6 +96,9 @@ ADR is minted in the first delivery and reviewed with the diff.
5. A pull request that leaves the merge queue is put back (iss-2610090642376032)
- packages: internal/core/implement/loop
- tests: a landed pull request left unqueued at CLEAN is enqueued, and one dropped after a failed merge-group check is reported with the failed check
6. The decision-record marker on the issue (decision 10)
- packages: internal/core/issueschema, internal/core/capture, internal/core/implement
- tests: a trust-rule hand-back writes a `decision_needed:` field holding its question onto the open issue and changes nothing else in the record; the dry run and the next drain pass a marked issue over with the marker as its reason; invariant 19 and the drain page name the marker

## How the criteria are satisfied

Expand All @@ -101,7 +108,7 @@ ADR is minted in the first delivery and reviewed with the diff.
| 2 judgement only hands back | scope 3 |
| 3 the issue-keyed lane | scope 4 |
| 4 user moment promoted, `related_intents` stamp only | scope 5 |
| 5 trust rule flagged, nothing minted | scope 5 |
| 5 trust rule flagged and marked, nothing minted | scope 5, step 6 |
| 6 handback stops and routes | scope 5 |
| 7 window exit; `--max` | scope 7 |
| 8 the summary | scope 8 |
Expand Down Expand Up @@ -156,4 +163,5 @@ until the run itself closes it.
- **Remaining:** scope 3 (the host judgement over each eligible remedy; the run
opens a lane for every eligible issue until it lands, and only the lane can
hand its issue back), and the counts of scope 8 not yet in the summary (the
spend).
spend), and the decision-record marker on a trust-rule hand-back (decision
10).
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
schema_version: 1
id: "iss-2610101610446956"
slug: "abcd-intent-ready-reported-itd-82-ready-while-abcd-build"
severity: "minor"
category: "inconsistency"
source: "agent-finding"
found_during: "build of itd-82, 2026-10-10"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/surface/cli/build.go"
remedy: "make intent ready run the open-questions check that build runs, so READY means build will start"
---

abcd intent ready reported itd-82 READY while abcd build itd-82 refused it at check (open_questions) for two open questions in its record: the readiness verb does not run the check the build makes, so READY does not mean the build will start.
Loading