sphinx-understand 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.sphinxconfig.example +10 -0
  2. package/.sphinxignore.example +22 -0
  3. package/CONTRIBUTING.md +19 -0
  4. package/LICENSE +21 -0
  5. package/README.md +186 -2
  6. package/bin/sphinx.js +9 -0
  7. package/docs/architecture.md +212 -0
  8. package/docs/configuration.md +241 -0
  9. package/docs/integrations.md +135 -0
  10. package/docs/logo.svg +3 -0
  11. package/eval/README.md +38 -0
  12. package/eval/RESULTS.md +205 -0
  13. package/eval/fixtures/known-false-negatives.json +115 -0
  14. package/examples/browser-demo.mjs +28 -0
  15. package/examples/config.json +59 -0
  16. package/package.json +50 -4
  17. package/src/activation-worker.js +10 -0
  18. package/src/activation.js +187 -0
  19. package/src/agent-settings.js +206 -0
  20. package/src/agent.js +45 -0
  21. package/src/browser-interview.js +344 -0
  22. package/src/browser-page.js +427 -0
  23. package/src/change-view.js +314 -0
  24. package/src/check-recovery.js +92 -0
  25. package/src/checkbox.js +148 -0
  26. package/src/cli.js +563 -0
  27. package/src/config.js +248 -0
  28. package/src/cursor-hook.js +18 -0
  29. package/src/evaluator.js +501 -0
  30. package/src/git-gate.js +116 -0
  31. package/src/git-interview.js +51 -0
  32. package/src/git.js +252 -0
  33. package/src/help.js +122 -0
  34. package/src/ignore.js +94 -0
  35. package/src/install.js +448 -0
  36. package/src/lifecycle-integrations.js +259 -0
  37. package/src/logo.js +6 -0
  38. package/src/mcp.js +352 -0
  39. package/src/model-presets.js +79 -0
  40. package/src/native-check.js +166 -0
  41. package/src/openrouter.js +269 -0
  42. package/src/overrides.js +68 -0
  43. package/src/pi-integration.js +179 -0
  44. package/src/pi-runtime.js +128 -0
  45. package/src/preparation.js +254 -0
  46. package/src/presentations.js +74 -0
  47. package/src/prompts.js +181 -0
  48. package/src/repo-config.js +72 -0
  49. package/src/repo-context.js +43 -0
  50. package/src/review-workspace.js +334 -0
  51. package/src/reviewer-limits.js +10 -0
  52. package/src/reviewer-response.js +22 -0
  53. package/src/reviewer.js +527 -0
  54. package/src/routing.js +40 -0
  55. package/src/sessions.js +377 -0
  56. package/src/stream.js +59 -0
  57. package/src/terminal-launch.js +288 -0
  58. package/src/terminal-worker.js +11 -0
  59. package/src/terminal.js +121 -0
  60. package/src/usage.js +31 -0
  61. package/src/version.js +4 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 1,
3
+ "enabled": true,
4
+ "events": ["pre-push"],
5
+ "branches": ["main"],
6
+ "remotes": ["*"],
7
+ "level": "standard",
8
+ "mode": "block",
9
+ "exclude": []
10
+ }
@@ -0,0 +1,22 @@
1
+ # Copy this file to .sphinxignore at your repository root and choose your exclusions.
2
+ # Only committed/index metadata is inspected before these rules filter content.
3
+
4
+ # Generated files and assets that should not enter a code-comprehension assessment.
5
+ dist/
6
+ coverage/
7
+ **/*.generated.*
8
+ *.min.js
9
+ *.png
10
+ *.jpg
11
+ *.woff2
12
+
13
+ # Use leading / for repository-root paths, or a bare name at any depth.
14
+ /private-notes/
15
+
16
+ # Negation can restore a path excluded earlier in this same file.
17
+ # It cannot restore built-in sensitive files, global ignores, or config exclusions.
18
+ !dist/handwritten.js
19
+
20
+ # Sensitive defaults are always excluded: .env/.env.*, private keys,
21
+ # common credentials JSON files, .netrc, .npmrc, .pypirc, and others.
22
+ # Add machine-wide patterns to $SPHINX_HOME/ignore.
@@ -0,0 +1,19 @@
1
+ # Contributing to Sphinx
2
+
3
+ Use Node.js 22.19+, install the pinned dependencies with `npm ci`, and run `npm test`. Tests must not call real models, change real agent settings, or modify a developer's global Git configuration. The test runner blocks outbound Node requests while permitting local fixtures.
4
+
5
+ Keep trigger policy deterministic and separate from model judgment. Preserve existing hooks. Filter paths before reading code. New integrations need isolated install/uninstall tests and clear coverage limitations.
6
+
7
+ The most useful assessment contributions are small, reproducible change fixtures with:
8
+
9
+ 1. A baseline and patch with no private data.
10
+ 2. The observable behavior or invariant a developer should understand.
11
+ 3. A bounded question with stated assumptions.
12
+ 4. Accepted answers and causal reasoning, including valid alternative explanations.
13
+ 5. Common misconceptions and a new scenario that tests transfer after teaching.
14
+
15
+ Question-quality evaluation should include ambiguous questions and cases where an answer correctly identifies a bug. Do not grade on naming trivia, prose style, or similarity to a single model-written answer.
16
+
17
+ Run `npm run eval -- --out /tmp/sphinx-eval.json` for the deterministic fixture baseline. Use the separately authorized, bounded live workflow in [eval/README.md](eval/README.md) to measure model quality. Retain generated questions, source evidence, grading probes, and request/cost totals when comparing changes. Never answer a real human checkpoint as part of testing.
18
+
19
+ Before proposing a stronger model or additional model calls, measure whether the change improves the assessment enough to justify its usage. Keep model selection explicit and avoid silent paid fallback.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sphinx contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,187 @@
1
- # Temporary Holding Version
1
+ <p align="center"><img src="docs/logo.svg" width="96" alt="Sphinx logo"></p>
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <h1 align="center">Sphinx</h1>
4
+
5
+ <p align="center"><em>Outsource your thinking, not your understanding.</em></p>
6
+
7
+ Sphinx adds an understanding check to agent-assisted development. When you push to a protected branch, Git waits while Sphinx asks you to predict what your change will do. If you miss something, it explains and gives you a new scenario to try. Once you pass, the same push continues. This works whether you or a coding agent ran `git push`.
8
+
9
+ The questions come from a separate reviewer model. It reads the committed change through read-only Git tools and does not see the conversation that produced the code.
10
+
11
+ ## What a check looks like
12
+
13
+ This is an illustrative exchange for a change that adds a background job queue:
14
+
15
+ > **Question.** The worker commits the operation but crashes before acknowledging the job. After redelivery, can the operation happen twice? Give a short reason.
16
+ >
17
+ > **Your answer.** No, the job is marked done when the operation commits.
18
+ >
19
+ > **Sphinx.** Not quite. The job is only marked done by the acknowledgement, which happens after the commit. A crash between the two leaves it unacknowledged, so the queue delivers it again and the operation runs a second time.
20
+ >
21
+ > **New scenario.** A worker stalls past the visibility timeout, so a second worker receives the same job. Both commit before either acknowledges. What stops a duplicate, if anything?
22
+
23
+ Questions cover behavior, failure modes, and invariants rather than file names or function names. The check is open-book: you can read the code, or ask your agent to show it to you, while you answer.
24
+
25
+ ## Before you install
26
+
27
+ - **Requirements.** Node.js 22.19 or newer, Git, and macOS, Linux, or WSL. Native Windows is not supported yet.
28
+ - **It applies to every repository on this machine.** `sphinx install` sets your global Git `core.hooksPath`. Your existing hooks still run first. Right after install, pushes to `main` or `master` in any repository are checked. `sphinx init` lets you adjust that for each repository.
29
+ - **It blocks Git.** A matching push waits until you pass, pause, or skip, for up to 25 minutes. Your coding agent's shell may time out sooner.
30
+ - **You need a reviewer model account.** This can be a signed-in Codex or Claude Code CLI, which uses that plan's allowance. It can also be an OpenRouter API key, which bills separately and is required even for free models, or any [OpenAI-compatible endpoint](docs/configuration.md#openai-compatible-endpoints). Sphinx has no account or hosted service of its own.
31
+ - **Code leaves your machine.** The reviewer provider receives the changed code and related files from the commit, your answers, and `.sphinxcontext.md`. Ignored files are never read, and `.env` files, private keys, and common credential files are excluded by default. Add your own sensitive paths to `.sphinxignore` before your first check. Ignore rules match file paths, so they will not catch a secret pasted into ordinary source.
32
+ - **There is no default cap on model calls.** A typical check makes about 5 to 8 requests, plus about one per answer. You can [set a cap](docs/configuration.md#model-calls-tokens-and-limits), and you should set spending limits with paid providers.
33
+ - **This is practice, not a security gate.** Anyone with local access, including a coding agent, can bypass hooks or get outside help. Passing does not prove who wrote the code or that you understood it unaided. The examiner is an LLM and can be wrong.
34
+
35
+ ## Quick start
36
+
37
+ ### 1. Install (required)
38
+
39
+ ```sh
40
+ npm install -g sphinx-understand
41
+ sphinx install
42
+ ```
43
+
44
+ Guided setup asks which coding agents you use and which reviewer to use. It suggests Haiku through Claude Code or GPT-6 Luna through Codex. If you choose OpenRouter, it asks for an API key. It then offers the recommended checkpoints (pushes to `main` or `master` at standard depth) or **Customize** to pick events, branches, remotes, and depth. To install without prompts:
45
+
46
+ ```sh
47
+ sphinx install --yes --preset claude-economy --agents claude
48
+ ```
49
+
50
+ You should see:
51
+
52
+ ```text
53
+ ✓ Git hooks installed for this user. Existing hooks are chained.
54
+ ✓ Claude Code native questionnaire hooks and Sphinx MCP server installed.
55
+ ```
56
+
57
+ Use `--preset codex-economy` for Codex, or `--agents none` if you don't use a coding agent. Other presets, OpenRouter, OpenAI-compatible endpoints, and custom routes are covered in [configuration](docs/configuration.md#reviewer-models).
58
+
59
+ ### 2. Load Sphinx in your coding agent (required if you use one)
60
+
61
+ Guided setup opens your selected agents in fresh sessions. Then:
62
+
63
+ - **Codex:** open `/hooks` and trust the Sphinx hooks. Sphinx cannot do or verify this for you.
64
+ - **Claude Code:** start a new session. `/mcp` should show `sphinx` connected.
65
+ - **Pi, Cursor, OpenCode:** see [per-client notes](docs/integrations.md#per-client-notes).
66
+
67
+ If you skip this step, the Git checkpoint still works. However, your agent won't know it should wait for a blocked push, and the fallback forms used when the browser can't open won't be available.
68
+
69
+ ### 3. Set up a repository (required)
70
+
71
+ ```sh
72
+ cd your-repo
73
+ sphinx init
74
+ ```
75
+
76
+ This asks which branches and events to check and how deep the questions should go. Then it creates three files without overwriting existing ones:
77
+
78
+ - `.sphinxconfig`: the repository's policy.
79
+ - `.sphinxignore`: paths that are never read. **Edit this now** if the repository has private or generated files.
80
+ - `.sphinxcontext.md`: a short description of what the project does, which every reviewer request receives. Leave out secrets.
81
+
82
+ To set it up without prompts:
83
+
84
+ ```sh
85
+ sphinx init --yes --branches main
86
+ ```
87
+
88
+ Commit the three files to share the policy with collaborators.
89
+
90
+ ### 4. Check the setup (recommended)
91
+
92
+ ```sh
93
+ sphinx doctor
94
+ ```
95
+
96
+ It should end with `✓ Configured integrations are in place.` and exit with status 0. If not, it says what needs attention, such as a repository with its own hooks directory. Fix that with `sphinx install --repo`.
97
+
98
+ ### 5. Push and pass your first check
99
+
100
+ ```sh
101
+ git push origin main
102
+ ```
103
+
104
+ Git prints the questionnaire address and waits:
105
+
106
+ ```text
107
+ Sphinx: understanding check needed for refs/heads/main (medium change).
108
+ Sphinx: Git is waiting for your answers in the local Sphinx questionnaire. It will continue automatically after you pass. Do not start another copy of this Git operation.
109
+ Sphinx questionnaire: http://127.0.0.1:56114/fSdZM7yg…
110
+ Sphinx: questionnaire opened in a background browser tab. Your coding window stays in place.
111
+ ```
112
+
113
+ On macOS, the page opens in a background browser tab. On Linux, WSL, and over SSH, Git prints `open the local URL above to answer` instead, so open the printed address yourself. From a remote session, forward the same port and open the URL unchanged, or run `sphinx check`; see [remote machines](docs/integrations.md#remote-machines-ssh-and-ci). Questions can take a moment while the reviewer reads the change, and the page shows its progress as it works. Beside each question, the page shows the checkpoint's changed files, lines added and removed, a browsable diff, and the code locations the reviewer read for that question. Answer each question with a prediction and a short reason. When you pass:
114
+
115
+ ```text
116
+ Sphinx: understanding check complete. Continuing this Git operation.
117
+ To github.com:you/your-repo.git
118
+ * [new branch] main -> main
119
+ ```
120
+
121
+ Pushing the same change again does not ask again. A pass lasts 24 hours, unless the code, destination, or policy changes.
122
+
123
+ ## During and after a check
124
+
125
+ - **Wrong answer.** You get an explanation and a new scenario about the same concept. Disputes and errors never count as passing.
126
+ - **Explain this.** Shows the concept and asks you a new question.
127
+ - **Dispute question.** Use this if a question's premise is wrong or ambiguous. A bad question must be corrected before that concept can pass.
128
+ - **Pause check.** Saves your progress and stops the push. Run the same `git push` later to pick up where you left off.
129
+ - **Closing the tab** doesn't stop anything. Git keeps waiting, and the same address works until the 25-minute deadline.
130
+ - **Skip this time.** Lets the push through immediately, even while the review is still running. Skips never count as passing.
131
+ - **`sphinx yolo`** turns checks off for the current repository, or globally when run outside one. Run it again to turn checks back on. A repository's own setting wins over the global one, so turning yolo off inside a repository keeps checks on there even while global yolo is on. `--reason "prod hotfix"` is optional.
132
+ - **`sphinx check`** runs the same check in your terminal instead of the browser.
133
+
134
+ Every skip and yolo toggle is logged with its reason, and `sphinx status` lists recent ones. If Git exited before you finished, for example because your agent's shell timed out, run the push once more. Never start a second copy while one is still waiting. For more cases, see [troubleshooting](docs/integrations.md#troubleshooting).
135
+
136
+ Your answers go straight from the page to Sphinx. Your coding agent sees only the check's status, progress, and usage, never your answers.
137
+
138
+ ## Limits and cost
139
+
140
+ Question count depends on the size of the change and the depth you choose. Small changes get one question, and large ones get up to three at the default depth. After commits, Sphinx prepares questions in the background, so they are often ready by the time you push. Calls, tokens, and (when reported) cost appear in the questionnaire.
141
+
142
+ ```sh
143
+ sphinx config --max-model-calls 30 # optional cap per check (1–100)
144
+ sphinx config --preset openrouter-value --allow-paid
145
+ ```
146
+
147
+ Context size, output tokens, and review time are always capped. Provider failures never retry automatically. For routing thresholds, model tables, pricing, and every limit, see [configuration and cost](docs/configuration.md).
148
+
149
+ Version 0.1 checks local commits and pushes only. It does not cover web merges, CI-required checks, or deployments. It cannot read binary file contents, and it tests understanding rather than auditing the code. The [evaluation results](eval/RESULTS.md) record question quality, grading errors, and costs on synthetic changes. They do not certify arbitrary repositories.
150
+
151
+ ## Commands
152
+
153
+ | Command | Use it to |
154
+ | --- | --- |
155
+ | `install` | Set up machine-wide Git hooks and agent integrations |
156
+ | `init` | Create this repository's policy, ignore, and context files |
157
+ | `doctor` | Check hook and integration coverage |
158
+ | `status` | Show this repository's policy, pending checks, and recent skips |
159
+ | `check` | Start or resume a check in the terminal (`--staged` for commits) |
160
+ | `pending` | List unfinished checks |
161
+ | `yolo` | Toggle skipping checks |
162
+ | `config` | Change reviewer models and limits |
163
+ | `auth` | Save your OpenRouter key or an OpenAI-compatible endpoint |
164
+ | `prepare` | Schedule background preparation (`--retry` after a failure) |
165
+ | `activate` | Open configured coding agents without reinstalling |
166
+ | `uninstall` | Remove Sphinx integrations, keeping unrelated settings |
167
+
168
+ Each command explains itself with `sphinx <command> --help`. `--json` gives machine-readable output, and `NO_COLOR=1` turns off color.
169
+
170
+ ## Reference
171
+
172
+ - [Configuration and cost](docs/configuration.md): reviewer models, OpenRouter, pricing, routing, limits, `.sphinxconfig`, `.sphinxignore`, project context, and background preparation.
173
+ - [Integrations and troubleshooting](docs/integrations.md): Codex, Claude Code, Pi, Cursor, OpenCode, fallback forms, SSH, existing hooks, the JSON protocol, and uninstalling.
174
+ - [Architecture](docs/architecture.md): the checkpoint sequence, the reviewer and its evidence, compaction, and state.
175
+ - [Evaluation](eval/README.md) and [results](eval/RESULTS.md).
176
+
177
+ ## Development
178
+
179
+ ```sh
180
+ npm ci
181
+ npm test
182
+ npm run eval -- --out /tmp/sphinx-eval.json
183
+ node bin/sphinx.js --help
184
+ npm install -g . # use this checkout as the installed sphinx
185
+ ```
186
+
187
+ Tests use Node's test runner, real temporary Git repositories, isolated homes, and fixture model backends. The suite makes no live model requests. Never run installer tests against a real home directory or Git configuration. See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.
package/bin/sphinx.js ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../src/cli.js';
3
+ import { formatError } from '../src/terminal.js';
4
+
5
+ try { process.exitCode = await main(process.argv.slice(2)); }
6
+ catch (error) {
7
+ formatError(error, { plain: process.argv.includes('--json') || ['hook', 'mcp'].includes(process.argv[2]) });
8
+ process.exitCode = error.exitCode || 1;
9
+ }
@@ -0,0 +1,212 @@
1
+ # Architecture
2
+
3
+ Sphinx has one local checkpoint engine and thin Git/agent integrations. It embeds `@earendil-works/pi-coding-agent` 1.2.0 for investigative reviewer sessions and requires Node.js 22.19+. Short-lived detached workers prepare reviews; there is no permanent daemon or Sphinx backend service.
4
+
5
+ ```mermaid
6
+ flowchart LR
7
+ PC[Commit or branch update] --> B[Debounced background reviewer]
8
+ B --> PI[Pi reviewer session]
9
+ PI --> W[Filtered Git tools and project context]
10
+ W --> PQR[Prepared questions and evidence]
11
+ G[Git operation] --> P[Deterministic policy]
12
+ P --> F[Filter paths]
13
+ F --> S[Exact snapshot]
14
+ S --> R{Valid completion?}
15
+ R -->|yes| C[Continue original operation]
16
+ R -->|no| Q[Save pending checkpoint and wait]
17
+ Q --> I[Local browser questionnaire]
18
+ PQR --> I
19
+ I --> E[Independent evaluator]
20
+ E -->|misconception| L[Explain and ask new scenario]
21
+ L --> I
22
+ E -->|all concepts resolved| A[Record completion]
23
+ A --> V[Revalidate batch and receipts]
24
+ V --> C
25
+ Q -->|unavailable| H[Native or manual fallback]
26
+ ```
27
+
28
+ ## Checkpoint sequence
29
+
30
+ 1. Git supplies the exact source and destination commits. Sphinx applies branch/event policy and filters paths before reading contents.
31
+ 2. If the exact change already passed, the operation continues. Otherwise the hook saves a pending checkpoint and keeps the original Git process waiting.
32
+ 3. The hook serves a private questionnaire on loopback and prints its URL. Git's stdin and the coding agent's shell are never used for questionnaire input.
33
+ 4. Sphinx reuses matching prepared questions, waits for an in-progress review, or starts a fresh reviewer. The reviewer reads relevant diffs and follows related source and tests before committing questions, private answer keys, and supporting evidence. A separate model request audits the questions against that evidence before display.
34
+ 5. Correct answers clear concepts. An incorrect answer gets an explanation and replaces that concept's question with a different transfer scenario, which receives its own source audit without the human answer or grading conversation. Ambiguity or evaluator failure never creates a completion record.
35
+ 6. Sphinx revalidates every original snapshot and completion record, then returns control to the same Git process without replaying its command. Completion is bound to the exact repository, commits/index, destination, ignore policy, project context, assessment policy, and expiry.
36
+
37
+ ## Modules
38
+
39
+ | Module | Responsibility |
40
+ | --- | --- |
41
+ | `config.js` | Defaults, global/repository settings, canonical/legacy policy discovery, private JSON files, credentials |
42
+ | `repo-config.js` | Exclusive creation of repository policy and ignore files, preserving existing files |
43
+ | `ignore.js` | Sensitive-file exclusions and project/global patterns |
44
+ | `git.js` | Deterministic triggers, filtered object/index evidence, snapshot identities |
45
+ | `routing.js` | Line/file/path tiers, depth-dependent question ceilings, and user-selected model routes |
46
+ | `model-presets.js` | Explicit economy presets, per-tier routes, billing descriptions, and reference sources |
47
+ | `evaluator.js` | Fresh CLI evaluator processes, question/rubric schemas, output validation |
48
+ | `reviewer.js` | Pi reviewer integration, exact observation archive, assessment validation, review budgets |
49
+ | `pi-runtime.js` | Isolated Pi SDK session, model-transport bridge, native compaction, cancellation, cleanup |
50
+ | `review-workspace.js` | Filtered immutable file, diff, listing, and search tools |
51
+ | `repo-context.js` | Bounded project background, ignore checks, context identity |
52
+ | `preparation.js` | Detached scheduling, debounce, exact cache matching, failure status |
53
+ | `openrouter.js` | Authenticated structured-output API requests and free-only price limits |
54
+ | `sessions.js` | Durable checkpoints, locks, progress, counted calls and optional caps, expiration |
55
+ | `presentations.js` | Session-bound queues and hook-owned presentation markers, without code or answers |
56
+ | `git-gate.js` | Waiting Git gate, exact snapshot/receipt revalidation, batch ownership, and fallback |
57
+ | `browser-interview.js`, `browser-page.js` | Loopback human questionnaire, background browser opening, recovery, cancellation, and batch reuse |
58
+ | `change-view.js` | Read-only questionnaire display of the frozen checkpoint comparison: file list, per-file stats, diffs, and verified question evidence ranges |
59
+ | `git-interview.js` | Explicit separate-terminal transport retained for compatibility |
60
+ | `native-check.js` | Direct human-form assessment loop, queue claims, cancellation, and summary-only results |
61
+ | `mcp.js` | Bounded stdio JSON-RPC transport, form elicitation, and lifecycle tool responses |
62
+ | `install.js` | Reversible hook chaining, agent configuration, coverage checks |
63
+ | `agent.js` | SessionStart guidance and Claude shell-session tagging for native questionnaires |
64
+ | `pi-integration.js` | Pi extension installation, native dialogs, and deterministic queued-check presentation |
65
+ | `lifecycle-integrations.js`, `cursor-hook.js` | Cursor/OpenCode installation, browser handoff for queued fallback checks, and status-only client results |
66
+ | `terminal-launch.js`, `terminal-worker.js` | Explicit terminal transport, shared browser/native/terminal reservations, and private worker status |
67
+ | `activation.js`, `activation-worker.js` | Fresh coding-client sessions after installation, prompt-free launch, and startup acknowledgment |
68
+ | `cli.js` | Onboarding, terminal interview, public JSON protocol, hook entry points |
69
+ | `terminal.js`, `help.js`, `prompts.js` | Terminal presentation, contextual command help, and guided selections |
70
+
71
+ ## Repository policy and terminal interaction
72
+
73
+ Machine-wide settings live in `$SPHINX_HOME/config.json`. A repository's canonical policy is JSON stored in `.sphinxconfig`. If that file is absent, the loader accepts legacy `.sphinx.json`. When both are present, canonical policy wins without merging the legacy file. Repository policy can control triggers, question depth, blocking mode, and exclusions; model routes, authentication, and usage budgets remain machine-wide. Repository exclusions add to machine-wide exclusions.
74
+
75
+ Reviewer presets write concrete per-tier routes into the global configuration. They are not dynamic model selectors: updating the preset catalog does not migrate saved models or trigger fallback. `sphinx config --preset <id>` and the `--small`, `--medium`, and `--large` flags edit those routes without reinstalling or invoking inference. Model-route changes remain part of assessment identity and invalidate reuse under the previous policy. The internal `openrouter/free` default remains for legacy configuration and checkpoint identity compatibility; new unattended installations require a preset or explicit route rather than accepting it silently.
76
+
77
+ `sphinx init` guides the user through event, branch, depth, mode, remote, and project-context choices. Branch defaults come from effective configuration rather than the currently checked-out branch. The initializer writes `.sphinxconfig`, `.sphinxignore`, and `.sphinxcontext.md` only when absent. It can copy a legacy policy into the canonical file while retaining the original. Rerunning setup preserves existing files and does not silently apply new flags over them.
78
+
79
+ Initialization does not install hooks, change global settings, resolve remote Git state, or invoke a model. Machine-wide integration is a separate, once-per-machine operation. A repository with a competing `core.hooksPath` needs the explicit `install --repo` compatibility step.
80
+
81
+ Human terminal output provides a compact ASCII mark, explanatory selections, and progress/context for assessments. Color and layout adapt to terminal capabilities. Every public command supports its own help through `sphinx <command> --help` and `sphinx help <command>`. `--json` output and hook protocols bypass decorative output; they remain suitable for coding agents, pipes, and tests. `NO_COLOR` disables color; redirected output is uncolored by default. Help and read-only status/configuration commands never invoke an evaluator. Reviewer dependencies are loaded only when an investigation starts, keeping ordinary Git gating and CLI inspection independent of reviewer initialization.
82
+
83
+ ## Human questionnaire transports
84
+
85
+ A blocking Git hook saves pending assessments and hook-owned presentation requests, then serves a local browser questionnaire while the original Git process waits. On macOS, `open -g` opens the page in the background without activating or minimizing applications. Elsewhere Sphinx prints the local URL instead of guessing window-manager focus behavior. It never automatically opens Terminal for a questionnaire. The batch reuses one page for all destinations. Hook-owned requests are invisible to native after-tool callbacks, which cannot run until the original shell tool finishes. Browser, native, and terminal transports share a per-checkpoint reservation to prevent duplicate questionnaires.
86
+
87
+ Human answers go straight from the browser to the independent evaluator. Neither questions nor responses enter client hook results, and Git protocol stdin remains untouched. After completion, the gate reloads policy and revalidates every original snapshot and receipt, including previously approved destinations, before returning zero to the same Git process. Existing hooks run once before snapshot collection; commands, refspecs, force flags, stdin, and remotes are never reconstructed or replayed. Git retains its own remote-update concurrency checks.
88
+
89
+ The HTTP listener binds only to `127.0.0.1` on an ephemeral port and requires a random URL token. Responses are not cached; CSP prevents third-party assets, frames, and form navigation. POST requests require the exact host, origin, token header, current checkpoint/revision, and current question ID. The page renders all source/model text with `textContent`. Questions and feedback are public assessment fields; answer keys, rubrics, and retained source observations are never served. Provider calls stay in the hook process with its normalized Git context, preserving temporary indexes and explicit Git directories without exposing credentials or Git context in launch arguments. SSE carries current state; reconnects do not replay submissions, and monotonic updates prevent a delayed POST response from overwriting a newer question or completion.
90
+
91
+ Pause aborts active evaluation and releases the waiting operation without approval. Closing a browser tab does not pause the check: the URL can reconnect until the 25-minute deadline. Cancellation, stale content, missing receipts, and the deadline cause nonzero Git exit and cleanup of the hook-owned presentation batch. The per-operation server closes after the gate finishes. CI and evaluator subprocesses do not open pages or begin browser inference. An unavailable browser transport stops Git and queues the native/manual fallback. Codex and Claude Code lifecycle hooks call the local `sphinx_checkpoint` MCP tool only for this fallback queue. Its only arguments are repository context and host/session identifiers: `cwd`, `host`, `hookEvent`, and `hostSession`. It accepts no questions or human answers from the development model.
92
+
93
+ The controller claims queued work and uses MCP `elicitation/create` to present a flat form. The user can answer, learn, dispute, or pause. Responses return directly to Sphinx and its independent evaluator. Questions, feedback, and responses are not included in the tool result; the development model receives only allowlisted status, assessment IDs, progress, usage counts, and static retry guidance. The client controls how forms appear and may retain its own interaction logs.
94
+
95
+ The stdio server negotiates protocol `2025-11-25` or legacy `2025-06-18`, supports both modern `elicitation.form` and legacy empty elicitation capabilities, and correlates each form to an active tool request. Unsupported clients leave queued checks untouched and consume no inference. No queued work returns an empty hook response, including on clients without form support. JSON messages and accepted field values are bounded and validated; malformed answers, cancellation, disconnection, or timeouts cannot mark a check complete.
96
+
97
+ Advertised form support does not guarantee the client will display a request: client approval policies may cancel it. Codex 0.162.1's `never` policy does so unless its host enables full-access form input for a user thread. Sphinx preserves the pending assessment and does not alter the client's approval settings. Terminal checks remain available. Completion guidance retries only blocked Git operations.
98
+
99
+ A paused or dismissed presentation is consumed while its assessment remains pending. Unrelated shell commands therefore do not reopen it. A new Git attempt queues presentation again and resumes existing progress. Session identifiers let the integration find requests from commands that change directories or use `git -C`; Codex supplies its thread ID, and the Claude SessionStart hook appends a Sphinx session tag through `CLAUDE_ENV_FILE`. Outside native hosts, `sphinx check` provides the terminal interview using the same assessment state.
100
+
101
+ The browser questionnaire shows the change it is asking about. A sticky header names the repository, Git operation, destination, exact comparison, file and line totals, and progress, labeled as checkpoint changes rather than a whole pull request. Beside the question, a file list (all changed files or only those relevant to the question) and a unified diff are rendered from the checkpoint's recorded blob IDs: the push base and head, or the pinned index entries of a commit checkpoint. Later commits and working-tree edits cannot change them. Renames are detected for display only; the reviewer still uses `--no-renames`. Binary, symlink, submodule, mode-only, empty, non-UTF-8, and oversized files show an explicit state and never receive invented line counts. Long diffs are truncated with a visible count, and excluded files appear only as a count. Question evidence lists the paths the question cites. Line ranges appear only when a retained reviewer observation (read_file, read_diff page, or search match) matches the checkpoint's blob IDs and, for diff pages, its exact bytes at the recorded offset. Model-written evidence reasons are not shown because they can reveal the answer. Display updates never rotate the actionable revision, and browsing never touches the draft answer or the current question.
102
+
103
+ Pi's development-client integration is a separate local extension from the embedded reviewer runtime. It observes built-in `bash` and `powershell` results, then calls the same questionnaire controller for queued Git requests. `ctx.ui.select` presents Answer, Learn, Dispute, and Pause; `ctx.ui.input` collects the person's response. Only a fixed status message is appended to the shell result. Questions, feedback, and human answers never enter the coding transcript. Interactive or dialog-capable RPC mode is required; noninteractive modes preserve pending work for a terminal check. Pi's built-in shell session ID associates requests across `cd` and `git -C`.
104
+
105
+ Cursor and OpenCode adapters inspect queued fallback presentation metadata after shell tools and use the same local browser questionnaire. The client hook waits for a status-only result. This fallback cannot resume Git after it has exited; guidance permits a new invocation only after checking that the original operation failed at Sphinx, and forbids repeating waiting or successful operations. Questions, feedback, answer keys, human responses, and browser URLs never pass through the adapter's returned tool result. Cursor receives a context note; OpenCode receives a shell-result note and a TUI toast when available. Session environment tags support cross-directory routing. Cursor user hooks apply only to local sessions.
106
+
107
+ Private reservation records track the exact assessment, presentation token, and owning process. Active interviews are reused, and dead owners can be recovered. A paused presentation is consumed so unrelated tool events cannot reopen it; a new Git attempt can resume the assessment. Both direct Git and fallback browser interviews have bounded waits. Host shell or remote-connection timeouts may stop Git earlier; a late receipt never revives or replays an exited operation. `sphinx check --id <id>` remains an explicit terminal alternative using the same assessment and receipts. No browser or native transport grants completion by itself.
108
+
109
+ ## Independent investigation and compaction
110
+
111
+ Version 2 snapshots contain change metadata and pinned Git identities, not a bundled patch. Before the first model request, Sphinx reads up to eight initial diff pages through the filtered immutable workspace, then a bounded file inventory when room remains, all within one quarter of `maxContextBytes`. These local reads consume no model calls. They enter the same exact evidence archive as subsequent tool observations, alongside statistics and `.sphinxcontext.md`. Listed names confer no citation privileges. Header-only or unavailable observations cannot satisfy the changed-code evidence requirement; if no usable evidence can be loaded within these limits, review stops before inference. The agent chooses `read_diff`, `read_file`, `list_files`, and `search` calls for missing ranges and dependencies. Tools filter paths before reading immutable blobs, reject unsafe paths and symlinks, and return bounded pages with explicit continuation information. Unchanged callers, tests, and dependencies are accessible at the pinned revision. Staged checkpoints retain index object identities.
112
+
113
+ The [Pi SDK](https://pi.dev/docs/latest/sdk) owns the reviewer session, agent/tool loop, and native compaction. Its entries and exact evidence archive are checkpointed privately so interruption does not discard the investigation. Sphinx registers only its filtered immutable workspace tools, supplies explicit project context, and disables ambient resource discovery and general-purpose tools. The session never loads the development transcript, project agent instructions, or unrelated Pi resources. `SPHINX_EVALUATOR=1` prevents recursive Sphinx hooks.
114
+
115
+ OpenRouter supplies model responses with native function calls. For explicitly selected `anthropic/` models, Sphinx sends `tool_choice: "auto"` on investigation and finalization requests to preserve compatibility with thinking-capable providers. Sphinx still rejects responses without actual tool calls and requires exactly one `finish_review` call during finalization; automatic selection never relaxes those local checks or triggers a transport retry. Other model families retain required or explicitly selected tool choices. See [Anthropic thinking and tool-choice compatibility](https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-with-tool-use). The Codex/Claude compatibility routes use fresh isolated CLI invocations as model transports underneath Pi. Structured model responses become Pi tool requests; Pi schedules the registered Sphinx tools and carries the conversation into the next request. These routes reuse CLI authentication without copying secrets into prompts. They do not run a persistent Codex or Claude reviewer session, or delegate isolation to those clients' native tools.
116
+
117
+ Every request includes bounded project context (maximum 16,000 bytes). Context is descriptive data, not evaluator policy, and its claims must be checked against code. The current project file is hashed into checkpoint identity; an excluded context file is not opened.
118
+
119
+ Before Pi validates a `finish_review` call, Sphinx normalizes two lossless representation differences: a valid JSON-object string in `assessment` becomes an object, and `summary` or `evidenceIds` nested inside it moves to the envelope only when that outer field is absent. Questions, keys and citations are never rewritten by this step. Duplicate metadata, unknown properties and malformed JSON remain subject to strict rejection. The original native provider message and opaque continuation are retained separately from Pi's normalized arguments. Recorded response replays cover both native tool calls and structured CLI transports without spending another inference request.
120
+
121
+ The reviewer requests further diff pages, source ranges, file listings, and literal searches through Sphinx's tools. It can inspect unchanged callers, dependencies, and tests at the same pinned revision. File names are navigation hints; only inspected source can support a question. Sphinx enforces ignores and tool access locally and never grants an unrestricted shell or the developer's working files. Large patches are inspected incrementally rather than bundled into one prompt.
122
+
123
+ Pi session entries, the evidence archive, and an assessment awaiting its independent audit are saved privately under the checkpoint lock, so an interrupted review resumes without repeating the investigation. After compaction, the reviewer can recover archived observations with `read_evidence`.
124
+
125
+ Pi's [native compaction](https://pi.dev/docs/latest/compaction) summarizes older conversation history and rebuilds the active context. Sphinx separately archives exact observations with IDs, paths, revisions, and ranges under a fixed byte budget. Compaction can shorten Pi's transcript without changing this archive; a model summary cannot replace code evidence. Final questions must cite inspected paths backed by archived observations. Grading receives the question's selected original evidence, rubric, project context, and verbatim human answer.
126
+
127
+ New assessments separate their minimal acceptance criteria—one prediction and its causal reason—from the longer answer key and explanation. The independent audit checks both against source and aligns the visible question with the minimum criteria. A question that bundles extra checks must be narrowed, not given hidden requirements. Grading still rejects an unsupported key, but explanatory implementation details do not become additional requirements for the human. Older saved questions remain readable and are assessed against their visible behavioral question. All acceptance criteria and explanatory keys stay private.
128
+
129
+ Sphinx enforces `maxContextBytes` on serialized review context: prompts, tools, and schemas. Provider transport metadata is outside this count; it is not a byte limit on the complete HTTP body or the whole Git patch. Pi's estimated context threshold leaves reserve space for compaction, while tool pages and the evidence archive have separate bounds. Byte-based token estimates drive Pi's context management, particularly for CLI transports without reliable token reporting; these estimates are not billed usage totals. If the next review context cannot fit, the assessment remains incomplete. Every actual model request, including native compaction, is counted before invocation and checked against any explicitly configured checkpoint cap. Provider retries and cache warming are disabled; an error never triggers a paid-provider fallback. Correctable protocol and question-validation errors return feedback to Pi within the existing allowance. Exact citation evidence is resolved deterministically from observed paths; observation IDs are optional narrowing hints. A separate audit checks all proposed questions against retained evidence before display. Pending audits survive interruptions and resume without another investigation. Audited reviews use five/seven/eight requests as soft planning targets for small/medium/large changes. `agentMaxTurns` and `maxModelCalls` both default to `null`, so those targets never impose a hidden request cap. Explicit numeric `agentMaxTurns` values cap a review attempt; explicit total caps also reserve calls for grading. Correctable finalization and audit errors may continue within those explicit caps, context limits, and the investigation deadline. Provider failures still stop and require a human retry decision. Private audit feedback survives resume without appearing in public errors.
130
+
131
+ These adapters depend on recent CLI features. Unsupported flags or managed settings that conflict with isolation may cause a failure; Sphinx does not retry in a less isolated mode. Provider adapters need continued compatibility testing.
132
+
133
+ ## Background preparation
134
+
135
+ Post-commit, post-merge, post-rewrite, and post-checkout dispatchers preserve original hook behavior, then schedule a detached worker without waiting for inference. A 1.5-second default debounce and job identities coalesce repeated work. Local push/upstream tracking metadata predicts the destination and remote base; missing tracking history is a cold-review case, not a reason to fetch or speculate automatically.
136
+
137
+ Workers call the same session preparation path as foreground checks. Exact source/destination/policy/ignore/context matches reuse questions and evidence. A foreground check waits for an in-progress review instead of duplicating requests. Superseded workers and changed snapshots cannot install valid prepared work. Preparation never opens a questionnaire or creates completion. Failures have safe status messages and require explicit retry. `backgroundPreparation: false` disables scheduling; repositories can opt out but cannot override a machine-wide opt-out.
138
+
139
+ ## State and cost
140
+
141
+ The existing line, file-count, and consequential-path rules deterministically select a small, medium, or large tier before inference. A consequential path promotes even a tiny patch to large; file count alone does not establish simplicity. That tier selects the configured evaluator route and, together with question depth, the maximum initial question count:
142
+
143
+ | Tier | Relaxed | Standard | Thorough |
144
+ | --- | --- | --- | --- |
145
+ | Small | 1 | 1 | 1 |
146
+ | Medium | 2 | 2 | 3 |
147
+ | Large | 2 | 3 | 5 |
148
+
149
+ The evaluator must return at least one question and may use fewer than the ceiling when fewer distinct behaviors are supported. It must not invent extra concerns to fill the budget. Model routes remain independent of depth. `maxOutputTokens` is preserved across all tiers; OpenRouter enforces it, while CLI evaluators receive concise-output instructions and local process limits.
150
+
151
+ The economy CLI presets select `codex:gpt-6-luna` or `claude:haiku` for all tiers, preserving the cheaper model while effort and review planning targets scale. The paid OpenRouter value preset selects `anthropic/claude-haiku-5.5` for every tier and sets an 8,192-token output ceiling; an explicit output flag takes precedence. Applying the preset preserves the total call limit. The experimental open-weight alternative selects `deepseek/deepseek-v3.2`. Existing routes are never migrated implicitly. See [the evaluation record](../eval/RESULTS.md) for measured results and failures; these starting configurations are not guarantees of assessment quality. OpenRouter routes consume API credits separately from coding-agent plans; Codex and Claude routes consume the selected CLI account's allowance. Pi, Cursor, and OpenCode client integrations do not supply a model transport or reuse those clients' credentials.
152
+
153
+ OpenRouter request parameters require compatible provider endpoints; model-level capability lists can combine capabilities from different endpoints. The [Haiku endpoint API](https://openrouter.ai/api/v1/models/anthropic/claude-haiku-5.5/endpoints), checked October 15, 2026, lists native tools, structured output and automatic tool selection, but not required/named selection. Reference per-million input/output rates start at $0.10/$0.50 below 100,000 input tokens and $0.50/$2.50 at the higher context tier. These are reference rates, not price ceilings or a reliability evaluation. OpenRouter's default Auto Exacto routing considers tool-call quality; explicitly sorting by price disables that routing step. Sphinx still validates every response and does not turn missing tool calls or invalid output into completion.
154
+
155
+ Snapshot IDs include repository identity, exact objects/index, destination, effective policy, ignore-policy hash, and project-context hash. Ignored files affect immutable object identity but their contents never enter evidence. Before model calls, tool use, and completion, Sphinx revalidates local source/index and policies. The eventual Git hook compares a fresh destination snapshot to the completion record, so a changed remote base also invalidates reuse.
156
+
157
+ The policy identity also includes an assessment-contract version. The introduction of minimal acceptance criteria invalidates prepared assessments and receipts from the previous contract; Sphinx does not silently upgrade them or treat them as passing the new assessment. Changing only the call allowance still preserves a checkpoint's identity and usage within the current contract.
158
+
159
+ `pending → active → passed` is the main state sequence. Wrong answers teach the missed concept and replace its question with a new transfer scenario without advancing progress or adding another concept. Each proposed replacement receives a separate source audit before the grade reaches the session store. That audit sees exact retained evidence and the candidate, without the human answer or grading conversation. It can correct unsupported conditions or reject the replacement; rejection preserves the original pending question and incurred usage. A grade without a replacement costs one request; a proposed replacement costs two, subject to any explicit cap. Retries can exceed the initial question count. Without a configured cap, all calls remain counted but the total alone does not stop the check. Ambiguity remains active. Calls are counted before invocation, including failed attempts; explicit limits are enforced before invoking a provider. Per-session file locks prevent simultaneous grading and duplicate generation; expected question IDs reject stale responses. Cancellation during answer persistence rolls back progress while retaining incurred usage. Receipt readers acquire the same lock so they cannot observe a receipt being rolled back. Private state files use mode `0600`; public JSON and questionnaires deliberately omit private concept labels, rubrics, and full source evidence. Concept labels remain in private assessment state for grading and transfer-question matching because a generated label can reveal the answer.
160
+
161
+ The source audit can rewrite a provisional replacement that repeats the original question; strict novelty checks run on its final output. For an ambiguous answer, a source audit that cannot support a replacement preserves the feedback with no replacement, leaving the original question pending for clarification. An incorrect answer still requires a valid audited transfer. Provider, cancellation, format and context errors are not swallowed by this optional-replacement path. Neither path can turn ambiguity into approval.
162
+
163
+ Successful records expire after 24 hours by default. Background investigation is enabled by default and shares the assessment's counted usage and any explicit total cap. Sphinx always bounds serialized review-context bytes, tool-page bytes, and whole-investigation time. With an explicit request cap, it reserves grading calls plus the final synthesis and independent audit. A lone remaining request cannot start a new synthesis that would lack its required audit. Near that explicit cap, native `tool_choice` requests `finish_review` while retaining earlier tool definitions for history compatibility, except for the Anthropic automatic-selection compatibility path above. The transport and reviewer reject any other returned call; the CLI response schema also allows only finalization, and Pi cannot compact away reserved requests. Missing evidence still fails the review. Only a saved pending audit can resume with one available review call; an unfinished investigation needs at least two, plus reserved grading calls when a total cap is set.
164
+
165
+ `maxModelCalls` is an optional operational ceiling, separate from assessment identity. Its canonical policy-hash value stays at the historical default of 10, and `agentMaxTurns` is normalized to its historical default of 8, preserving those existing checkpoint IDs when request caps change. Older checkpoints originally hashed with other custom limits require a fresh checkpoint. All other policy fields remain bound. Both defaults are `null`, meaning no request limit; numeric saved values remain explicit limits. The session store reloads global request limits under its lock before resume, grading, and every actual model request. A changed total cap replaces the absolute limit and records the change without resetting calls, questions, attempts, review evidence, or completion. Lowering below used calls blocks inference; clearing the cap preserves usage. Prior explicit retry extensions remain until the configured total cap changes. `sphinx config --max-model-calls <1-100|unlimited>` saves or clears the global total cap without reinstalling or invoking a model; `none` is an alias for `unlimited`. Public JSON represents an uncapped `usage.limit` as `null`, and human displays say “no limit.”
166
+
167
+ When a numeric total cap is configured, for a one-attempt extension without changing that global cap, `check --id <id> --retry-review` and the equivalent human choice in the interactive recovery menu remain available for failed, questionless checkpoints. Under its session lock, it validates the unchanged policy/snapshot, records prior attempt usage, and allows at most `maxModelCalls` additional requests. Total calls remain cumulative, and the public usage limit reflects the extension. Provider errors expose only numeric status and allowlisted error categories, never raw response messages or metadata. With no cap, or when enough calls remain for review plus grading, the interactive menu offers a retry within that allowance; otherwise it offers a new allowance under the explicit cap. Without a cap, a retry reuses saved work and never asks for an allowance extension. Pause is always the default, and every further failure requires a fresh choice. Known setup/auth/context failures and zero-request preflight failures do not offer another spending attempt; stale content or policy stops recovery. The browser page or explicit terminal stays open while the human decides, allowing the original Git hook to remain waiting within its deadline. JSON commands keep their noninteractive failure behavior. Ordinary resuming and background work adopt an explicitly edited global ceiling but never authorize an additional per-attempt allowance; active or passed questionnaires cannot be restarted. Provider escalation remains explicit. A local completion record is a workflow convenience, not a cryptographic attestation.
168
+
169
+ ## Installation
170
+
171
+ A global Git `core.hooksPath` points to Sphinx dispatchers. Existing hooks are chained with their arguments and input preserved. Unrelated hook protocols are forwarded directly so interactive/streaming hooks are not buffered. Repository-level overrides need `sphinx install --repo` to wrap the repository's effective hook directory.
172
+
173
+ The installation manifest tracks original settings and the exact files/handlers Sphinx created. Uninstall restores only configuration it still owns; subsequent edits are preserved. `--agents auto` detects Codex, Claude, Pi, Cursor, and OpenCode from executables, configuration directories, or an existing installation record. An explicit comma-separated subset selects integrations; `none` selects Git-only setup.
174
+
175
+ Interactive setup begins with coding-agent checkboxes, with All supported agents first, then offers economy reviewer presets based on the selected clients. Users can choose paid OpenRouter, free OpenRouter as an explicit best-effort option, or custom per-tier routes. Existing configurations retain their saved routes unless the user selects a replacement. A deliberate paid selection in guided setup supplies consent; unattended `install --preset` and `config --preset` require `--allow-paid` or an existing paid-enabled setting. Fresh unattended installation without a preset or explicit reviewer route stops before installing. Credential setup remains separate, uses hidden input for OpenRouter keys, and makes no model request.
176
+
177
+ Codex and Claude integrations register a local stdio MCP server and inject guidance at session start. Codex uses a native `PostToolUse` MCP tool hook for `Bash`; Claude uses `PostToolUse` and `PostToolUseFailure` for `Bash`. Pi installs `extensions/sphinx.js` under `PI_CODING_AGENT_DIR` or `~/.pi/agent`; a new session or `/reload` loads it. Cursor adds `sessionStart`, `postToolUse`, and `postToolUseFailure` handlers to `~/.cursor/hooks.json`. OpenCode installs `plugins/sphinx.js` in its configuration directory, honoring `OPENCODE_CONFIG_DIR` or `XDG_CONFIG_HOME`, without rewriting `opencode.json` or JSONC settings.
178
+
179
+ After configuration succeeds, interactive `sphinx install` opens the selected installed clients by default. `--no-launch` defers activation; `install --yes` opens clients only with explicit `--launch`. `sphinx activate` opens already-configured integrations without reinstalling, and `--agents codex,claude,pi,cursor,opencode` can select a configured subset. `--json` returns launch outcomes without decorative output. Repository-only `install --repo` remains a hook-compatibility operation.
180
+
181
+ Activation starts fresh Codex, Claude Code, Pi, and OpenCode CLI sessions, or a new Cursor editor window. It supplies no initial model prompt, invokes no Sphinx evaluator, and does not restart existing processes. Missing executables or headless environments produce a focused manual-launch fallback. A successful launch means the client opened, not that its MCP connection, form support, or hook trust has been verified. Native client trust decisions remain with the human; Codex's hook browser must be opened with `/hooks`. Sphinx does not pass a slash command as an initial model prompt or use an undocumented approval deep link.
182
+
183
+ The Git hook remains the canonical local checkpoint. Client integrations consume already queued work; they do not let a model decide whether a check is required. Evaluator sessions tagged `SPHINX_EVALUATOR=1` skip queueing and client presentation. Tests redirect integration homes and never install into a developer's real configuration.
184
+
185
+ ## References
186
+
187
+ - [Pi SDK](https://pi.dev/docs/latest/sdk)
188
+ - [Pi compaction](https://pi.dev/docs/latest/compaction)
189
+ - [Pi SDK full-control example](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/examples/sdk/12-full-control.ts)
190
+ - [Pi extensions](https://pi.dev/docs/latest/extensions)
191
+ - [Cursor hooks](https://cursor.com/docs/hooks)
192
+ - [Cursor MCP support](https://cursor.com/docs/mcp)
193
+ - [OpenCode plugins](https://opencode.ai/docs/plugins/)
194
+ - [Git hook protocols](https://git-scm.com/docs/githooks)
195
+ - [Git central hooks path](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath)
196
+ - [Codex hooks and trust](https://learn.chatgpt.com/docs/hooks)
197
+ - [Codex CLI reference](https://learn.chatgpt.com/docs/cli/reference)
198
+ - [Claude Code hooks](https://code.claude.com/docs/en/hooks)
199
+ - [Claude Code CLI reference](https://code.claude.com/docs/en/cli-reference)
200
+ - [MCP form elicitation](https://modelcontextprotocol.io/specification/2025-11-25/client/elicitation)
201
+ - [MCP initialization and protocol negotiation](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle)
202
+ - [MCP stdio transport](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)
203
+ - [OpenRouter structured outputs](https://openrouter.ai/docs/guides/features/structured-outputs)
204
+ - [OpenRouter tool calling](https://openrouter.ai/docs/guides/features/tool-calling)
205
+ - [OpenRouter provider price limits](https://openrouter.ai/docs/guides/routing/provider-selection)
206
+ - [OpenRouter Auto Exacto routing](https://openrouter.ai/docs/guides/routing/auto-exacto)
207
+ - [Qwen3 Coder Next endpoints](https://openrouter.ai/api/v1/models/qwen/qwen3-coder-next/endpoints)
208
+ - [Qwen3 Coder endpoints](https://openrouter.ai/api/v1/models/qwen/qwen3-coder/endpoints)
209
+ - [DeepSeek V3.2 endpoints](https://openrouter.ai/api/v1/models/deepseek/deepseek-v3.2/endpoints)
210
+ - [Qwen3 Coder Next model card](https://huggingface.co/Qwen/Qwen3-Coder-Next)
211
+ - [Codex model configuration](https://learn.chatgpt.com/docs/models)
212
+ - [Claude model configuration](https://code.claude.com/docs/en/model-config)