Skip to content

merge queue: checking #1332 on main (0d8f2e0), stacked on 4 pull requests ahead - #1339

Closed
mergify[bot] wants to merge 20 commits into
mainfrom
mergify/merge-queue/436c2a0822
Closed

mergify[bot] wants to merge 20 commits into
mainfrom
mergify/merge-queue/436c2a0822

Conversation

@mergify

@mergify mergify Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

⏳ The pull request #1332 is queued for merge and currently being checked. ⏳

#1332 is queued for merge on branch main (0d8f2e0).

Stacked behind 4 pull requests queued ahead of this batch, not part of it. These checks run on a tip that also carries their commits, so a failure here can come from them as much as from #1332.

Queued ahead of this batch:

This pull request has been created by Mergify to speculatively check the mergeability of #1332.
You don't need to do anything. Mergify will close this pull request automatically when it is complete.

Required conditions of queue rule admin-bypass for merge:

  • check-success = test
  • check-success = lint
  • check-success = validate

Required conditions to stay in the queue:

---
all_scopes: false
checking_base_sha: 669b5ef93323c6eaff287284c1072df9409eebff
previous_check_retries: []
previous_failed_batches: []
pull_requests:
  - number: 1332
    scopes: []
scopes: []
...

EdbertChan and others added 20 commits October 10, 2026 23:28
Reflect was writing a new preference whenever someone reminded the agent of a skill it had already skipped. Add lesson_route.py so that signal stays an intervention for ordering, and the lesson bucket is already-covered unless no skill states the preference yet.

Co-authored-by: Cursor <cursoragent@cursor.com>
Change-Id: Ibb2d3e90a7cf01987aeb14b71e9413d7cec536c3
The boundary-parser allow mark stays, and the comment checker treats that mark as a machine directive so the two gates agree.

Co-authored-by: Cursor <cursoragent@cursor.com>
Change-Id: I0a048d4d387df53de81d2638521a5198de499b36
Hook runs belonging to the same harness event had no shared key, so
grouping them for herd/wall-clock metrics relied on fragile 2s-window
inference. Add event_uid = sha256(stdin)[:12] to _row() so every
runner that receives the same stdin self-groups with zero coordination.
…runner metrics row gains an event_uid field that groups all hook runs belonging to one harness event, with no change to hook stdout, stderr, or exit codes.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/run.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.

Exit code: 0
Invoker-Finalize-Id: 5330cf4f-7efd-43e4-9fc5-fbc19b9c9a89
…770-8d121c9e — Review claim: Every runner metrics row gains an event_uid field that groups all hook runs belonging to one harness event, with no change to hook stdout, stderr, or exit codes.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/run.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.
tests/test_install.py and engine/hooks/_runner/tests/test_wrap_installed.py
asserted one settings entry per hook, so every per-hook guarantee they check
failed once CATSTACK_HOOK_DISPATCHER (#1122) collapsed an event to a single
_runner/dispatch.py entry: 70 failures and 1 error on #1122's head, all in
these two files.

load_config() in tests/test_install.py now reads an installed config and
expands a collapsed event back into one entry per hook, resolving each hook's
registration the way dispatch.py itself does (dispatch.load_event_hooks: the
cursor registry, or the hook's own manifest for claude and codex). Each
assertion therefore sees the identical shape in both layouts and keeps
checking the same guarantee -- right event, right harness, Stop mirrored to
SubagentStop or opted out, dead entries pruned, non-catstack entries
untouched. test_wrap_installed.py's fixture pins the flag off, since it
asserts the settings bytes install writes rather than a hook's registration.

#1122's own test_default_is_off_and_byte_identical_to_no_flag_at_all now
compares the default install against an install that sets the flag to
whatever flags.py resolves as the default, and clears the key from its own
environment first, so the flag-on run of the full suite cannot leak into the
"default" side of the comparison.

The CATSTACK_HOOK_DISPATCHER default is left off. Flipping it on is gated on
both full-suite runs passing, and the source branch
plan/hook-backlog-1c-install-tests-accept-the-one-entry-per-event-layout-default-on-only-if-both-suites-pass
never changed engine/hooks/_flags/flags.py, so that gate was not met there
and this commit does not claim it.

Cherry-picked from 6330abf on that branch.
The branch's two other content commits (engine/hooks/_runner/doctor.py,
scripts/test/run_skill_scenarios.py) are unrelated to this claim and are
left behind.
…ew claim: tests.test_install and test_wrap_installed accept both install layouts (one entry per hook with CATSTACK_HOOK_DISPATCHER off, one dispatcher entry per event with it on), and the flag defaults to on only if bash scripts/test/run_all_tests.sh passes with the flag on and off.

Review lane: behavior
Safety invariant: If either suite run fails, the default stays off. Per-hook guarantees stay checked in the dispatcher layout.
Files: tests/test_install.py, tests/test_wrap_installed.py
Change types: test
Acceptance criteria: This workflow publishes one pull request for the install-layout claim only.

Exit code: 0
Invoker-Finalize-Id: f459f9c9-a623-4fd7-9708-21cc3ae4cbda
…s/g0.t0.a-a464d403f-4908b6a4 — Review claim: tests.test_install and test_wrap_installed accept both install layouts (one entry per hook with CATSTACK_HOOK_DISPATCHER off, one dispatcher entry per event with it on), and the flag defaults to on only if bash scripts/test/run_all_tests.sh passes with the flag on and off.

Review lane: behavior
Safety invariant: If either suite run fails, the default stays off. Per-hook guarantees stay checked in the dispatcher layout.
Files: tests/test_install.py, tests/test_wrap_installed.py
Change types: test
Acceptance criteria: This workflow publishes one pull request for the install-layout claim only.
`report.py --scorecard` folds runs.jsonl into one row per
(phase, event type) and prints procs/event, cpu_ms/event,
wall_ms/event, timeout%, crash% and spoke-rate. Rows are split into
"before" and "after" by whether the row carries a `dispatch_path`,
and grouped into events by `event_uid` (falling back to the row index
when a row has no uid), so one harness event counts once no matter how
many detectors ran under it.

The phase split and the proc count read the row field the runner
actually writes, `dispatch_path`. An earlier draft of this fold read
`dispatch_mode`, which no row has: every post-dispatcher row then
landed in the "before" bucket and the after-phase proc count never
credited the dispatcher, so the scorecard showed no change at all.

`--days N` is accepted alongside `--since` so the canary window can be
given in whole days.

Tests: two cases in engine/hooks/_runner/tests/test_report.py drive the
CLI over a fixture ledger holding one pre- and one post-dispatcher
event; they assert the per-phase numbers and the printed column header.
Both fail against the base report.py with "unrecognized arguments:
--scorecard --days 14".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
….py --html folds runs.jsonl and events jsonl once into summary.json and emits a static dashboard.html on demand, with no server and no change to any hook behavior.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/report.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.

Exit code: 0
Invoker-Finalize-Id: e5a0edf3-e934-4a17-8242-75988f61e013
…478-adac8c27 — Review claim: report.py --html folds runs.jsonl and events jsonl once into summary.json and emits a static dashboard.html on demand, with no server and no change to any hook behavior.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/report.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.
The fleet self-saturates: one SubagentStop burst spawned 15-30 processes
that each re-parsed the same transcript, measured at 15.1s p50 wall idle
against 1.55s for a single process, with per-hook durations escalating in
launch order.

dispatch.py now runs opted-in detectors in-process, sequentially, parsing
the event once and passing the same parsed payload to every detector. A
hook opts in with subagent_stop.dispatch in its manifest, naming a
MODULE:FUNCTION entry point (default detect:detect). A detector with no
resolvable entry point still runs as a subprocess and its metrics row is
marked subprocess_fallback. Each detector keeps its own verdict, its own
runs.jsonl row under its own hook name, and its own rule_ids; a detector
that raises, exits, or overruns its 4s soft budget is caught and recorded
without stopping its siblings. The event budget defaults to 9s for
SubagentStop. mirror_stop_hooks_to_subagent_stop.py emits one dispatcher
entry for the opted-in hooks and leaves every other hook's direct entry
alone.

(cherry picked from commit 531f5c8 on
plan/hook-fleet-dispatcher-measure-the-herd-then-dispatch-it)
…op hooks dispatch through one process that parses the event once and shares one transcript parse across all opted-in detectors, emitting the same per-detector metrics rows and verdicts as the subprocess fleet.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/dispatch.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.

Exit code: 0
Invoker-Finalize-Id: aaa80940-f2d5-4d79-bb40-79c68fe333ad
…e5bede34 — Review claim: SubagentStop hooks dispatch through one process that parses the event once and shares one transcript parse across all opted-in detectors, emitting the same per-detector metrics rows and verdicts as the subprocess fleet.

Review lane: behavior
Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims.
Files: engine/hooks/_runner/dispatch.py
Change types: bugfix
Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.
…son-route-already-covered/drop-lesson-router-comments-failed-comment-gate--0a048d4d

Drop the lesson-router comments that failed the comment gate.
@mergify mergify Bot mentioned this pull request Oct 11, 2026
4 tasks done
@mergify mergify Bot closed this Oct 11, 2026
@mergify
mergify Bot deleted the mergify/merge-queue/436c2a0822 branch October 11, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant