M2-REPORT.md
Rama main · réplica de lectura del repositorio original.
# M2 report — cloud witness mode for `crux-llm-shim`
Date: 2026-07-13
ExecPlan: `tier-packaging-and-site-reframe-2026-07-13`, M2
## What was built
- Added a cloud-witness operating mode selected with `--cloud-witness
--cloud-upstream anthropic|openai` and independently gated by
`CRUX_CLOUD_WITNESS=1`. Local injection remains independently gated by
`CRUX_LLM_SHIM=1`; the same binary can run separate instances on distinct
loopback ports.
- Added the closed `CloudUpstream` enum. Production origins are exactly
`https://api.anthropic.com` and `https://api.openai.com`; redirects are
disabled, request targets must be origin-form paths, and the listener
remains loopback-only. The existing local HTTP/RFC1918 allowlist is
unchanged.
- Added exact request-body forwarding with end-to-end/auth header forwarding,
RFC hop-by-hop filtering (including names nominated by `Connection`), TLS
through `ureq`/rustls, response streaming, incremental SHA-256 output
hashing, and bounded metadata-only response parsing. Workspace `ureq` keeps
rustls but disables transparent gzip decoding, so explicitly requested
compressed response bytes remain verbatim.
- Witnessed Anthropic `POST /v1/messages` and OpenAI
`POST /v1/chat/completions` / `POST /v1/responses`. Other paths produce a
signed `passthrough_unwitnessed` path/timestamp record.
- Added request metadata extraction for model, stream flag, names-only tools,
and optional `x-crux-session-id`; added Anthropic/OpenAI JSON and SSE usage
plus stop/finish metadata extraction. Request/response content and auth
values never enter records, logs, or the JSONL spool.
- Added a dedicated Ed25519 witness key at
`~/.local/state/crux/llm-shim/witness.key` by default. First creation is
race-safe and `0600` on Unix; later starts reuse the same public identity.
Symlink/non-regular keys, keys that are group/world-accessible when loaded,
and writable parent custody are rejected into fail-soft degradation.
The `wit_…` key id is the first 16 lowercase hex characters of SHA-256 over
RFC 8410 Ed25519 SPKI DER.
- Added recursively sorted canonical-JSON signing and identity-pinned strict
verification. The verifier rejects record alteration, key-id mismatch, and
attacker re-signing with a different key. **It does NOT reject replay**: there
is no nonce/sequence/timestamp-freshness check, so a valid envelope can be
re-submitted. Nor does the same-UID key custody stop a same-user compromise
from forging (the `0600` key is readable by the invoking user). Both limits
are stated in the assurance/coverage matrix; closing them (hardware key store
or off-host witness; a replay guard) is follow-up work, not claimed here.
- Extended the existing daemon-first `/v1/mediation/receipts` plus JSONL spool
fallback. Cloud delivery uses a bounded, non-blocking ordered queue so
daemon/filesystem stalls cannot create unbounded memory growth or delay
provider calls; queue overflow is retained as one deferred degraded notice.
Cross-process file locking preserves JSONL framing for concurrent local,
Anthropic, and OpenAI instances. Key/signing/delivery failures attempt a
content-free `witness_degraded` record and never stop forwarding.
- Witness receipt IDs include a random 128-bit process-instance component plus
a monotonic counter, avoiding PID-reuse collisions across restarts.
- Added the loud `--insecure-test-upstream` path. It only honors
`CRUX_CLOUD_WITNESS_TEST_UPSTREAM` when explicitly enabled (or in unit-test
compilation), accepts loopback HTTP only, prints a warning in the CLI, and
stamps every resulting record `test_upstream:true`.
- Documented what the witness proves, its limits, detectable absence on
reconciled bypass, and Anthropic/OpenAI base-URL quickstarts.
## Files touched
- `Cargo.lock`
- `Cargo.toml`
- `crates/crux-claude-hooks/Cargo.toml`
- `crates/crux-claude-hooks/src/bin/crux_llm_shim.rs`
- `crates/crux-claude-hooks/src/llm_shim/allowlist.rs`
- `crates/crux-claude-hooks/src/llm_shim/cloud_witness.rs` (new)
- `crates/crux-claude-hooks/src/llm_shim/http.rs`
- `crates/crux-claude-hooks/src/llm_shim/mod.rs`
- `crates/crux-claude-hooks/src/llm_shim/receipts.rs`
- `crates/crux-claude-hooks/src/llm_shim/witness.rs` (new)
- `crates/crux-claude-hooks/tests/cloud_witness_e2e.rs` (new)
- `docs/llm-shim.md`
- `llms-full.txt` (regenerated to restore the repository freshness gate after
pre-existing linked-doc edits)
- `M2-REPORT.md` (new)
`README.md` and `docs/assurance-coverage-matrix.md` were not edited.
## Receipt shapes
All normally witnessed records use this signed envelope:
```json
{
"record": { "schema": "cuecrux.mediation.witness.v1", "kind": "..." },
"witness": {
"alg": "ed25519",
"kid": "wit_<16 lowercase hex chars>",
"public_key_b64": "<raw 32-byte Ed25519 public key, standard Base64>",
"sig_b64": "<Ed25519 signature over sorted-key canonical JSON(record)>"
}
}
```
`cloud_request_witnessed` carries `receipt_id`, provider, path, parsed model,
the `sha256:` digest of exact request body bytes, names-only `tool_names`,
`stream`, optional `session_hint`, `created_at`, and the test marker.
`cloud_response_witnessed` has its own `receipt_id` plus
`request_receipt_id`, provider/path, upstream status, the `sha256:` digest of
exact response bytes delivered, filtered numeric usage-token fields,
stop/finish reason, first-byte/end timestamps, `completed|aborted|upstream_error`,
and the test marker.
`passthrough_unwitnessed` contains schema/kind plus path, timestamp, and the
test marker. `witness_degraded` contains only operational metadata and no
request, response, or auth content. When the persistent key itself is
unavailable, the degraded record is necessarily unsigned and says
`persistent_key:false` rather than claiming the configured witness identity.
### Signed example captured from the forgery test run
Command:
```text
cargo test -p crux-claude-hooks --lib llm_shim::witness::tests::valid_envelope_verifies_and_forgery_paths_fail -- --nocapture
```
Output example (the same test verified this envelope before testing altered
record and different-key forgeries):
```json
{
"record": {
"kind": "cloud_request_witnessed",
"request_digest": "sha256:001122",
"schema": "cuecrux.mediation.witness.v1"
},
"witness": {
"alg": "ed25519",
"kid": "wit_7db89400a2058592",
"public_key_b64": "IyobU7IDlPFFiJfmWZt800liOhrFlj0T7ouF1JujPiQ=",
"sig_b64": "5N935umxJWlRxcoTg7dq1PRPKmAiOwonIhjGjqYdxojTadeEZIR/3lnNHknDvYNZK5tF8O122IfA6LDk9VHyBA=="
}
}
```
## Test and quality summary
- `cargo fmt --all -- --check` — **PASS**.
- `cargo clippy -p crux-claude-hooks --all-targets -- -D warnings` — **PASS**.
- `cargo clippy --workspace --all-targets -- -D warnings` — **BLOCKED outside
this change** in existing `corecrux-frame/src/v3.rs` tests: seven
`clippy::unwrap_used` findings. The new crate target is clean.
- `cargo test -p crux-claude-hooks --lib llm_shim` — **PASS: 37 passed, 0
failed** (allowlist, path matrix, parsers, hop headers, gates, canonical
signing, forgery rejection, hardened key custody/reuse/unusable paths,
authority-smuggling rejection, response end states, concurrent JSONL
framing, and receipt delivery).
- Bind-free cloud CLI e2e — **PASS: 1 passed, 0 failed**.
- `cargo test -p crux-claude-hooks --no-fail-fast` — compiled every target;
the sandbox then rejected all loopback `TcpListener` binds with
`PermissionDenied`. Cloud target result after the final additions: **1
bind-free help test plus 6 network tests requiring the outside-sandbox
rerun**. The pre-existing hook/local-shim network targets and one existing
lib test hit the same bind denial. No functional assertion ran and failed
after a successful bind.
- `cargo doc --no-deps -p crux-claude-hooks` — **PASS**.
- `bash scripts/build-llms-full.sh --check` — **PASS** after regeneration.
- `bash scripts/check-agent-docs.sh` — **PASS**.
- CCL header check on every new Rust file — **PASS**.
## Deferred items and why
- The six cloud network e2e cases (Anthropic buffered, Anthropic gated SSE,
OpenAI chat, OpenAI Responses API, gzip fidelity, and key-unavailable
fail-soft) require the orchestrator's
outside-sandbox rerun because this sandbox forbids loopback binds. They
compile and their bind-free companion passes.
- The workspace-wide clippy gate needs the pre-existing
`corecrux-frame/src/v3.rs` test unwrap warnings resolved by that crate's
owner; editing unrelated trust-core tests was deliberately kept out of this
M2 change.
- Daemon-side promotion of the new JSON drafts into other canonical CROWN
receipt families was not added; this milestone owns the self-signed witness
envelope and reuses the existing mediation delivery endpoint/spool.