Skip to content

fix(init): Tirith integration is detect-only — do NOT modify shell rc - #5

Merged
thehoff merged 1 commit into
developfrom
fix/tirith-detect-no-shell-touch
May 14, 2026
Merged

thehoff merged 1 commit into
developfrom
fix/tirith-detect-no-shell-touch

Conversation

@thehoff

@thehoff thehoff commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Reverts the shell-rc-write behavior introduced in PR #2 (commit 6f65f9d).

PR #2's `install_tirith_shell_hook` appended an `eval "$(tirith init --shell )"` block to the user's `.bashrc`/`.zshrc`/`config.fish`. That was the wrong design call on my part — the ContextCrawler Tirith integration lives at the Claude Code rewrite gate (`hooks/tirith_gate.rs` calls `tirith check` as a subprocess right before auto-allowing a rewrite). The user's interactive shell isn't part of the gate's value path and must not be modified by `contextcrawler init -g`.

What changed

Before (PR #2) After (this PR)
Tirith detected Append eval block to ~/.bashrc Print "Tirith gate: ARMED"
Tirith missing Print install hint Print fail-open notice + install hint
Files touched outside ~/.claude/ yes (~/.bashrc, ~/.zshrc, ~/.config/fish/config.fish) none
Helper functions shell_rc_path, build_tirith_block, rc_has_tirith_sentinel, detect_shell (all removed)
Tests 5 helper tests + 1 idempotency test 1 smoke test (never_panics)

New output

When Tirith is installed:
```
Tirith gate: ARMED — Claude Code rewrites pass through `tirith check`
before auto-allow (subprocess invocation only).
```

When Tirith is not installed:
```
Tirith gate: fail-open (binary not on PATH)
Optional URL-security defense-in-depth:
cargo install tirith
No shell config is modified by ContextCrawler either way.
```

Test plan

  • `cargo test` — 1785 passed / 0 failed / 6 ignored
  • Devel-test on Framework: `contextcrawler init -g` reports Tirith status without modifying any shell rc file

🤖 Generated with Claude Code

PR #2 (feat/init-chains-tirith, commit 6f65f9d) appended an
`eval "$(tirith init --shell <shell>)"` block to the user's
`.bashrc`/`.zshrc`/`config.fish`. That was the wrong design: the
ContextCrawler Tirith integration lives at the Claude Code rewrite
gate (`hooks/tirith_gate.rs` calls `tirith check` as a subprocess
right before auto-allowing a rewrite). The user's interactive shell
is not part of the gate's value path and should not be modified by
`contextcrawler init -g`.

This change:

* Replaces `install_tirith_shell_hook` with `report_tirith_status`.
  Tirith presence is detected; no filesystem write happens outside
  `~/.claude/`.
* Removes the helpers that only existed for the rc-write path:
  `detect_shell`, `shell_rc_path`, `rc_has_tirith_sentinel`,
  `build_tirith_block`, and the `TIRITH_SENTINEL_{START,END}`
  constants.
* Drops the 5 unit tests for those removed helpers; keeps a single
  smoke test (`test_report_tirith_status_never_panics`) covering the
  remaining surface.
* Sentinel comments updated to document the design choice
  explicitly so it doesn't get re-introduced.

Output after `contextcrawler init -g` is now one of:

  Tirith gate: ARMED — Claude Code rewrites pass through `tirith check`
               before auto-allow (subprocess invocation only).

or

  Tirith gate: fail-open (binary not on PATH)
    Optional URL-security defense-in-depth:
      cargo install tirith
    No shell config is modified by ContextCrawler either way.

Verified: cargo test → 1785 passed / 0 failed / 6 ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thehoff
thehoff merged commit c63c2c6 into develop May 14, 2026
3 checks passed
@thehoff
thehoff deleted the fix/tirith-detect-no-shell-touch branch May 14, 2026 13:11
@thehoff thehoff mentioned this pull request May 14, 2026
3 tasks done
thehoff added a commit that referenced this pull request Jun 5, 2026
A failed `go build` whose stderr matched none of the error heuristics
printed "Go build: Success" while the runner correctly propagated the
non-zero exit code — a user-facing message that contradicted reality.

Adapt upstream rtk-ai/rtk f69ad6e to the fork:

- runner: add `FilteredWithExit` RunMode + `run_filtered_with_exit`,
  handing the filter the child's exit code. Both filter modes share a
  new `run_captured_filter` helper that keeps the fork-only no-bloat
  guard (issue #95) and verbatim exit-code propagation (RTK rule #5).
- go_cmd: split `filter_go_build` into an exit-aware
  `filter_go_build_with_exit`. With no recognised error line it now
  emits "Go build: Success" only on exit 0, otherwise a neutral
  "Go build: failed (exit N)" message that surfaces the raw output.
  The exit-blind `filter_go_build` is retained as a thin wrapper
  (exit 0) for existing callers/tests. Recognised-error path unchanged.

Exit-code propagation itself is untouched.

Tests: success (exit 0) -> "Success"; failed build (non-zero exit) with
no recognised error line -> failure message, never "Success"; failed
build with recognised error lines -> errors shown as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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