Kernel: what is admitted on an issue, and what apply checks again

Merged
DO
2d ago
+1928-13

Closes #42.

The issue side of the Kernel now decides what is admitted on an issue, and what apply checks again before it acts. It's still in its own module: issue.decide sits beside issue.derive in kernel/issue.py, with its own schema, issue-decision/1. decide.py, derive.py, terms.py and gate.py are untouched. The rulings are on #42, and decision 0031 records them.

What changes

  • Admission: in triage, an investigating Run, then a readiness Run, then nothing; in ready, the opening Run.
  • The Controller's three acts:
    • it accepts an issue;
    • it removes a label that no longer counts, but only an App's or the machine user's, never a person's, not even in a same-second tie;
    • it places a Hold when linked pull requests close unmerged too often.
  • Labels and acceptance: while acceptance has lapsed, no label is removed in new, so the Maintainer's warning stands.
  • A Run in flight: the brakes are asked about that Run's own Intent, over completed Runs only, before anything the Run wrote is read. Its comment or factory:ready counts only once it completes. A Run in flight can't hide attempts_exhausted or run_ceiling. This is the same rule #158 applies on the pull-request side.
  • An App's comment or label stands in for a Run only once that Run's record has expired.
  • Intents that share an App defer with intents_share_an_app.
  • What apply checks again: two new facts, acts_since_writer and branch_head.
  • issue_labels() is built from t.CONTROL_LABELS plus the issue's own labels: CodeRabbit's note on #155. It's a function rather than a constant, because check_purity allows only constants at module level.
  • Intent codes: JUDGE_READINESS and OPENING are adopted from #41.
  • Capacity and concurrency deferrals apply as on a pull request.

Left out:

  • Issue stale times are filed as #165, "Kernel: an issue goes stale as a pull request does".
  • Whether a brake's Hold also adds the factory:hold label is decided with controller/.

Verified:

  • make verify passes (632 tests) on a plain git archive export with PATH=/usr/bin:/bin. The record was renumbered there only, for the gap until 0030 merges.
  • All 202 issue mutants were checked by hand against their tests, and all are killed. CI's shards run the set.
  • check_decisions is clean.

Reviewed by: a fresh-context Claude review, a security pass, and AGY (Gemini 4 Argon) on f2ba92b. All their findings are fixed in 5ada0b3 except #165:

  • AGY's blocker: a Run in flight hid the brakes' Holds;
  • the lapsed-acceptance warning lost to a label removal;
  • an App's comment counted too early;
  • two Intents sharing an App;
  • a person's label removed in a same-second tie;
  • a boundary with no mutant.

AGY is reading 5ada0b3 again, since the fix restructured Kernel logic.

Order: merges after #156 (decision 0030).

šŸ¤– Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added issue triage decisions that can accept or hold an issue, remove non-counting labels, and admit investigation, readiness, or pull-request work.
    • Added configuration for enabling or disabling these issue intents and assigning roles and apps.
    • Added checks that defer work when issue information is unreadable, another run is in progress, or issue state, content, or branch head has changed.
  • Documentation
    • Documented issue admission rules and the information recorded for issue decisions.