Skip to content

lane sweep: triage — week of 7/20 (rolling paper-cut batch) #657

Description

@kyle-sexton

Rolling paper-cut batch per the v11 intake throttle (operating-procedures + canonical lane prompts): consequence findings file standalone; paper-cuts land here as lines and are batch-fixed in one sweep PR when the batch justifies it. Control tower created this because the throttle was inert without it (2026-07-20 triage audit finding).

Lines

Folded from standalone issues (closed, content preserved here):

From the 2026-07-20 cross-PR consistency audit:

From the 2026-07-20 triage-lane session (tool-mechanics nit):

  • TaskCreate invoked with a batched tasks:[...] array param (assumed multi-task-per-call shape) — actual tool signature is one task per call (subject+description strings), and its schema wasn't loaded into context yet, so the batched call round-tripped as InputValidationError before any tasks were created. No functional impact (skipped task-tracking for this cycle and proceeded), but worth flagging if TaskCreate batching is ever considered — the current one-task-per-call contract makes multi-item tracking expensive enough that lanes reasonably skip it.

From the 2026-07-20 work-2 lane session (rule 4b adjacency nit):

From the 2026-07-20 babysit lane session (amendment-round 13 restart, 6-PR cycle: #489, #568, #616, #665, #699, dotfiles#236):

From the 2026-07-20 triage-lane session (rule 8b/8c priority-consistency nit):

From the 2026-07-20 work-2 lane session (tool-mechanics nit, rule 23):

  • gh issue view --json comments / gh api repos/.../issues/{n} return comment id as the GraphQL global node ID (e.g. IC_kwDO...); gh api repos/.../issues/comments/{id} -X PATCH (the REST edit-in-place endpoint rule 23 needs) requires the plain numeric REST id instead and 404s silently on the node-ID form — no error surfaced beyond a bare 404, easy to miss if the caller doesn't re-verify. First edit attempt this session silently no-op'd on the wrong ID shape; caught only by re-fetching and diffing updated_at. Get the numeric id via gh api repos/<o>/<r>/issues/<n>/comments -q '.[] | select(...) | .id' instead of the --json comments node-ID field before any rule-23 PATCH.

From the 2026-07-20 work lane session (amendment-round 13 restart):

From the 2026-07-20 triage-lane session (own-work correctness miss):

  • This repo has native GitHub Issue Types configured (Task/Bug/Feature, confirmed via issueTypes GraphQL query) and the label taxonomy doc says type belongs there, not a type: label, on org repos — but no type: label exists in this repo's live label set either, and the 9 items this lane triaged in its first cycle today (source-control:babysit-prs: bulk --resolve --include-human can sweep a thread deliberately deferred pending a human ruling #671/672/674/677/684/687/688/691/693) all shipped with zero issue type set, because prior cycles' own precedent (checked before filing) never set one either and the standing rules don't call it out explicitly. Caught mid-cycle-3 and backfilled retroactively (gh issue edit --type) for all of cycle 1+2's items (15 issues) plus set correctly on this cycle's historic-normalization batch going forward. Worth adding an explicit "set native issue type" step to this lane's own rule 1/8g text so it isn't rediscovered per-session.

From the 2026-07-20 triage-lane session (cycle 4, gh CLI tool-mechanics nit):

From the 2026-07-20 triage-lane session (resolved: earlier #632/#633 anomaly):

From the 2026-07-20 PR #737 review (setup-skill pattern gaps — verbatim-mirrored across /discovery:setup, /planning:setup, and the new /verification:setup; fix belongs to the shared pattern / the topic-docs contract binding, not one copy — patching one copy diverges an explicitly-mirrored family):

From the 2026-07-20 PR #742 review (deferred, fail-closed kept — security-guard relaxation, not a paper-cut fix):

  • Literal-$ authorized-path support in the disk-hygiene destructive guard. Repro: _literal_shell_words (plugins/disk-hygiene/skills/clean/scripts/destructive_guard.py L56-59) blanket-rejects any command containing $, so an authorized --data-root whose CLAUDE_PLUGIN_DATA path contains a literal $ is rejected before parsing — scan/preview/apply fail closed for those installs despite the argv authority. Current behavior is fail-closed/fail-loud (deny with visible reason) = over-blocking, the safe direction, outside DEFER-FORBIDDEN — so deferred deliberately, not a quick fix. Fix direction (design note): allow $ only inside a single-quoted literal word (bash does NOT expand $ in single quotes; it DOES inside double quotes), which requires a quote-aware tokenizer that still rejects real expansion/$(...)/backtick syntax — a security-guard change that must not reopen the injection vector the blanket check exists to block. Origin: PR fix(disk-hygiene): guard resolves authorized data root from hook argv #742 thread (destructive_guard.py line 141). → disk-hygiene: destructive_guard.py literal-$ authorized-path support in the shell tokenizer (PR #742 follow-up) #1035

From the 2026-07-20 PR-review blitz (deferred review threads, genuine-but-deferrable — outside DEFER-FORBIDDEN, off-default-path/advisory):

  • DECLARED_SAVEPOINT granularity mismatch in the retro multi-session snippet. Repro: handoff SKILL.md "Where handoffs live" defines a "save-point convention in CLAUDE.md / .claude/rules" as the FULL handoff location (used as-is, wins), but plugins/session-flow/skills/retro/context/session.md (~L55) labels rung 2 with that same "save-point convention" phrasing while using it as the memory_dir ROOT and appending /handoffs. A user who declares handoffs at .claude/handoffs and passes it as DECLARED_SAVEPOINT gets .claude/handoffs/handoffs; ls … 2>/dev/null swallows the miss silently. Deferred: retro is a read-only reflection pass (no gate, no irreversible action), off default path (.work default works), bounded. Fix direction: relabel rung 2 as a memory ROOT (not "save-point convention"), OR reconcile the two skills' granularity + make the retro snippet tolerant of a /handoffs-suffixed value. Origin: PR fix(claude-memory,session-flow): quote-aware topic-docs seam parser via shared helper #756 thread (retro/context/session.md:55). → session-flow/retro: fix DECLARED_SAVEPOINT granularity mismatch in multi-session snippet #821

  • /interview mid-task upgrade rule cannot fire. Repro: plugins/planning/skills/interview/context/session-config.md "Inverse direction — mid-task" (~L89) is phrased as an imperative to an executing actor, but /interview terminates at handoff (its own "handoff ALWAYS terminates current execution" rule) and no hook wires this context into the downstream execution session — read as runtime behavior it never runs. Deferred: advisory prose, no gate/irreversible action. Fix direction: reframe as guidance the interview hands the USER at handoff ("watch for these signals during execution"), consistent with the file's "advisory framing" section, OR relocate the rule into the execution/implement workflow where an agent is actually running. Origin: PR feat(planning): interview recommends downstream model, effort, and advisor #750 thread (interview/context/session-config.md:89). → planning/interview: reframe session-config advisory framing for terminal/general sessions #822

  • Session-config recommendation applied to terminal general interviews. Repro: session-config.md L7-8 frames the recommendation as configuring "the downstream execution session," but plugins/planning/skills/interview/SKILL.md Step 5 (L190) makes a general session terminal with no downstream consumer, while the deliberate "Both domains" section (SKILL.md:225 / session-config.md L76-80) extends the recommendation to general sessions — the two framings are never reconciled, producing /model/effort//advisor guidance for a session that will not exist. Deferred: advisory prose, reversible. Fix direction: for general sessions frame the advice as config for the current / next session (applied now), not "the downstream execution session," rather than dropping the deliberate "Both domains" scope. Origin: PR feat(planning): interview recommends downstream model, effort, and advisor #750 thread (interview/SKILL.md:225). → planning/interview: reframe session-config advisory framing for terminal/general sessions #822

From the 2026-07-20 PR #739 review (education explain evals — manual/advisory eval-format design, not DEFER-FORBIDDEN; the fix is a skill-quality schema decision):

From the 2026-07-20 decide-lane session (cycle 1, decided-item re-park churn — mis-routing class):

From the 2026-07-21 triage-lane session (blocked-briefed re-promotion gap):

From the 2026-07-21 triage-lane session (lane-coverage gap, self-caught cycle 7):

From the 2026-07-21 triage-lane session (gh tool-mechanics gotcha, self-caught):

Sweep rule: one PR per batch, structure-only/small fixes, each line checked off with the commit that fixed it.

From the 2026-07-21 work-lane session (cycle 1, pick-order scoping nits):

From the 2026-07-21 babysit-lane session (cycle 1, worktree-prune stale-record nit):

  • Queue-start prune (prune_babysit_worktrees.py --apply) errored on a leftover state record for a merged/closed PR (melodic-software/ci-workflows#159) pointing at worktrees/melodic-software__ci-workflows__pr-159: fatal: not a git repository (or any of the parent directories): .git. The directory is gone (deleted outside the helper, or never fully created) but its state entry persists, so every queue-start prune re-errors on it instead of self-healing (removing an orphaned state record for a path that no longer exists as a worktree at all). Fix direction: when git status fails with "not a git repository" for a tracked worktree path, treat that as "already gone" and drop the state record instead of reporting an error. → source-control/babysit-prs: harden prune_babysit_worktrees.py against orphaned state #816

  • Queue-scope lease was lost mid-cycle to a stale-takeover (release --scope queue returned exit 3, "token does not match") after ~24 minutes waiting on 7 background per-PR workers without a queue-lease heartbeat in between. orchestration.md's Concurrency Guard requires heartbeating the queue lease at least every 5 minutes while waiting on background workers; this session didn't, so a concurrent runner reclaimed it via --steal-stale (>900s default staleness window) partway through. No apparent harm this cycle (all PR-scoped worker leases are independently scoped and were unaffected), but worth a documented reminder/example in orchestration.md or a defensive periodic-heartbeat helper call inserted directly into the queue-cycle procedure in SKILL.md/loop.md, since it's easy to lose track of during a long parallel worker fan-out.

  • Read-only babysit_merge.py <pr> --allowed-owners ... --self-logins @me (no --merge flag) was denied outright by the host's own auto-mode permission classifier — filed standalone as source-control:babysit-prs: read-only babysit_merge.py invocation blocked by host auto-mode permission classifier #787 since it blocks this lane's own required per-cycle MERGE-READY gate-proving (DEFER-FORBIDDEN-adjacent: it's the mechanism that would otherwise gate-prove the human merge-ready list), not batched here; cross-referenced for visibility.

From the 2026-07-21 babysit-lane session (cycle 3, additional false-positive-blocker observation):

From the 2026-07-21 work-lane session (operator course-correction — no staleness/heartbeat check on dispatched workers):

  • The orchestrator has no systematic policy for checking on a dispatched worker that goes quiet for a long stretch — it was relying on the worker sending an idle_notification or a status message, and had no fallback timer. Surfaced when a worker (issue claude-config: add model-upgrade unhobbling audit — sweep instruction surfaces for constraints newer models no longer need #800, authoring a brand-new skill from scratch) went ~30+ min with zero notifications of any kind (not even an idle ping, unlike every other worker this session), and the operator asked directly whether it was stuck. Checked the worker's worktree directly (git status/git log in its out-of-tree worktree) and found real, uncommitted progress (new skill directory + version/CHANGELOG/README edits) — not stuck, just a bigger task than the fixes other workers handled. Fix direction: since dispatched workers here are file-based (each owns a worktree the orchestrator can already read), the orchestrator should periodically poll worker worktree state (a cheap git status/git log check, no message round-trip needed) on some interval for any worker that hasn't reported in, rather than only reacting to inbound messages/idle-notifications or waiting for a user nudge. Worth wiring into the standing loop-prompt rules (a "long-silent worker" checklist item) so this isn't rediscovered per-session.

From the 2026-07-21 babysit-lane session (cycle 9, third readiness-gate over-count variant):

From the 2026-07-21 work-lane session (recurring worker-brief gap — exec-bit, 2nd occurrence same session):

From PR #802 (fix #486, tower-dispatched unblock - deferred Codex P2):

  • /work-items:triage attention view omits the priority-axis raw marker. PR fix(work-items): re-key triage scope on state, not authorship (#486) #802's new Scope section defines the raw marker as status:needs-triage / priority:needs-triage (whichever axis a consuming repo files under), but the "Attention view (no number)" buckets in plugins/work-items/skills/triage/SKILL.md still only list Unlabeled + status:needs-triage + needs-info. A consuming repo that files raw items under priority:needs-triage would have them missed by the no-arg attention view (neither unlabeled nor in the status bucket). Fail-safe - the missed item waits un-triaged, and the autonomous /work-items:work lane selects from the role-labeled frontier (list-frontier --autonomous), not this view, so nothing acts on the omission - hence deferred rather than blocking the PR. This repo's own raw marker is status:needs-triage, which the view already buckets, so it does not bite here. Origin: Codex review thread on PR fix(work-items): re-key triage scope on state, not authorship (#486) #802 (chatgpt-codex-connector, 2026-07-21). Fix direction: add the resolved priority-axis raw marker to the attention-view bucket list + filtering instructions, mirroring the Scope section's dual-axis wording. → work-items/triage: reconcile SKILL state machine + attention view with live labels #817

From the 2026-07-21 work-lane session (self-correction — wrong search path, not actually stale):

From the 2026-07-21 decide-lane session (cycle 10, brief-staleness sweep — systemic finding):

From the 2026-07-21 work-lane session (self-caught, fixed same-turn — exact #559 bug reproduced in this lane's own telemetry-edit habit):

From the 2026-07-21 work-lane session (self-caught, fixed same-turn — plugin-directory mismatch):

From the 2026-07-21 work-lane session (worker collision-instruction compliance gap — caught by orchestrator re-verification, not self-caught by the worker):

  • Gave a worker (disk-hygiene/clean: document per-plugin shell-helper + exit-code divergence as deliberate #820, a 5-plugin fanout PR) explicit, itemized version-collision instructions ahead of time — named the exact plugins at risk and the exact sibling PR numbers to check against. The worker still shipped 3 EXACT version-number collisions (not merely close — identical target versions to 3 already-open sibling PRs from this same lane) and applied no do-not-merge label, instead only noting the collisions in prose as "flagged for merge-order awareness, not blocking" — which is not what the collision protocol requires (serialize + do-not-merge + bump past the live claim). This was only caught because the orchestrator independently re-diffed the actual plugin.json changes in the PR rather than trusting the worker's self-report that collisions were "documented." Fix direction: a multi-plugin PR's collision handling should never be accepted on the worker's narrative alone — the orchestrator (or a CI check) should mechanically re-diff every touched plugin's version bump against current open-PR claims before treating a fanout PR's collision handling as complete. Consider requiring workers to paste the exact landed version number per touched plugin in their return payload specifically so this is cheap to cross-check without re-reading the whole diff.

From the 2026-07-21 work-lane session (account-wide session-limit disruption — recovery pattern, not a codebase defect but a fleet-operations gap):

  • 3 concurrently-dispatched workers (feat(typos-format): per-file typos autofix hook plugin #831, feat(toolchain): add lychee-offline to cross-cutting ecosystem default #833, feat(toolchain): add pyright to python ecosystem check-cmd #834) all independently reported idleReason: "failed" / "You've hit your session limit · resets 8:30am (America/New_York)" within about a minute of each other — consistent with an ACCOUNT-level session limit affecting every spawned agent under this account simultaneously, not a per-agent failure. A real wall-clock gap of ~5.5 hours elapsed around this event despite otherwise-normal turn-by-turn interaction (i.e., the limit likely blocked more than just the 3 reporting workers — plausibly the orchestrator's own tool calls too, and possibly other concurrent lanes sharing the account). Recovery followed session-flow:keep-going's pattern rather than assuming state: inspected each dead worker's actual worktree (git status/git log) before acting — one had zero uncommitted work (redispatched clean), two had real uncommitted-but-unpushed progress with no PR opened yet (zero side-effect risk, safe to auto-resume per the autonomy policy — redispatched into the same worktrees with instructions to inspect the existing diff first rather than blindly redo). Fix direction: this lane's standing rules have no explicit handling for an account-wide (as opposed to single-worker) disruption — worth adding a checklist item to distinguish "this one worker died" (redispatch it) from "many workers died in the same short window" (a systemic account-level event, worth explicitly re-verifying ALL in-flight state — not just the reporting workers — since some may have silently stalled without ever sending a failure notification).

From the 2026-07-21 work-lane session (worker fabricated a plausible-but-wrong Claude-Session trailer value — caught by orchestrator cross-check, not self-caught):

  • A resumed worker (feat(toolchain): add pyright to python ecosystem check-cmd #834, after the account-wide session-limit disruption above) needed a Claude-Session: commit trailer value but only had a local CLI worktree-directory UUID available, not a claude.ai/code/session_... URL — it used the local UUID as the trailer value and flagged the substitution rather than silently guessing, which is the right instinct, but every other worker dispatched this same session used the identical real value https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o (the orchestrating session's own URL, correctly reused verbatim across every dispatched sub-worker — confirmed by grepping prior commits in this session's own worktrees). The dispatch brief template asks workers to add "a Claude-Session: line" without ever stating what value to put there, leaving each worker to either already know it, guess, or flag-and-ask. Fix direction: the brief-composition step should state the exact session URL value explicitly (it's a single constant for the whole dispatching session, not something each worker needs to independently discover or invent) rather than leaving the value implicit and hoping every worker either already has it or asks.

Resolution reached this cycle: worker correctly refused to force-push to fix the interim commit's wrong trailer when the permission system explicitly denied it (right call — a peer's say-so, mine included, never substitutes for actual user/permission-system consent on a destructive op; this is NOT what got force-pushed, it was correctly refused). Investigated before escalating to the actual user: confirmed via gh repo view that this repo is squash-merge ONLY (merge/rebase commits disabled), and grepped .github/+scripts/ for any check that inspects individual commit trailers — none exists. Conclusion: the wrong interim-commit trailer is harmless — it's discarded at squash-merge time and nothing gates on it. Told the worker to leave it as-is rather than force-push or open a fresh branch/PR. No user escalation was needed once the actual stakes were checked empirically instead of assumed.

From the 2026-07-21 work-lane session (PR review job silently failed at the infrastructure level — same signal-quality class as #465/#473/#601's readiness-gate over/under-counting gaps, now confirmed in the review-posting workflow itself):

  • On PR feat(toolchain): add lychee-offline to cross-cutting ecosystem default #867, the review / review GitHub Actions check reported pass, but the actual comment it posted was an infra-failure placeholder: <!-- claude-review-infra-status --> + "Automated review did not complete — this is an infrastructure failure, not a review verdict... Last SDK result: (no execution file was produced)". The CI check's green status gives zero signal that the review itself never ran — an orchestrator (or a human) skimming "all checks green" would wrongly treat this PR as reviewed-clean when no review verdict exists at all. gh run rerun <run-id> could not retry the run directly ("this workflow run cannot be retried") — the only documented recovery path is pushing a new commit to retrigger. Fix direction: (1) the review CI check's pass/fail should reflect whether a REAL review verdict was posted, not just whether the job process exited 0 — an infra-failure placeholder comment should itself flip the check to fail or at least a distinct neutral state, not pass; (2) this lane's own post-green-review-pass step should explicitly check comment CONTENT for the claude-review-infra-status marker (or equivalent "did not complete" language) before treating a PR's review as done, not just trust the green check — caught here only because the reply text was read directly, not inferred from the checks list.

From the 2026-07-21 work-lane session (recurring pattern — rebase force-push blocked by permission system, 2nd occurrence same session):

From the 2026-07-21 work-lane session (near-miss — orchestrator dispatched a duplicate worker into an already-live worktree after wrongly concluding the first was dead):

  • Issue feat(typos-format): per-file typos autofix hook plugin #831's worker (worker-831b) went quiet for an extended stretch — two direct worktree checks (git status/git log) a few minutes apart showed zero visible change, and a direct status ping got no reply for a while, which matched this session's established "worker likely died to the account-wide session-limit disruption" pattern from earlier in the cycle. Concluded worker-831b was dead and dispatched a FRESH worker (worker-831c) into the EXACT SAME worktree directory to redo the task. Worker-831b was not actually dead — it was deep in a long, careful verification pass (hand-testing behavior against a real typos-cli binary) and eventually surfaced with a complete, correct, already-committed-and-pushed PR (feat(typos-format): per-file typos autofix hook plugin #880). Worker-831c, dispatched concurrently into the same live worktree, found what it reasonably interpreted as "an untracked prior session's uncommitted work" (actually worker-831b's own in-progress commit-in-flight) and proceeded to independently verify and build on it. Both workers ultimately converged on the SAME single commit with no corruption — but this was fortunate git-locking/timing, not a designed safeguard; a worse-timed race (both processes writing/committing at truly the same instant) could plausibly have corrupted the shared git index or produced a genuinely conflicting duplicate commit. Fix direction: before redispatching into an EXISTING worktree after concluding a worker is dead, either (a) require a longer silence threshold and more than one ping attempt with real spacing before declaring death (2 quick checks a few minutes apart is not enough signal, especially right after a known account-wide disruption event where slow-but-alive is a live possibility), or (b) when redispatch is warranted, create a NEW worktree/branch for the redispatch attempt instead of reusing the same directory, specifically so two live agents can never write to the same git state concurrently even if the "dead" conclusion turns out to be wrong.

From the 2026-07-21 work-lane session (new collision-detection gap class — a clean git auto-merge can silently hide a real version collision):

From the 2026-07-21 decide-lane session (cycle 23, decision-taxonomy coverage gap):

From the 2026-07-21 work-lane session (2nd account-wide session-limit disruption — this time a dead worker's local branch had genuinely DIVERGED from origin, not merely fallen behind):

  • During keep-going recovery from a second account-wide session-limit event (4 dispatched workers died mid-task), one worker's (source-control:babysit-prs: 'source-control-babysit-resolve-thread' bare wrapper not on PATH (command not found), worker must fall back to raw GraphQL #484/PR#840) local worktree turned out to be in a real 3-way-divergence state: its local unpushed merge commit and origin's actual current tip had a different common ancestor, because ANOTHER actor (a different lane, same account identity) had pushed a legitimate, unrelated content fix directly to the same PR branch while this worker was mid-rebase. A naive recovery (just git push, or worse git push --force) would have either failed outright or silently clobbered the other lane's real commit. Correct recovery required: git merge-base --is-ancestor to detect true divergence (not just "origin moved"), then git merge origin/<branch> --no-edit to combine both histories (clean, no conflicts here since the two changes touched different files), re-verify the version claim was still uncollided against ALL currently-open siblings post-merge, THEN push normally. Two of the four recovered workers turned out to be simple fast-forward cases (local simply ahead, no divergence) and one had already fully succeeded before dying (idle-death, not mid-task-death) — only one of four needed the full divergence-reconciliation treatment. Fix direction: a keep-going-style recovery routine for a dead worker's git branch should always run the ancestor check FIRST (not just diff git log output by eye) before deciding whether a plain push suffices, since the difference between "origin moved ahead" and "origin diverged" determines whether a push will even succeed, let alone whether it's safe.

From the 2026-07-21 decide-lane session (cycle 28 restart, parked-PR scan under-detection):

  • The decide lane's periodic parked-decision PR scan (queue tier b) using only LITERAL markers ("needs-decision"/"parked decision"/"Decision defaulted"/"decide-and-defer"/etc.) returned NONE for several cycles while 4 genuinely-parked, unbriefed review-thread decisions existedfix(disk-hygiene): define "suspicious" for unhinted home-root entries #869 (clean app/config exclusion: allowlist vs heuristic), feat(toolchain): add pyright to python ecosystem check-cmd #859 (pyright-in-default-check-cmd portability gate), docs(knowledge): youtube-digest synthesis target + named agnosticism gaps #854 (youtube-digest persist Target on resume), feat(implementation): front-load CI-hygiene and early-push clauses in dispatch brief #849 (orchestrator worker-commit integration when early-pushed source is absent). They were only caught once the scan prompt was broadened to SEMANTIC-equivalent language ("deferred to author/operator", "design question", "left open for", "author decision", "operator decision"). All four now briefed (PR-level comments, 2026-07-21). Fix direction: any parked-decision PR scan (decide lane tier-b here, and the triage lane if it runs one) must match the SEMANTIC shape of a deferred design fork in review threads, not just a fixed literal-marker list — reviewers/authors rarely write the exact tokens; they write "I'll leave this to the author" / "open design question" / "deferred". A literal-only scan silently under-reports tier-b coverage. Applied the broader term set in this session's scan prompt; worth baking the semantic term set into the standing scan contract so it survives restarts.

From the 2026-07-21 PR #859 verifier-resolver lane (toolchain pyright deferrals — review threads resolved under operator delegation; design decisions tracked here for the author):

From the 2026-07-21 PR #849 verifier-resolver lane (dispatch-brief phase-boundary exception — review thread resolved under operator delegation; design decision tracked here for the author):

From the 2026-07-21 babysit verifier session (PR #854, youtube-digest doc nit):

From the 2026-07-21 babysit verifier session (PR #854, youtube-digest target-resolution gap):

From the 2026-07-22 PR #898 verifier-resolver lane (feat/399 shared worktree helper — codex re-review P2 robustness edges on worktree-create.sh; review threads dispositioned + resolved under operator delegation, design decisions tracked here for the author):

From the 2026-07-22 merge-drive lane (worker-tier conflict-resolution dispatches, amendment-round 16):

From the 2026-07-22 work lane (T3, PR #1030, #972 fix — dispatched-worker self-observation, amendment-round 16):

  • 9 sibling formatter hooks share the same latent out-of-tree lint/format noise #972 fixed for markdown-format only (converted to #1091, routed needs-human — the shared-lib approach already regressed once): bash-format, biome-format, eol-normalizer, go-format, guardrails, powershell-format, ruff-format, typos-format, actionlint all carry the same hook::read_file_path() gap (project-membership scoping skipped when CLAUDE_PROJECT_DIR is unset, so a PostToolUse hook fires on scratchpad/temp .md-or-equivalent files outside any repo). PR fix(markdown-format): skip out-of-tree Markdown when CLAUDE_PROJECT_DIR unset (#972) #1030 scoped the fix to markdown-format alone after an attempted shared-lib fix (editing lib/hook-utils.sh + syncing all 12 carriers) caused 9 genuine plugins/guardrails/hooks/cli-flag-verify.test.sh regressions and was reverted. Fixing the other 9 as a class wants an opt-in shared scoping mechanism (each formatter hook opts in; the shared guardrail-adjacent code stays location-agnostic so a future guardrails-side change doesn't cascade into unrelated formatters again) — worth a dedicated issue with this trigger recorded, not another blind shared-lib edit. Source: PR fix(markdown-format): skip out-of-tree Markdown when CLAUDE_PROJECT_DIR unset (#972) #1030.

From the 2026-07-22 merge-drive lane (worker-tier claim-comment protocol, amendment-round 16):

From the 2026-07-22 babysit lane (safe tier, PR #1628, amendment-round 16):

  • /quality-gate restatement lane emits frontmatter that violates its own contract: both .work/delete-pr-template-inherit-org-default/review/*-restatement-review.md artifacts on melodic-software/medley#1628 had type: restatement-review plus non-schema mode/branch fields and a missing slugquality-gate-evidence-contract.md's required frontmatter is type: quality-gate-evidence + slug. No corpus/runtime-gate cascade (.work/ is excluded from those), so this cycle just conformed both artifacts directly on the branch. Root cause is upstream in the /quality-gate restatement lane itself (plugin-owned), not this PR — worth fixing at the source so future restatement runs emit contract-conforming frontmatter instead of each consumer PR patching it after the fact. Source: PR https://github.com/melodic-software/medley/pull/1628.

From the 2026-07-22 work lane (T3, PR #1021 — second instance of the version-line serialization pattern already logged above for disk-hygiene, amendment-round 16):

From the 2026-07-22 work-2 lane (T5, telemetry self-observation, amendment-round 16):

  • gh issue comment --edit-last produced a duplicate telemetry comment across a session-interruption boundary: this lane's ops: loop-lane telemetry — running per-lane status (babysit / triage / work) #502 telemetry comment (id 5048731522) got duplicated into a second live comment (id 5051467200, created 2026-07-22T20:57:59Z) sometime around a weekly-usage-limit interruption, holding a full copy of the same cycle-1..7 history. Root cause not isolated (candidate: --edit-last's "last comment by current user" resolution racing or misfiring across an interrupted turn boundary; not reproduced on demand). Recovered by patching the original comment via its numeric id with gh api -X PATCH .../issues/comments/<id> (bypassing --edit-last entirely) and neutralizing the duplicate in place with a pointer back (deleting it was denied by this session's own permission gate against destructive ops — worth noting --delete-last/direct comment deletion may need an explicit approval path for any lane relying on self-cleanup). Suggested fix direction: any skill/rule prescribing --edit-last for a durable single-comment invariant (rule 23's telemetry pattern, and likely similar patterns elsewhere) should pin and reuse the comment's numeric id after first creation instead of re-resolving "last comment" every cycle.
  • triage-decide lane: cross-repo triage subagents keep reaching for status: needs-decision on genuinely-open items instead of the convention needs-human (alone) — 3rd occurrence across cycles 11-12 (github-iac#139, ci-runner#55, ci-runner#61), all self-caught and fixed same-cycle via post-hoc live-state verification. Dispatch-prompt wording likely needs a clearer positive instruction ("apply needs-human, never status: needs-decision, for fresh triage routing") rather than only the negative "never pair the two" phrasing added in round 17.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: lowNice-to-have, cosmetic, or speculative; opportunistic.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions