Skip to content

Name guard fails open: lanes-edit.sh guard exceeds its 5 s UserPromptSubmit timeout, and Claude Code cancels it and lets the prompt through #298

Open

Description

@brettheap

Lane: openRepoProject-1

Related: #25 (the guard's adoption, lane protocol Amendment 12; CLOSED) and #52 (its implementation, merged 2026-09-15 as 2faa883, where the code comment quoted in section 4 was written). Amendment 23 act 2 is tracked by #198 (OPEN) and PR #282 (OPEN); see the Sibling search at the end. All figures are from Eagle on 2026-10-20 (UTC) unless a date is given; figures re-read on 2026-10-21 say so.

  • "Installed build" = /home/brett/.local/bin/lanes-edit.sh (2026-10-08 20:52, 17,046 lines, 1,007,136 bytes; unchanged on 2026-10-21, sha256 8800a541...).
  • "HEAD" = /workspace/projects/openRepoTools at 21e0829 (lanes-edit.sh 18,467 lines, 1,104,141 bytes, +9.6%).
  • "origin/main" = a42946e, read with git ls-remote origin main on 2026-10-21 (HEAD is its ancestor, 9 commits behind; lanes-edit.sh 18,479 lines, 1,104,831 bytes).

Summary

The guard is registered with "timeout": 5 and no onFailure. When it overruns, Claude Code cancels the hook, discards its output and delivers the prompt (official docs, quoted below). The guard's own fail-closed mapping, every exit other than 0 or 2 becomes 2 (guard) arm, installed lanes-edit.sh:15010-15037, HEAD 16351-16377, origin/main 16363-16389), never runs for a cancelled process. The guard is cancelled up to 640 times a day across the estate (100 or more on 9 of the 11 days from 10-09 to 10-19), and in the one transcript where prompts could be counted, on 23 of 28 turn starts on 10-19 and 10-20. No guard refusal has been recorded since 10-05. The code has said since 2026-09-14 that the timeout is "the one path on which this guard fails open". HEAD and origin/main have the same cost and the same path.

Evidence

1. What Claude Code does (https://code.claude.com/docs/en/hooks; Claude Code 2.1.304 when measured, 2.1.305 on this host since 2026-10-20 20:48Z)

Quoted from the page's raw markdown on 2026-10-20 and re-checked against the live page on 2026-10-21 (every quoted sentence is still there); only the markdown link targets are removed.

Section "UserPromptSubmit":

"UserPromptSubmit hooks have a default timeout of 30 seconds for command, http, and mcp_tool types, shorter than the 600-second default for those types on most other events. Because this hook runs before every prompt and blocks model processing until it completes, a stuck hook stalls the session."

"Apart from a command hook you run with async: true, a UserPromptSubmit command, HTTP, or MCP tool hook that reaches its timeout is canceled and its output, including any additionalContext, is discarded. The prompt still reaches Claude without that context. To block the prompt instead, set onFailure: "block" on a command or HTTP hook. The transcript shows a notice naming the hook, the timeout that fired, and that the output was discarded."

Section "Timeouts" (under "Exit code output"):

"Apart from a command hook you run with async: true, Claude Code cancels a command, http, or mcp_tool hook that reaches its timeout, discarding the hook's output, so on most events a timed-out hook renders no decision."

Section "Block the action when a hook fails":

"On most events, when a hook fails or times out, Claude Code still carries out the action. ... To block the action instead, set "onFailure": "block" on a command or http hook. Requires Claude Code v2.1.295 or later."

"With "block" set, a failure does what exit code 2 does on that event ... For example, a PreToolUse failure blocks the tool call and a UserPromptSubmit failure blocks the prompt."

"After a timeout, the message says timed out instead of failed."

Exit codes: only exit 2 blocks a prompt ("Blocks the prompt, so it never reaches Claude"); any other code, "or fails in some other way", is a non-blocking error and "The action goes ahead". So a timed-out guard is cancelled, its output is dropped, and the prompt proceeds. A cancelled process has no exit code for the guard's own mapping to act on.

2. How the guard is registered

{"type":"command","command":"~/projects/xFactory/lanes-edit.sh guard","timeout":5} in /home/brett/.claude/settings.json and in 333 of the 428 settings.json files found up to four levels below ~/.claude-profiles/profiles (recounted 2026-10-21; 331 of the 333 are the team profiles at depth four; the 2026-10-20 count was 331 of 393, over a file set that was not recorded). None mentions onFailure (95 files carry no guard entry). ~/projects/xFactory/lanes-edit.sh is a symlink to /home/brett/.local/bin/lanes-edit.sh (sha256 8800a541...). The installer writes the entry from openRepoTools:2105-2116 at HEAD, 2343-2354 at origin/main (GUARD_COMMAND, GUARD_TIMEOUT=5, guard_block_text; re-read 2026-10-21) and has merged it since 2faa883 (2026-09-14).

3. What the transcripts show

Hook attachments of type hook_cancelled, timedOut: true, timeoutMs: 5000, command "~/projects/xFactory/lanes-edit.sh guard", counted per day over every transcript under ~/.claude-profiles/state/opensoft/projects (3,707 files changed since 10-01):

before the 2026-10-08 20:52 install:  10-05 2 | 10-06 1 | 10-07 5 | 10-08 0
after:  10-09 442 | 10-10 18 | 10-11 459 | 10-12 330 | 10-13 114 | 10-14 7 | 10-15 112 | 10-16 264 | 10-17 471
        10-18 640 | 10-19 186 | 10-20 25 (to 09:30Z)
  • Median cancelled duration about 5.5 s (the 5 s kill plus about 0.5 s); maximum 24.7 s (10-18).
  • No hook_blocking_error for the guard in any transcript since 10-05.
  • session-start, the offline SessionStart hook (also timeout 5), is cancelled too (51 on 10-18, 35 on 10-19). When it succeeds it takes 3-5 s; on 09-13 it took 0.07-0.65 s.
  • One instance, transcript /home/brett/.claude-profiles/state/opensoft/projects/-workspace-projects-openRepoProject/a0e10447-aab0-411d-8015-359674fb42ea.jsonl, lines 2795-2800: a prompt is queued at 09:27:37.131Z, the guard is hook_cancelled/timedOut at 09:27:42.662Z (timeoutMs 5000, durationMs 5519), the assistant acts on the prompt at 09:27:47.715Z.
  • In that transcript the denominator can be counted (turn starts = user text records plus queued commands, including subagent reports, which also fire UserPromptSubmit per the docs). A turn start counts as cancelled when a guard cancellation follows 3.5-10 s later: 23 of 28 on 10-19 and 10-20 (82%), 2 of 9 on 10-18, 0 of 16 on 10-11 with the same installed build (UNCONFIRMED whether the guard was registered for that profile on 10-11, or finished in time). A silent pass leaves no record, so the share of prompts the guard finishes cannot be counted from transcripts.
  • In the same session usage-guard.sh, the other UserPromptSubmit hook, finished in 121 ms in a recorded run.

4. What the code says about itself

lanes-edit.sh:8407-8414 (HEAD and origin/main 9114-9121), the same text in all three builds; it arrived with 2faa883 (#52, 2026-09-14):

WHAT IT COSTS, AND THE ONE WAY IT FAILS OPEN. Measured on Eagle 2026-09-14 against 329 session records and a 1.3 MB register: the register read is ~2 s wall and the grep -l over every profile's records ~0.4 s, so a refusal lands inside the ratified timeout 5. A hook that EXCEEDS its timeout is killed, and a killed hook does not exit 2 -- so the timeout is the one path on which this guard fails open. It is the amendment's own number and is left at it; ...

(The dash is ASCII-fied.) Today there are 466 session records (+42%) and the register blob on origin/main is 2,358,766 bytes (+81%).

5. Measured on 2026-10-20, 11:19-11:22Z (one sample each; the host was busy)

  • The exact call session_files makes on the big tree (find "$HOME/.claude-profiles/profiles" -path '*/sessions/*.json' -type f; lanes-edit.sh:3873-3896, HEAD 4247-4270) found 466 records in 28,819 directories. First pass 4.681 s. Repeats 0.913, 0.831 and 0.663 s. One cold pass alone is 94% of the 5 s budget.
  • Host at that time: load average 78 / 98 / 76; memory pressure, PSI memory some avg300 31.7% and full avg300 30.1%; free 0.8 GB, page cache 45 GB, 4 GB of 14 GB swap in use; /dev/sdd 94% full (891G of 1007G).
  • Process spawn was cheap then: about 2 ms per process and about 6 ms per jstr call (four processes). So spawn count is not what costs time at present.
  • A three-level glob (profiles/*/*/*/sessions/*.json) took 0.654 s against 0.663 s for the find, and missed 1 of 466 records (profiles/xfactory-001/sessions/3506923.json, one level up).
  • bash -n (parse only) median of 9 runs: 42.9 ms installed, 41.8 ms HEAD.

6. Is it fixed at HEAD or at origin/main? No.

guard_run at HEAD (10069-10538) differs from the installed one (9290-9736) by 7 added and 4 removed code lines. Cost: -1 jnum (installed line 9385 assigns gr_since and never reads it; -4 processes); +1 full awk pass over the register (a new test that the register text is readable, register_text | awk 'NF{t=1} END{exit !t}'; the first register render moves to that point, so the render itself is not extra); record_window_state adds one tmux display-message only when a window is not found; log_files_named_ci adds one subshell; transcript_holders adds shell bookkeeping only. The register read's cold path makes the same three git calls (ls-tree replaces cat-file -e). Identical in both: session_files (the whole-tree find), jstr, jnum, pid_alive, pid_under, here_context, lane_binding_scan, binding_window_state, lane_alias_text, rows_named_ci_alias, the guard) arm (HEAD 16351-16377, origin/main 16363-16389, no deadline), and all load-time code before dispatch.

Failure mode, all toward fail-closed on a failed read: HEAD refuses (exit 2, correct reason) when the register text cannot be read, where the installed build fell through to the last table arm with a cure that cannot mend a read that did not happen; rows_named_ci and log_files_named_ci pass a failed read's status on; record_window_state answers 2 ("no answer") instead of 1 ("gone") when no tmux server answers. Choice 2 (guard_answer, installed 9943-10087, HEAD 10754-10906) now runs lane-start --no-launch --bind "$G_ID" and no longer runs a second writer (guard_bind_uuid -> append-session-id), but that one writer still runs synchronously inside the hook.

So HEAD would still overrun for the same reasons (by code comparison; unmeasured, because the guard was not run during this investigation). An install of HEAD would not fix this issue.

origin/main (a42946e, re-read 2026-10-21) has the same guard code. Its lanes-edit.sh differs from HEAD's in one place only, inside lane_reconcile (starts at 13851; HEAD lines 14196-14214; 12 more lines; called only from the reconcile verb at 18394, not from the guard). So the guard) arm moves from 16351-16377 to 16363-16389 and no other line cited here moves. session_files (4247-4270), the comment at 9114-9121, transcript_holders (9342-9460), lane_binding_scan (9506-9633), guard_run (10069-10538) and guard_answer (10754-10906) are at the same lines at HEAD and origin/main.

Root cause

  1. The budget is fixed and the cost is not. The entry says timeout 5 (Claude Code's own default for this event is 30 s). The agreeing path loads and parses a 1 MB script, then runs transcript_holders (installed 8585-8683): the whole-tree find above, xargs grep -l -F for the session id across 466 records, and for each matching record about 20 processes (jstr, kill -0 and /proc/<pid>/stat, tmux display-message, an ancestry walk of up to 64 /proc reads); then rows_named_ci_alias twice (window name, session name) plus session_ids_of_lane and row_of_lane, each an awk pass over the 2.36 MB register; lane_binding_scan (8729): git ls-tree, git show of the lane's 64 KB log, awk, tmux. guard_run has 6 lines that call jstr and 1 that calls jnum (4 processes each).
  2. Most of that is cache-sensitive, and this host has sustained memory pressure. The one step timed end to end costs 0.66-0.91 s warm and 4.68 s on a cold pass.
  3. The code accepted the fail-open path in 2026-09-14 because the measured cost was about 2.4 s (section 4). The data has grown by 42% (records) and 81% (register) since, and the cost now often passes 5 s.
  4. On the overrun Claude Code cancels the hook, discards its output and delivers the prompt (section 1). The guard's fail-closed mapping (the guard) arm turns every code other than 0 or 2 into 2, Amendment 12(d)) cannot act on a process that was cancelled. Nothing else in the entry (no onFailure) makes a timeout block.
  5. The guard does not fetch and takes no lock, except on choice 2 (guard_answer), which runs lane-start --no-launch, a writer with fetch and push (LANES_GIT_TIMEOUT default 60 s, up to 6 attempts), synchronously inside the hook.

Not established: which in-guard step crosses 5 s on a given prompt. No end-to-end profile exists: the guard was not run outside a live prompt during this investigation. What changed on 10-09 is also unattributed: no lanes-edit.sh commit between 10-04 and 10-09 names the guard (7 commits: worktrees, derived index, ctx, crash-consistent recovery), and the installer has merged the guard entry since 2026-09-14. The step from 0-5 to 442 cancellations a day may be environment (cache, load, disk), a per-profile rollout, or growth; it is UNCONFIRMED which.

Impact

  • The Amendment 12 guarantee (fail closed, clause (d)) is not what runs on a prompt the guard does not finish. A window, session name and register row that disagree can pass. UNCONFIRMED whether any real mismatch passed in this period; no refusal has been recorded since 10-05.
  • A cancelled guard still costs the person about 5.5 s on that prompt, and the hook "blocks model processing until it completes" (docs). session-start adds up to 5.5 s at launch and resume.
  • Choice 2 can be cancelled in the middle of a lane-start --no-launch write. What the harness does to that child process is not in the docs and is UNCONFIRMED.
  • Nothing tells the person: the only trace is a hook_cancelled notice in the transcript.

Proposed fixes, ranked

Rank is the order to land them. Fixes 2 and 3 turn a slow guard into a prompt-blocking guard, so with today's cost they would refuse most prompts. Fix 1 must land first or with them.

  1. Make the agreeing path cheap and independent of cache state. Target: p95 under 1 s warm and under 2.5 s cold, on the data above, at load average 10 or more.
    • Do not walk 28,819 directories at every prompt (session_files). The guard needs this window's own record and the Amendment 18(h) other-holder check. Read its own record directly (the harness pid is an ancestor of the hook, and the record is sessions/<pid>.json under $CLAUDE_CONFIG_DIR), and answer the cross-profile check from a small index that lanes-index or session-start keeps, or from a glob of the roughly 100 known sessions/ directories. The layout is not uniform, so both profiles/*/*/*/sessions and profiles/*/sessions are needed. Warm, a glob took the same time as the find, so the saving is expected only cold (about 100 sessions/ directories and the few above them, instead of 28,819 directories) and is unmeasured.
    • Read the register once into a file and answer each lookup with one awk. Today it is at least five passes over 2.36 MB (six at HEAD). Skip the alias read when the window's name has a row.
    • Replace jstr's four-process pipeline with the one-awk parse that already exists (SESSION_RECORD_AWK, installed line 3927, HEAD 4301).
    • Make the guard write one line per run (elapsed ms, exit code) to a local file. Silent passes leave no record today, so no one can measure the guard's real distribution.
  2. An internal deadline below the hook budget that exits 2 itself. Start a watchdog at the top of the guard) arm (for example LANES_GUARD_DEADLINE, default 4 s). When it fires it kills the guard's process group, prints the name guard could not finish in <n> s; this prompt is refused (Amendment 12(d)) with the safe-mode line, and exits 2. A deliberate exit 2 is the only way the person sees a reason: a cancelled hook's output is discarded.
  3. "onFailure": "block" on the guard's UserPromptSubmit entry, as the backstop when the guard dies for any reason (cancel, cannot start, exit 1 or 127). Claude Code v2.1.295 or later (2.1.305 here; other hosts UNCONFIRMED). It touches: the installer (guard_block_text, openRepoTools:2346-2354 at origin/main (2108-2116 at HEAD), and plan_hook_merge, 3150-3407 at origin/main (2597-2854 at HEAD), where an existing entry with the exact command string counts as present and is not updated, so a migration of the existing entries is needed), the workBenches launcher that ensures the same two strings in each profile's settings.json (331 files today), the five test files that mention the entry (tests/test_install_skill_and_hook.py, test_install_hook_gate.py, test_install_payload_source.py, test_skill_shell_blocks.py, test_repo_hygiene.py; not read for what they assert; the same five mention it at origin/main), and Amendment 12 adoption act 3's text. It needs Brett Heap's word. Not before fix 1.
  4. Never run a writer inside the guard. Choice 2 should print the lane-start --no-launch command (the refusal tables already print it as the cure), or start it detached and report next prompt, instead of running a fetch and push loop under a 5 s budget where a cancel can land mid-write.
  5. A larger hook timeout (for example 15 s). This is a protocol change (Amendment 12 adoption act 3, "timeout 5"), needs Brett Heap's word, hides the cost, and makes every prompt wait. Stopgap only. It may not even suffice: cancelled hooks were seen taking up to 24.7 s to stop, so a natural completion time above 15 s under load is possible (UNCONFIRMED).

Acceptance criteria

  • On the data above (466 records, 2.36 MB register), with caches cold (after a reboot or a dropped cache on a test host) and with load average 10 or more, the agreeing path finishes in under 2.5 s, and in under 1 s warm, at p95, read from the guard's own timing line.
  • A test seam that slows one read (a sleep) makes the guard exit 2 with the deadline message before the hook's timeout. A suite case asserts exit 2 and the message.
  • Over a 24-hour working day after the install, no transcript carries a hook_cancelled with timedOut: true for the guard or for session-start.
  • Choice 2 makes no network call and starts no writer inside the hook process. A suite case asserts it, for example with the fake git logging no fetch and no push.
  • No find over $HOME/.claude-profiles/profiles on the guard's call path (a suite case reads the call graph).
  • If onFailure is adopted: the entry in /home/brett/.claude/settings.json and in every profile settings.json carries it, and a guard killed after N s shows the prompt blocked on Claude Code 2.1.295 or later (a manual check).
  • session-start finishes in under 1 s on the same data.

Not confirmed

The installed tools are out of date, and Amendment 23 S3 and S4 are in no build

What is installed, against HEAD and origin/main

file(s) in ~/.local/bin installed against HEAD 21e0829 and origin/main a42946e
lanes-edit.sh, lane-start, lane-end, lanes, lanes-index, lane-worktrees, openRepoTools 2026-10-08 20:52 differ
lane, lane-handoff, claude-current, claude-restart-check 2026-10-06 14:19 differ
park, resume, status 2026-09-15 13:52 differ
lane-rename, link-estates, repos.tsv 2026-10-05 / 2026-09-15 identical

HEAD's lane-start, lane-handoff and lane-worktrees are 2026-10-19; its lanes-edit.sh is 2026-10-19 22:01. The checkout showed no change on 2026-10-21. origin/main is a42946e (git ls-remote origin main, 2026-10-21 about 10:48Z; the local ref agrees), 9 commits ahead of HEAD. Against HEAD it changes openRepoTools (619 lines: pipx package mode, "--install leaves pipx's link to pipx"), lane-handoff (62 lines), lane-worktrees (95) and lanes-edit.sh (18 lines, 12 added in lane_reconcile at 14197; the guard path is unchanged), and adds pyproject.toml, src/openrepotools/ and the release workflows. lane-start, lane-end, lane, lanes, lanes-index, claude-current, claude-restart-check, park, resume, status, lane-rename, link-estates, repos.tsv, skills/ and commands/ are byte-identical to HEAD's.

Amendment 23 S3 and S4

Rules: /home/brett/.agents/protocols/lane-collision-protocol-amendment-23.md (fetch, refuse on unpublished commits, merge --ff-only, reset --keep replay, never pull --rebase). Occurrences by grep -o -F, shown as installed / HEAD / origin/main a42946e (all three counted the same way on the file or the blob; re-run on 2026-10-21, same figures as before):

tool merge --ff-only reset --keep git cherry pull --rebase
lanes-edit.sh 0 / 0 / 0 0 / 0 / 0 3 / 3 / 3 21 / 27 / 27
lane-start 0 / 0 / 0 0 / 0 / 0 0 / 0 / 0 4 / 4 / 4
lane-handoff 0 / 0 / 0 0 / 0 / 0 0 / 0 / 0 2 / 2 / 2
lane-worktrees 0 / 0 / 0 0 / 0 / 0 0 / 0 / 0 0 / 0 / 0

(lane-end and lane: all four strings 0 in installed and HEAD.) No tool in ~/.local/bin, in the checkout or at origin/main implements S3 or S4, and none names S1's per-lane checkout path (0 hits for brett-wip-lanes, $W-lanes, .partial, at origin/main too). PR #282 (OPEN, not merged) is the work that names it.

  • The executed pull --rebase calls are: lanes-edit.sh commit_push (installed 2092, HEAD 2297, with rebase --abort at 2116 / 2321, sleep 3 at 2160 / 2370 and the six-attempt die ... 6 at 2162 / 2372); lane-start (installed 4144, HEAD 4422); lane-handoff (installed 2132, HEAD 2636, origin/main 2676; the lanes-edit.sh and lane-start lines are the same at origin/main). The other mentions are comments and printed hints.
  • The three git cherry hits are two comment lines (installed 2141, 2146; HEAD 2346, 2351) and one printed recovery hint (2151 / 2356). None is the S3 "unpublished commits" refusal test.
  • The only reset either build suggests is a printed git reset --hard origin/<branch> (installed 2154, HEAD 2364), where S3 prescribes reset --keep.
  • lane-worktrees is not a register writer, so its zeros are not a gap.

The amendment's act 2 (the tooling: S1 resolver, S2 in every writer, S3-S4, S5, S6) has not landed in any build examined here (installed, HEAD, origin/main).

What openRepoTools --install would change (read from the code and cmp -s; NOT run)

From the checkout (HEAD 21e0829; /workspace/projects/openRepoTools/openRepoTools; payload_select finds all 23 payload files beside it, so local mode: the checkout's bytes, no network):

  • ~/.local/bin, 17 files (INSTALLABLES, line 1077; 1292 at origin/main): UPDATED, 14: openRepoTools, park, resume, status, lane, lanes, lane-handoff, lanes-edit.sh, lane-start, lane-end, claude-current, claude-restart-check, lanes-index, lane-worktrees. Unchanged (mode stamp only), 3: lane-rename, link-estates, repos.tsv. This replaces every 2026-10-06 and every 2026-10-08 build there.
  • Skills and commands, 12 destinations: ~/.claude-profiles/shared/skills/{handoff,lane-swap,restart}/SKILL.md and ~/.claude/skills/{...}/SKILL.md; ~/.claude-profiles/shared/commands/{handoff,ctx,swap}.md and ~/.claude/commands/{...}.md. Only handoff SKILL.md differs, at both paths (2 files updated); the other 10 are unchanged.
  • ~/.claude/settings.json: both entries are already present by exact command string and the mode is already 600, so nothing is written. The installer's "answers guard" probe is an awk text search of the script, so the guard is not run. It never writes a profile's settings.json (the launcher owns those).
  • Receipt /home/brett/.local/share/openRepoTools/installed.tsv (29 rows, 2026-10-08T20:52:08Z) is rewritten. restart is not in ~/.local/bin, so nothing is retired. jq 1.7 and sha256sum are present, so no prerequisite refusal.
  • Mechanism: each file is written beside its target and renamed over it (place_by_rename, line 1810), so a tool already running finishes on its old inode.
  • Reach: the hook path ~/projects/xFactory/lanes-edit.sh is a symlink into ~/.local/bin/lanes-edit.sh, so after the rename the next hook run in every live session on this workstation uses HEAD's lanes-edit.sh at once, and every later lane-start, lane-handoff and lane-end is HEAD's.
  • Other invocation forms, from payload_select (not run): the installed ~/.local/bin/openRepoTools --install finds no skills beside itself, so it re-copies the 17 files beside it (no change to the stale tools) and fetches the skills and command files from GitHub main; the README's curl ... | bash -s -- --install fetches everything from main, which is a42946e today, 9 commits past HEAD (its installer has the pipx mode; README line 228 still gives the command).
  • Re-read on 2026-10-21 against origin/main a42946e. The same cmp -s of the origin/main files against ~/.local/bin gives the same result: 14 would be updated, 3 unchanged (lane-rename, link-estates, repos.tsv); the handoff SKILL.md differs at its two paths and the other 10 skill and command files are the same. It is the same because the four files that differ between HEAD and origin/main (openRepoTools, lane-handoff, lane-worktrees, lanes-edit.sh) already differ from the installed ones. New at origin/main is pipx mode (Releases: annotated tags, release/vX.Y branches, and openrepotools on TestPyPI and PyPI from v1.1.0 #228): if ~/.local/bin/openRepoTools is pipx's link, --install leaves it to pipx and counts the other sixteen. Here it is a regular file (stat), so all 17 would be placed as above. The installer's line numbers at origin/main: payload_select 1192, place_by_rename 2025, install_commands 2065-2200, the guard entry 2343-2354, plan_hook_merge 3150-3407 (HEAD: 977, 1810, 1850-1962, 2105-2116, 2597-2854). The present test in plan_hook_merge is still by command string alone, so a re-install does not update an existing guard entry.

Consequence

Installing HEAD or origin/main would neither fix the guard timeout (section 6) nor deliver Amendment 23 (S3 and S4 are in no build). It would replace the guard workstation-wide with a build that is 9.6% larger (HEAD; 9.7% at origin/main) and has the same cost and no deadline. Track Amendment 23 act 2 through #198 (OPEN), PR #282 (OPEN) and #197 (named by the amendment; state not established), and land the guard fixes above before or with any install.

Sibling search

Searched on 2026-10-21 (about 10:49Z) in opensoft/openRepoTools, issues and pull requests in every state, with GitHub text search (title, body, comments): one request that ran 14 separate queries. Hits per query: UserPromptSubmit 17; onFailure 0; "fail open" 36; "fails open" 5; "fail-open" 36; "name guard" 60 (40 returned); guard timeout 33; guard "timed out" 12; hook_cancelled 0; "hook timeout" 1; "timeout 5" 4; guard overrun 0; guard "fail closed" 46 (40 returned); lanes-edit.sh guard 88 (40 returned). A second request, to read the bodies and comments of the 60 most likely hits, failed with HTTP 502 and was not repeated, so no hit's body was read: the judgments below rest on title, state, last-update date and the words the search matched. On 2026-10-20 a search limited to issues (gh issue list --state all --search "guard timeout UserPromptSubmit") had returned one issue, #25.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions