Skip to content

feat(credentials): add bounded per-caller watchdog TERM grace - #1143

Merged
seathatflowsinourveins merged 2 commits into
mainfrom
foundation/credential-watchdog-term-grace-20261015
Oct 15, 2026
Merged

seathatflowsinourveins merged 2 commits into
mainfrom
foundation/credential-watchdog-term-grace-20261015

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

Add per-caller --term-grace SECONDS, a separate canonical integer from 1 through 3600, to the existing credential-run watchdog. Default execution retains the existing TERM then 2.0-second grace; the dispatch's zero-grace premise did not match current main. The help/usage text gains two lines describing the option.

Base: 0f4ee075b2ab3af1b099d5ca1ecb8cae02ee3f5b; lane: lane:shared. Production changes cover watchdog option selection, parser/dispatch, the separately approved K4 argument grammar and arithmetic checksum/registry updates. Tests and dated decision/caller records accompany them. Credential loading, scrubbing, masking, must_not_be_set and the original watchdog program are unchanged in the reviewed diff. No existing caller opts in. Shared-lane acknowledgement and both-family reads precede adoption.

SOTA sources

  • Official Linux man-pages 6.17, commit c420f73ec92dacd8c6801283e2e4c47e9a1828b7: signal.7:372,387,403–407 describes TERM and uncatchable/unblockable KILL; kill.2:28–81 defines process/group targeting and signal-0 probes. Both official pinned sources were read.
  • CPython 3.12.3 subprocess.py, supported signal/wait primitives. The existing pipe/EOF watchdog and os.killpg mechanism are retained. The existing resource-tracker source citation remains in credential_run.py.
  • Current-main credential_run.py's existing watchdog program is retained. K4 accepts only the separate bounded opt-in form; first-position, attached, repeated, missing-value, --check and missing-separator uses refuse. The option parity test and established K4 semantic fixtures cover the unchanged rules.
  • Caller budget selection remains a separate adoption change. Public signal semantics above justify the generic mechanism. This PR accepts 630 seconds as an example and does not validate or wire a trading recovery budget.

Existing callers

Decision and complete caller table and its JSON locator index account for 503 tracked references in 92 files at base, including hidden files, direct builders, aliases, tests, declarative instructions and documentation. Every runtime constructor was inspected; the base has zero new-flag uses. Runtime sites include runtime_profiles/runtime_acceptance, the Claude review worker, key-health builders, e-series slot wrapper, canary instructions and lane B launcher fixtures. Module consumers retain their APIs. External private jobs are outside this repository audit.

Evidence-class table

Claim Evidence class Command / receipt
Opt-in TERM/grace/KILL and unchanged execution default local_integration with synthetic process groups TERM-handling/ignoring children, successful disarm, API routing, actual grace=1 watchdog argv versus default 2.0
Opt-in value regression sensitivity local_integration negative control Watchdog override deliberately discarded; ignoring-child test fails on actual argv '2.0' versus required '1'
Grammar and policy compatibility synthetic / local_integration Existing K4 fixtures and synthetic parsing, required-variable refusal, scrubbing, forbidden names and masking; fixed historical semantic control rather than whole-file equality
Repository compatibility local_integration Prepared 108 credential/new tests; initial 90 guard tests with 3 skips in portable mode and 127 installer tests with 1 skip; validator and privacy scan passed

Local commands run

Heavy commands run in idle-class scopes. The exact original 13-test head module ran verbosely on base using managed CPython 3.12.3: rc 1, 15 failed assertions and 1 expected missing-feature error. This includes the previously missing CLI-refusal case. The prepared 14-test module also ran verbosely on base: rc 1, 17 failed assertions and 1 expected missing-feature error; semantic compatibility controls pass. Prepared pinned-runtime module: rc 0, 14 tests. The deliberate ignored-override mutation produces the required assertion failure and its detection harness returns 0.

Combined suite on managed CPython 3.12.3: rc 0, 108 tests; python3 scripts/validate.py: rc 0, 12040 hashed files and 240 receipts. The final body is privacy-scanned before publication. The single review fold strengthens opt-in-value detection, replaces whole-file locks with semantic compatibility tests and fixes the inexpensive documentation/refusal-coverage comments. Earlier initial-suite/metadata failures are retained. The native guard run's sole failure compares candidate source to the deliberately unchanged installed host copy; portable mode explicitly skips that comparison. No host acceptance is claimed.

Decision record

docs/decisions/2026-10-15-credential-term-grace.md records contract, public pins, baseline correction, caller table and measured limits. The JSON companion is the complete tracked-reference locator index.

Host evidence

No host adoption, evidence/status flip, credential access, broker action or deployment. Installer tests use temporary homes only. Both-family/guard review and shared-lane acknowledgement remain required.

Follow-ups

  • Adoption precondition: the PR that first wires --term-grace into any runner must first fix the guard's argument extraction at scripts/hooks/secret_path_guard.py:3127-3131 (adjacency-aware), with a fail-first regression that distinguishes a separate-word grace value followed by a redirection from a real descriptor redirection (local review 35edf393; CC ruling 10-15 06:23Z).
  • GPT P3-1: add a native handler-duration regression spanning the default wait while completing inside a larger selected grace. The ignored-option detection portion is fixed here by checking the actual watchdog argv; the additional duration case remains a follow-up.
  • GPT P3-2: pin historical line citations in docs/decisions/2026-10-08-guard-hook-fails-closed.md:15,141 to their intended source version. The current guard parser docstring now uses the function name; historical documents and frozen snapshots are preserved.
  • Remaining CC P3: no-flag help/usage output expands by two lines. Exact legacy help/error text compatibility is deferred; execution and default grace remain unchanged. The other inexpensive CC P3s are addressed: grammar docstring, guard refusal cases and public mechanism citations.

Limits

The opt-in affects only the watchdog's response to runner death. Ordinary end_group cleanup and existing PID/group/parent-death boundaries remain unchanged; escaped groups and successful recovery are not guaranteed. Help/usage output intentionally expands by two lines to document the new option; execution compatibility is the unchanged-default claim. Future caller budget validation and wiring are separate.

Checklist

  • Credential loading, masking, scrubbing and must_not_be_set unchanged in the reviewed diff.
  • Existing callers/default execution unchanged; no caller adoption.
  • Public pinned mechanism citations and fail-first evidence retained.
  • No new workflow, dependency, paid service or real credential test.
  • No installation/deployment; shared guard remains uninstalled pending reviews.
  • Peer worktrees and untracked files preserved.

@seathatflowsinourveins seathatflowsinourveins added the lane:shared Touches files owned by both lanes; needs both lanes' acknowledgement label Oct 15, 2026
@seathatflowsinourveins
seathatflowsinourveins merged commit 4204520 into main Oct 15, 2026
34 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the foundation/credential-watchdog-term-grace-20261015 branch October 15, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:shared Touches files owned by both lanes; needs both lanes' acknowledgement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant