* feat: register write-scope guard launcher degradations in the degradation registry (#769) The registry claims to index every graceful-degradation mechanism in the suite, but hooks/run_guard.sh's documented degraded states had no rows, and the #757 prose table in docs/CONTROL_AVAILABILITY.md stood up a second, unpinned authority for those facts. Four write_scope_guard_* rows added (no-python, no-git-bash, no-timeout-binary, subprocess-misbehaves), each with verbatim D3 authority anchors into hooks/run_guard.sh + the README Requirements bullet; pinned_by names scripts/test_run_guard_launcher.py where a CI-executable pin exists (the Windows-without-Git-Bash path never executes the launcher, so its row honestly carries no pin). Registry 1.2.0 -> 1.3.0; _EXPECTED_MECHANISMS updated in the same commit (D5 lock semantics). The CONTROL_AVAILABILITY degradations table now declares itself a convenience summary backpointing at the registry. Closes #769 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NZwcSFBwiJBZEtsSTcCxq * review: address codex findings on #769 — permission phrasing, no-timeout decision forwarding, launcher-internal failure coverage - Rows no longer claim "writes are never blocked" or relitigate what an 'allow' decision would do: the launcher emits no permissionDecision, so the session's normal permission rules still decide. - The no-timeout row's terminal_policy_effect states that the healthy watchdog fallback forwards the guard's real decision (including deny); only an overrun resolves to pass-through. - The misbehaves row now also covers the two remaining documented launcher-internal degradations (SELF_DIR self-resolution failure and the POSIX payload-length cap on multi-megabyte Writes), with verbatim anchors; CHANGELOG + CONTROL_AVAILABILITY backpointer updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NZwcSFBwiJBZEtsSTcCxq * review: round-2 codex findings on #769 — per-row quantifiers, actual validity-check shape, payload-edge honesty - terminal_policy_effect now speaks per failure path, not "every degraded path"; the no-Git-Bash row states the hook simply does not run. - The misbehaves row names the launcher's ACTUAL validity check (a JSON object carrying a top-level hookSpecificOutput key — deliberately shallow, not full hook-schema validation). - The multi-megabyte payload edge is recorded as a documented accepted, untested case with no pinned outcome — no deterministic claim. - The no_python row's authority anchor swaps to the no-permissionDecision pass-through line (the launcher's disputed 'allow' comment is pre-existing text this PR neither adds nor endorses). - CONTROL_AVAILABILITY prose quantifier fixed to match ("none of which ever blocks", with the no-timeout forwarding stated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NZwcSFBwiJBZEtsSTcCxq * review: round-3 codex findings on #769 — payload edge split into its own no-pinned-outcome row - write_scope_guard_payload_capacity_edge becomes a dedicated row whose every field honestly declares "no pinned outcome" — the misbehaves row's pass-through claims are now unconditionally true for its own failure classes (registry 20 -> 21 rows, D5 lock updated). - CONTROL_AVAILABILITY prose reworded: degraded states never INTRODUCE a block; the no-timeout swap keeps the guard operating normally (real decisions, including deny, still apply). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NZwcSFBwiJBZEtsSTcCxq --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
11 KiB
Control Availability by Install Channel
Purpose. ARS documentation names several controls — the write-scope guard, the citation-verification gate, mandatory checkpoints, the tools allowlist. Which of those actually operate depends on how you installed ARS. This page maps mechanism × channel in one place, so a user evaluating an integrity claim can see whether it holds in their channel. The linked source documents remain authoritative for each fact.
Origin. ISO/IEC 42001-spirit gap assessment
(audits/iso42001-spirit-gap-assessment-2026-08-17.md,
finding T-6, #757).
Transparency here is one of this repo's distilled operating principles (with informative
anchors to ISO/IEC 42001) — not an ISO-mandated artifact.
Install channels
| Channel | Documented in | Channel-wide limitation |
|---|---|---|
| Plugin — Claude Code plugin install | SETUP Method 0 | None — the reference channel. |
Skills copy — skill folders copied into a project's .claude/skills/ or the global ~/.claude/skills/ |
SETUP Method 1 | Nothing wired by the plugin manifest runs (note 3). |
| Repo clone — Claude Code run inside a clone of this repository | SETUP Method 2 | Nothing wired by the plugin manifest runs (note 3). |
| Cowork — skills uploaded to Claude Cowork (desktop) | SETUP Method 3 | Each skill runs standalone: no Task-tool subagent dispatch, so the coordinated pipeline — and its staged checkpoints — does not run as designed. |
| claude.ai Project — repo attached to a claude.ai Project as retrievable knowledge | SETUP Method 4 | Read-only knowledge: Claude can read and cite the skill bodies, but nothing executes — no activation, routing, hooks, scripts, or orchestration. (The Method 4a upload path is documented but not recommended; see SETUP § Method 4a.) |
| Claude Science — skills imported via "Import from GitHub" | SETUP Method 5 | Methodology layer only; Claude Code-specific machinery does not transfer, and Claude Science substitutes its own agent system (details: SETUP Method 5). Imports are point-in-time snapshots. |
| Pi port — community-maintained wrapper for the Pi coding agent | pi/README.md |
Two documented boundaries: the wrapper itself supplies no agent isolation or orchestration — an installed Pi orchestration capability is used when available, otherwise roles run sequentially (degraded execution, disclosed, not independent multi-agent review) — and no Claude hooks (write-scope enforcement stays prompt-level). /ars-pi-doctor reports what the local environment supplies. |
Availability matrix
Legend: Active = operates as documented · Conditional = operates only under the noted conditions, with a defined degraded state otherwise · Absent = does not operate in this channel. Read down your channel's column: a claim about a mechanism holds only where its row says Active — or Conditional with the linked note's conditions met — after applying your channel's channel-wide limitation above.
| Mechanism | Plugin | Skills copy | Repo clone | Cowork | claude.ai Project | Claude Science | Pi port |
|---|---|---|---|---|---|---|---|
Methodology layer (the four skills' SKILL.md protocols) |
Active | Active | Active | Active | Conditional | Active | Active |
| Skill auto-routing (trigger keywords → skill activation) | Active | Active | Active | Active | Absent | Conditional | Conditional |
/ars-* slash commands |
Active ⁽¹⁾ | Absent | Absent | Absent | Absent | Absent | Conditional |
| SessionStart announce + update reminder | Conditional ⁽⁸⁾ | Absent ⁽³⁾ | Absent ⁽³⁾ | Absent | Absent | Absent | Absent |
Write-scope guard (PreToolUse hook) |
Conditional ⁽²⁾ | Absent ⁽³⁾ | Absent ⁽³⁾ | Absent | Absent | Absent | Absent |
| Plugin agents with tools allowlist (#514) ⁽⁴⁾ | Active | Absent ⁽³⁾ | Absent ⁽³⁾ | Absent | Absent | Absent | Absent |
| Subagent orchestration (Task-tool multi-agent dispatch) | Active | Active | Active | Absent | Absent | Absent | Conditional |
Python-backed opt-in features (repo scripts/) |
Conditional ⁽⁵⁾ | Conditional ⁽⁵⁾ | Conditional ⁽⁵⁾ | Absent | Absent | Absent | Conditional ⁽⁵⁾ |
| Cross-model verification (consent-gated second model) | Conditional ⁽⁶⁾ | Conditional ⁽⁶⁾ | Conditional ⁽⁶⁾ | Absent | Absent | Absent | Absent |
| Prompt-level checkpoints and integrity gates | Active ⁽⁷⁾ | Active ⁽⁷⁾ | Active ⁽⁷⁾ | Conditional | Absent | Conditional | Conditional |
CI-side checks (mutation-tested lints, content locks, changelog gates) are deliberately
not a matrix row: they run in this repository's GitHub Actions, protecting the
published artifact all channels ship from, and never run on a user machine —
identical for every channel. They do not all enforce at the same strength or fire on
every change: the per-workflow classification (blocking / advisory / administrative /
post-push detection, with triggers and bypass tokens) is
ARCHITECTURE.md §7.1. The machine-readable index of the suite's
runtime graceful-degradation mechanisms is
shared/contracts/degradation_registry.json.
Notes
- Plugin installs namespace commands as
/academic-research-skills:ars-<mode>; a bare/ars-<mode>alias also works on recent Claude Code versions — the exact minimum version and the older-version behavior are documented in SETUP Method 0 (#633). - The write-scope guard needs a real Python interpreter and a
bashto run its launcher; missing either produces a defined degraded state, never a block — see the environment degradations table. The guard is optional subagent hardening; core skills are unaffected when it is inactive (README Requirements). - Hooks and plugin agents are wired by the plugin manifest (
hooks/hooks.json,agents/, resolved viaCLAUDE_PLUGIN_ROOT). A skills-copy or repo-clone install does not wire them: thePreToolUsewrite-scope guard and the SessionStart announce do not run, and agent dispatch uses the in-skill prompt templates without the frontmatter tools allowlist. A user may wire the hook into their own Claude Code settings manually, at which point the note-2 conditions apply. - The allowlist's canonical contents live in the three plugin agents' frontmatter,
pinned in CI by
scripts/check_tools_allowlist.py— this page deliberately does not restate the list. - These features (e.g. the citation-verification gate CLI, the revision
token-conservation checker, the submission-package verifier, the PDF read preflight,
the cache commands — a non-exhaustive, growing set) shell out to Python scripts at
the repository root (
scripts/,shared/), not inside the four skill folders. They need (a) a real Python interpreter and (b) the repo checkout present: automatic for the plugin channel (the plugin root is the repo snapshot) and repo clones; for a skills-copy install, keep the original clone — the copied skill folders alone cannot run them. On Pi, they work if Python and the repo are present (pi/README.md). - Note-5 conditions, plus a transport: provider API credentials and
curlfor the general transports, or — for the citation-only calls — a Codex CLI ChatGPT-subscription login (ARS_CROSS_MODEL_TRANSPORT=codex). All transports sit behind the same boundary defined inshared/cross_model_verification.md: the user's explicit consent per session — theARS_CROSS_MODELenvironment variable is configuration, not consent. Unset, the feature is invisible and makes zero network calls. - The MANDATORY checkpoints, integrity gates, and IRON RULE constraints are prompt-level, trust-based controls with audit trails, executed by the session model following the skill instructions — not coercive runtime enforcement. Documented overrides require recorded reasoning, and final integrity responsibility stays with the human researcher (see the gap assessment §3). This row says the instructions are present and active in the channel, nothing stronger.
- The SessionStart hook is launched through
bash, so on Windows it needs Git Bash (the same PowerShell limitation as the guard launcher); its update-reminder path additionally needscurl, stays silent on any failure, and is disabled entirely byARS_UPDATE_CHECK=0(SETUP Method 0).
Environment degradations within a channel
Independent of install channel, the write-scope guard has documented degraded states.
None of them introduces a block: launcher failure paths resolve to pass-through,
and a missing timeout binary is a bounding-mechanism swap under which the guard keeps
operating normally — its real decisions (including deny) still apply, with only an
overrun resolving to pass-through. The guard is an optional
hardening layer, and a broken guard must not lock a user out of their own files
(maintainer decision recorded in hooks/run_guard.sh; user-facing summary in the
README Requirements bullet). This table is a convenience summary, not a second
authority: the indexed rows are the write_scope_guard_* mechanisms in
shared/contracts/degradation_registry.json
(#769), whose anchors into hooks/run_guard.sh are lint-pinned, and which also cover
two states this table omits — guard subprocess misbehaves or the launcher fails
internally (→ pass-through), and the documented multi-megabyte payload edge (an
accepted, untested case with no pinned outcome):
| Condition | Behavior |
|---|---|
| No real Python found (Git Bash / POSIX shell present) | Guard silently no-ops (pass-through); core skills unaffected. On Windows, the 0-byte Microsoft Store python3 stub is rejected, not mistaken for Python. |
| Windows without Git Bash | Claude Code falls back to PowerShell, which cannot run the .sh launcher: guard inactive, and the PreToolUse hook logs an error per call (accepted degradation — noisy, never blocking). |
No timeout binary |
Portable background-watchdog fallback with the same wall-clock bound and the same pass-through-on-overrun posture. |