Skip to content

fix(runtime-bridge): consumer setup script auto-writes settings.json (NC-3 scoped) - #311

Merged
artyhoo merged 1 commit into
stagingfrom
fix/consumer-setup-autowrite-nc3
May 31, 2026
Merged

fix(runtime-bridge): consumer setup script auto-writes settings.json (NC-3 scoped)#311
artyhoo merged 1 commit into
stagingfrom
fix/consumer-setup-autowrite-nc3

Conversation

@artyhoo

@artyhoo artyhoo commented May 31, 2026

Copy link
Copy Markdown
Owner

What

setup-runtime-bridge.sh now offers to auto-write the consumer's .claude/settings.json PostToolUse entry (with consent + safety), instead of only printing a snippet to paste by hand.

Insight (live setup session 2026-05-31): the .claude/settings.json deny-list (Edit(.claude/settings.json) / Write(.claude/settings.json), lines 56-57) binds only the AI agent's tool calls — NOT a shell script a human runs. So the human-run consumer setup script can safely write settings.json. NC-3 is scoped, not deleted: the agent deny-list stays; only the human-run setup path gains the ability.

Auto-write behaviour

On y to the bridge install → [Y/n] sub-prompt (default Y); on confirm + python3 present → idempotent patch (backup → append → JSON-validate → atomic swap). Degrades to print-only when --no-write-settings, consent declined, or python3/patch fails. Never a silent clobber.

Files (4)

  • packages/runtime-bridge/scripts/setup-runtime-bridge.sh--no-write-settings flag, header update, the consent+auto-write block, reframed fallback message
  • docs/runtime-bridge-setup.md — Quick-start "yes" bullet now describes auto-write-with-consent + fallback + agent-vs-human distinction (Authoritative-for header untouched)
  • .claude/hooks/runtime-bridge-dispatch.sh — NC-3 comment qualified (agent must not; human script may)
  • packages/runtime-bridge/DESIGN.md — new ## NC-3 scope history (2026-05-31) section (tracked rationale home; orchestrator-prompts/ is gitignored). SW-B's historical §1.7 record at line 44 left intact.

🟢 Pre-merge (verified locally)

  • bash -n setup-runtime-bridge.sh → syntax OK
  • T19 cold-QA (independent orchestrator run): settings.json with 5 unrelated PostToolUse hooks → 5→6, all 5 originals byte-preserved, 6th = runtime-bridge, permissions.deny intact, .bak created
  • Idempotency: re-run stays 6, prints "already present — skipping"
  • Missing-file: non-existent path → creates valid settings.json (0→1), no spurious .bak
  • Fallback: --no-write-settings / python3-absent → print-only, no mutation
  • Agent deny-list unchanged: .claude/settings.json diff is empty (T15/T16)
  • markdownlint-cli2 on both docs → 0 errors
  • Scope clean: diff = exactly the 4 files above, 0 drift (T5)

🟡 Post-merge

  • CI green on staging (auto-merge gate)

§1.7 Forward-check applied

Checked the new behaviour against existing disciplines. no-paid-llm-in-ci.md — compliant: the auto-write is pure bash + stdlib python3 with zero API calls (packages/runtime-bridge/scripts/setup-runtime-bridge.sh:1). doc-authority-hierarchy.md — the Authoritative-for header in docs/runtime-bridge-setup.md:3 is preserved; only the behavioural Quick-start bullet changed. dual-implementation-discipline.md:1 — the §6 @dual-pair / @cc-only-rationale grep targets .claude/hooks/*.sh only, so it is correctly N/A to this packages/runtime-bridge/scripts/ human-run harness-agnostic script (it IS the portable artefact, not a CC-native primitive needing a fallback). NC-3 is scoped, not deleted.

§1.7 Backward-check applied

Swept the artefacts this change touches. Agent deny-list unchanged — .claude/settings.json:56 (Edit/Write(.claude/settings.json)) is untouched (the file's diff is empty), so the agent path is unaffected (T15/T16). SW-B's historical §1.7 backward record at packages/runtime-bridge/DESIGN.md:44 ("NOT modified (NC-3)") is left intact — the NC-3 scope note was appended as a separate dated ## NC-3 scope history section rather than rewriting the historical record. The NC-3 comment in .claude/hooks/runtime-bridge-dispatch.sh:27 was qualified (agent must not; human script may), not deleted. No other artefact silently superseded.

Prior-art

aif-handoff installMcpServer writes AI-runtime config (~/.claude.json / ~/.codex/config.toml) from a setup action — "setup-script writes AI-runtime config" is an established pattern, not novel. Not a capability commit (modifies existing 125-LOC script; no new ≥80-LOC file, no new dep) → no SSOT row, no mandatory trailer; trailer added for traceability.

🟢 Простыми словами

Раньше скрипт настройки только печатал кусок JSON, который пользователь должен был сам вставить в .claude/settings.json — потому что AI-агенту запрещено трогать этот файл. Но запрет — это deny-list на инструменты агента, а не замок на файле: shell-скрипт, который запускает живой человек, под запрет не попадает. Теперь скрипт сам предлагает дописать нужную строчку (спросив согласие), с резервной копией, проверкой JSON и сохранением всех существующих хуков — а если что-то не так (нет python3 / отказались / --no-write-settings), откатывается к старому «вот текст, вставь сам». Запрет для агента при этом остался нетронутым.

…try in setup script

Relaxes NC-3 for the human-run consumer setup path only. The agent
deny-list ("Edit(.claude/settings.json)" / "Write(.claude/settings.json)"
in .claude/settings.json) binds the AI agent's tool calls — not a shell
script run by a human. setup-runtime-bridge.sh now:
  - asks Y/n consent before writing (skip with --no-write-settings)
  - is idempotent (skips if runtime-bridge entry already present)
  - backs up settings.json → settings.json.bak before writing
  - handles missing file: starts from {} instead of crashing
  - JSON-validates before atomic swap
  - preserves all existing PostToolUse hooks (parse + append, never overwrite)
  - degrades gracefully to print-only if python3 absent or consent declined

Agent deny-list unchanged (settings.json lines 56-57 untouched).
NC-3 scope history recorded in packages/runtime-bridge/DESIGN.md.

Prior-art: aif-handoff installMcpServer pattern (setup-script writes
AI-runtime config file — ~/.claude.json / ~/.codex/config.toml) confirms
"setup-script writes AI-runtime config" is an established pattern, not
novel. No new capability file ≥80 LOC; modifies existing script.
@artyhoo
artyhoo enabled auto-merge (squash) May 31, 2026 16:08
@artyhoo
artyhoo merged commit ecb6457 into staging May 31, 2026
22 checks passed
artyhoo added a commit that referenced this pull request Jun 1, 2026
…te-nc3 umbrella (#311) (#334)

Umbrella-closure marker (CLAUDE.md «Umbrella closure convention») left uncommitted
by the session that closed PR #311 (2026-05-31). priority-score.sh completion-detection
Layer C3 reads done.md existence — committing so #311 detects as DONE.

Prior-art: skipped — orchestrator closure-marker doc, no new capability
artyhoo added a commit that referenced this pull request Jun 1, 2026
)

Operator-side bookkeeping: (1) scripts/setup-cc-adoptions.sh — idempotent
wiring of the merged census adoptions (SubagentStart hook #330; verifies
inject-matching-rule #331 dual-pair; Channels guidance; backs up + jq-merges
settings.json, run by the maintainer). (2) Three done.md closure markers for
already-merged umbrellas (#333 companion-adoption-iphase, #321
companion-capability-survey, #311 consumer-setup-autowrite-nc3) — all final PRs
verified MERGED; priority-score.sh Layer C3 reads these.

Prior-art: skipped — operator script under scripts/ (not packages/, no new dep/capability) + done.md closure records; not a capability commit
artyhoo added a commit that referenced this pull request Jun 10, 2026
Task 3 of one-click-installer plan (S2 engine sub-wave). engine.sh is
verbatim from the plan. One deviation in the test: the dry-run case uses
grep -qx (whole-line) instead of grep -q — the plan-verbatim pair is
internally inconsistent (engine's dry-run message echoes install_cmd,
substring grep flags the echo as execution → PASS=4). Whole-line match
detects actual execution only; mutation-checked (eval-in-dry-run mutant
is caught). Spec mandates dry-run prints the plan, so the engine output
keeps the command.

Prior-art: aif-handoff installMcpServer precedent (spec §11; same pattern as commit ecb6457 / PR #311).
artyhoo added a commit that referenced this pull request Jun 10, 2026
… bridge) (#447)

Prior-art: aif-handoff installMcpServer precedent (spec §11; same pattern as commit ecb6457 / PR #311).
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