Each queue act is a dispatched Run of the queue workflow, once it is named (queue step, part 1)

Merged
DO
7d ago
+416-68

Part of #381, "A narrow queue App, combsmith-sf-queue, enqueues and dequeues with contents and pull-request write alone (P-2)": the queue step's first part of three. Record 0128, on the Factory Builder's word. Part of #182.

Each of the queue App's acts, an enqueue, a dequeue and a resolution, becomes a dispatched Run of the queue workflow, as an approval is a Run of the approval workflow. Nothing changes live yet. workflows.queue stays null, so each act is still recorded not_built until parts 2 and 3 land the step and its workflow. accounts.queue must also be set, which waits on P-39's re-read.

For the Maintainer's review: protected paths edited

  • kernel/brakes.py:
    • A landed enqueue or dequeue Run is outside the Run ceiling, as a landed approval is, since the timeline already counts both among the acts.
    • A failing enqueue is held by its own jobs alone: its attempts, then its own Runs at max_runs_per_item. An existing rule (FR-39) lets an approved item's enqueue go ahead at the Run ceiling, so this is not the shared ceiling a failing resolution meets.
    • A dequeue's own jobs that keep failing hold the item at the Run ceiling, for the Maintainer to stop the merge.
  • config/controller.json: workflows.queue: null.

What changes

WhereWhat changed
kernel/terms.py, adapters/records.pyIntents enqueue-merge and dequeue-merge, read as a pull request's Runs, which ask for no contract
kernel/decide.pyA dequeue waits on its own job in flight, and is never sent beside it; another Intent's Run in flight still never delays it
controller/writes.pyQUEUE_INTENTS; queue_workflow, the queue file only when its account is set beside it; the plan's dispatch_queue writes
controller/pass_.pyOnce the queue workflow is named, a Run id is minted for each queue act and it is dispatched under its Intent's run-name
adapters/effects.pyThe pass job's token may dispatch the queue file once it is named, with the three inputs a Run takes; expected holds the plan to its record
adapters/facts.py, controller/__main__.py, harness/read.py, harness/reread.pyrun_files_of: every Run list reads the queue file once it is named
controller/reconcile.pyA queue act's dispatch is matched to its pass's record
schemas/, examples/invalid/controller/1's workflows.queue; dispatch_queue in writes/1 and written/1
tools/mutants.py43 mutants this story touches, each killed by its test when run alone on the final tree
Records and docs0128 is new; the design's line that enqueue and dequeue have no run record, and that the Controller's App dequeues, now says the queue App's Runs

Declined

  • An unidentified Run deferring queue acts (security #4). Record 0036 lets an unidentified Run stop no enqueue. A second queue Run sent while the first is unnamed is answered by the queue step in part 2, which reads the item again and sends nothing it finds done.

Parts 2 and 3

  • Part 2, the harness: harness/queue_step.py mints from QUEUE_APP_KEY, finds the Decision by Run id, reads the item again, asks still_wanted, makes the one write and reads it back, and records applied/1 and outcome/1. The enqueue is bound to the decided head by expectedHeadOid, which is owed to a trial the Release lane is recording. Reconciliation will match the queue App's writes to that record.
  • Part 3, the workflow: queue.yml and queue-job.yml in factory-queue, the check_workflows rules for them, and naming workflows.queue.

Verify

  • make verify on an export of 9dbc8af: 1,526 tests, all OK but one. tests.test_hooks.Identity.test_the_spellings_that_ran_long_are_read_in_linear_time, which times the identity hook's CPU and which this change does not touch, failed under load (3.23 s against 1.31 s at half). It then passed alone three times of three.
  • make verify on an export of the merged head c0313fa: 1,526 tests OK (8 expected failures), the timing test among them. CI is green there.
  • The 43 mutants this story touches were each run on their own on the final tree and killed; every mutant's text appears once and compiles, and no two share a name. The full mutant run is CI's.

Reviews

All four read 8f1b73e. The fix round is 9dbc8af; nothing has re-read it.

ReviewerHeadUnread partsBlockingMajorMinorInfo
claude-review8f1b73enone0320
claude-security8f1b73enone0130
agy (parts 1, 3, 4 and 5: high; part 2: medium fallback)8f1b73enone0520
muse8f1b73enone0300
FindingSeverityCriterionWhereWhatDisposition
claude-review#1majorPR-3controller/pass_.py:292A dequeue is minted and dispatched again every pass while its own Run is still in flight, and after any number of failuresfixed in 9dbc8af: the Kernel waits on a dequeue's own job in flight, and its jobs that keep failing hold the item at the Run ceiling
claude-review#2majorPR-3controller/reconcile.py:41dispatch_queue in reconcile's DISPATCHES has no test; the mutant that drops it survivesfixed in 9dbc8af: a reconcile case and a mutant
claude-review#3majornonedocs/decisions/0128-each-queue-act-is-a-dispatched-run-of-the-queue-workflow-once-it-is-named.md:12A landed enqueue or dequeue counts nowhere when workflows.queue is named before accounts.queuefixed in 9dbc8af: the queue file is used only once accounts.queue is set too, so a landed enqueue or dequeue is counted among the acts
claude-review#4minornonecontroller/AGENTS.md:12Rule 'A Run id is minted for an admission or an approval alone' is now false once workflows.queue is named, and is not updatedfixed in 9dbc8af: controller/AGENTS.md, the design and pass/1's title name the queue acts
claude-review#5minorPR-3kernel/brakes.py:122A cancelled or never-started enqueue Run counting toward the Run ceiling is not held by a testfixed in 9dbc8af: cancelled enqueue jobs reach the Run ceiling; a case
claude-security#1majorPR-3controller/pass_.py:268Naming workflows.queue while accounts.queue is null leaves landed enqueues and dequeues counted by neither ceilingfixed in 9dbc8af: as claude-review#3
claude-security#2minorPR-3controller/pass_.py:292A dequeue is now an unbounded Run, dispatched again on every pass even while an earlier dequeue Run is in flightfixed in 9dbc8af: as claude-review#1
claude-security#3minorPR-3controller/reconcile.py:41Reconciliation of a dispatch_queue write has no test: a mutant dropping it from DISPATCHES survivesfixed in 9dbc8af: as claude-review#2
claude-security#4minornonekernel/decide.py:97Enqueue and resolution are now Runs but skip the unidentified-Run deferral that decision 0036 gives every Rundeclined: record 0036 lets an unidentified Run stop no enqueue, and changing it would hold every enqueue; the queue step (part 2) reads the item again and sends nothing it finds done, which answers a second Run sent while the first is unnamed. Record 0128 says so
agy#1majorPR-3docs/decisions/0128-each-queue-act-is-a-dispatched-run-of-the-queue-workflow-once-it-is-named.md:14Failing dequeue-merge Runs are unbraked and dispatch without bound once workflows.queue is namedfixed in 9dbc8af: as claude-review#1
agy#2majorPR-3tools/mutants.py:4754Mutant "an approval's failed attempts stop an enqueue" is a no-op once "enqueue" is in run_actsdeclined: enqueue is not in run_acts at this head (its ceiling is enqueue_ceilings), so the repointed mutant is not equivalent; it is killed
agy#3majorPR-3tools/mutants.py:11826Six new kernel/brakes.py mutants name test_each_landed_resolution_counts_toward_the_act_ceiling instead of enqueue/dequeue testsfixed in 9dbc8af: the enqueue and dequeue cases have a test of their own, which those mutants name
agy#4majorPR-3tools/mutants.py:11835kernel/brakes.py enqueue ceiling mutants omit >= boundary mutants and since/unlanded filter mutantsfixed in 9dbc8af: the >= boundary mutants for the enqueue's attempts and Run ceiling and the dequeue's Run ceiling
agy#5majorPR-3tools/mutants.py:11862No mutant holds dequeue / DEQUEUE_MERGE in adapters/records.py, controller/writes.py, controller/pass_.py, or adapters/effects.pyfixed in 9dbc8af: twins for the dequeue in the records port and the intent map
agy#6minorPR-3docs/architecture/software-factory-design.md:1256An in-progress dequeue-merge Run does not defer subsequent passes from dispatching duplicate dequeue-merge Runsfixed in 9dbc8af: as claude-review#1
agy#7minorPR-3tools/mutants.py:11857No mutant flips workflows['queue'] is not None to True in adapters/effects.py or controller/main.pyfixed in 9dbc8af: a mutant that permits the queue file with nothing named
muse#1majorPR-3controller/pass_.py:324A dequeue is re-dispatched as a new Run while its own dequeue-merge Run is still in flightfixed in 9dbc8af: as claude-review#1
muse#2majorPR-3controller/reconcile.py:41Reconciliation of a queue dispatch is unheld: dropping dispatch_queue from DISPATCHES survives every relevant testfixed in 9dbc8af: as claude-review#2
muse#3majorPR-3harness/reread.py:22The approving act's re-read never lists the queue workflow, so its Kernel re-ask is blind to queue Runsfixed in 9dbc8af: the Run's read and the approving act's read again list the queue file too, through adapters/facts.py's run_files_of

šŸ¤– Generated with Claude Code