trimwire cockpit — plan + working POC + live preview (web + multi-platform, PWA-first) - #100
Open
AZagatti wants to merge 8 commits into
Open
trimwire cockpit — plan + working POC + live preview (web + multi-platform, PWA-first)#100AZagatti wants to merge 8 commits into
AZagatti wants to merge 8 commits into
Conversation
Add docs/cockpit/ — an overnight multi-agent research+design dossier for a proposed control UI for trimwire: a browser web UI plus a multi-platform app that both control an installed trimwire daemon. Contents (internal; not synced to the public site): - README: ask, decisions, executive summary, reconciliation, invariants - 01 research grounding: current control/data/web surfaces + gaps - 02 framework decision: unanimous Tauri 2 council (+ Svelte note for the UI) - 03 control API: separate loopback admin listener, REST + SSE, auth, hot-reload - 04 web cockpit UI: "Flightdeck" IA, 10 screens, vanilla-vs-Svelte decision - 05 multi-platform app: Tauri shell, build/sign/CI, mobile, shared frontend - 06 remote control: deferred BYO-overlay design + v1 don't-preclude seams - 07 security/ToS red lines: disagree-seeking review + risk register (R1-R9) - 08 roadmap: v0 read-only -> v1 local control -> v2 app -> v3 remote -> v4 mobile Hard invariants throughout: OAuth token never leaves the host, content-free panes only, lightweight single-binary ethos, ToS-compliant (no evasion), local-by-default with every remote step opt-in and gated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
trimwire | 260f28d | Commit Preview URL Branch Preview URL |
Jun 28 2026, 09:07 PM |
A small end-to-end vertical slice of the cockpit plan (docs/cockpit/),
off by default and adding no new dependencies.
Control API (src/admin/):
- Separate LOOPBACK admin listener (default 127.0.0.1:8766), kept off the
gateway port that transits the Anthropic OAuth token. Non-loopback bind is
refused at startup (remote control is a deferred, opt-in phase).
- Authenticator seam + LoopbackToken: 256-bit bearer token at
~/.trimwire/control.token (0600), constant-time compare.
- Host allowlist + same-origin Origin check (DNS-rebind / drive-by-browser guard).
- GET /api/v1/{health,version,service,stats} (stats reuses the content-free
ledger Report verbatim) and a content-free SSE GET /api/v1/events.
- Embedded single-file web cockpit ("Flightdeck") served at GET /, with a
same-origin token bootstrap, teal design tokens, KPIs and a live SSE log.
Wiring:
- New opt-in [admin] config section (enabled=false default, loopback listen).
- serve.rs spawns the admin listener alongside the gateway when enabled; new
`trimwire cockpit` subcommand forces it on and prints the URL.
App layer:
- app/ — Tauri 2 desktop shell scaffold (shape A: thin webview onto the loopback
cockpit). Independent crate, NOT a root workspace member, not built by CI.
Invariants honored: OAuth token never read/returned by the control plane;
upstream never writable here; responses content-free; admin logic lives outside
gateway.rs. Updates ARCHITECTURE.md with the admin/* layer row.
Verified: cargo fmt --check, clippy --all-targets -D warnings, and
cargo test --all-features all green (6 new admin unit tests); manual smoke test
of every endpoint + auth/Host/Origin guards; headless screenshot in
docs/cockpit/09-poc.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
Security code-review + fresh-2026-sources pass found real gaps; fixes: - F1 (content-free red line): strip `db_path` from the control-API /stats response so it never ships an absolute filesystem path over the network (the CLI `stats --json` keeps it). - F2 (global-only red line): `[admin]` is now clawed back to the trusted (defaults+global+env) layer, so a checked-out project ./.trimwire.toml can no longer switch on or relocate the control port. Adds a regression test. - G1 (CSRF/DNS-rebind defense-in-depth): add a `Sec-Fetch-Site` gate, ordered before the token compare and any side effect; validate the request authority (h2 `:authority` ∪ Host), default-deny. - F5: write control.token atomically as 0600 (no world-readable TOCTOU window); surface a chmod failure instead of swallowing it. - F8/G3: add `Content-Security-Policy` + `X-Frame-Options: DENY` to every response, incl. the token-bearing HTML. Docs: new docs/cockpit/10-security-fresh-sources.md (2026-sourced addendum — Host-pin needs more gates, Chrome 142 LNA does not cover localhost→localhost, token-in-HTML XSS tradeoff, base-proxy ToS gray zone) with cross-refs from docs 02/03/07. Production follow-ups (custom preflight header on writes, CSP nonces, HttpOnly-cookie handshake) are tracked there. Verified: fmt/clippy -D warnings/test all green (449 lib tests; new Sec-Fetch-Site + admin-global-only tests); manual smoke test confirms db_path absent, Sec-Fetch-Site cross-site rejected, CSP present, page renders + fetches under CSP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
- 09-poc: correct the unit-test count (6 -> 7) and name the Sec-Fetch-Site + [admin]-global-only tests. - 04-web-cockpit-ui: mark `trimwire cockpit --no-open` and `dashboard --serve` as PROPOSED (the POC ships only `trimwire cockpit`); avoid implying they exist. - README: soften the "vanilla DOM" claim to reflect doc 04's open vanilla-vs-Svelte decision (Svelte recommended once the site rebrands), so the summary doesn't contradict the detail doc. - 03-control-api: add the SSE `/events` endpoint to the auth exception note (EventSource cannot send Authorization; it stays Host/Origin/Sec-Fetch-guarded and content-free). - app/README: note the scaffold's `security.csp: null` must be locked (deny-by-default capabilities + real CSP) before shipping, per doc 10 G5. Docs/scaffold only; no Rust changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
…aid stores, CLI-stability) Three maintainer constraints folded into the plan + POC: 1. No Flutter/Dart — ruled out in docs 02/05 (it was only ever a runner-up flip-case and loses on merits anyway). The mobile fallback is the SAME web frontend (PWA/Capacitor), never a second-language UI. 2. No paid app stores for this app — doc 05 §4 + doc 08 v4 rewritten around no-store mobile distribution: PWA / add-to-home-screen ($0, iOS + Android) as the default, optional Android APK via GitHub Releases / F-Droid. No Apple Developer / Play fee required. 3. CLI changes must not break the cockpit — new doc 11 (API stability) states the guarantee: the cockpit speaks ONLY the versioned /api/v1 contract, never the CLI; the CLI and API are two consumers of one library; contract tests fail CI on shape drift. Adds two contract tests in src/admin/mod.rs (version_payload key-set pinned; stats missing-ledger shape + db_path-never- exposed) and cross-refs from docs 03/08 + the README constraints section. Verified: fmt/clippy -D warnings/test green (451 lib tests; 9 admin incl. the 2 new contract tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
Maintainer steer: focus on PWA (Android is converging toward iOS-style developer verification, Sept 2026, so a store-free APK path won't stay durable), and make code/component sharing explicit. POC — make the cockpit an actually installable PWA: - Serve GET /manifest.webmanifest (valid, display=standalone) + GET /icon.svg, linked from the HTML with theme-color + apple-touch-icon + standalone metas. - CSP gains manifest-src 'self'. New test asserts the manifest is valid + installable-shaped. Verified: manifest/icon served with correct Content-Types, page still renders under CSP. Docs: - 05 reframed to PWA-primary, Tauri = optional desktop wrapper; native mobile de-prioritized (Android verification cited). New "Code & component sharing" section: ~100% of the frontend is shared (components, tokens, API client, store); platform differences are a thin transport/secure-store adapter; one Vite build feeds browser+PWA+Tauri; desktop gets a bonus Rust-crate-sharing layer. Added offline/service-worker + secure-context(remote=TLS) findings. - 02 refinement note: the decision is "PWA + Tauri-for-desktop", not a native app per platform. - 08 roadmap: v1 installable PWA; v2 = optional Tauri desktop wrapper; v4 mobile = the PWA (no Apple/Play pipeline). - README exec summary + constraints updated; 09 POC table notes PWA install. Verified: fmt/clippy -D warnings/test green (452 lib tests; 10 admin incl. the new PWA-manifest test). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
Add docs/cockpit/demo/index.html — a self-contained, mock-data preview of the Flightdeck cockpit (Live / Savings / Strategies / Sessions / Config panes). No daemon, no backend, no build step: every figure is canned, content-free sample data, so the UI is viewable from a static link. Preview (githack, straight from this branch): https://raw.githack.com/AZagatti/trimwire/claude/trimwire-cockpit-ui-8s69wn/docs/cockpit/demo/index.html It can also be dropped into site/public/cockpit-demo/ to ride the site's Cloudflare deploy. Mirrors the real cockpit's content-free guarantee (only counts/bytes/tokens/model/strategy names — never prompts or content). Rendered headless to verify. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
…nciled Acted on the findings the council agreed on / that held up to scrutiny: - Strip `[server] upstream` from GET /api/v1/version (+ AdminState). It's the credential-routing field and a custom upstream URL can embed creds; the UI doesn't use it. Contract test now asserts `upstream` is ABSENT. (both Sonnets) - Token-page XSS hardening: serve the cockpit HTML with a per-render NONCE CSP (script/style 'nonce-…', worker-src 'none', no 'unsafe-inline') via a dedicated html_response(); the non-HTML surface keeps a strict no-script CSP. (all 4) - Token file: create with O_EXCL (create_new) + adopt the winner on AlreadyExists, closing the TOCTOU / concurrent-start race. (both Sonnets) - SSE: documented the per-reconnect ledger-read cost in code + doc 09. (3 of 4) - Deconflict clap display_order (Cockpit 30→24, was colliding with Summarizer). (Sonnet B) - Demo: version pill "v0.3.16"→"demo build"; fake "dedup"→"cross_turn_dedup". (both Sonnets) - Docs: remove duplicated "Frontend stack decision" paragraph (doc 08); fix stale test count (doc 09: 7→13) + smoke-test example; update doc 10 (nonce CSP now done, upstream stripped); strengthen the Tauri scaffold CSP (was null). - New tests: HTML placeholder/nonce guard, nonce-CSP-not-unsafe-inline, gen_nonce. Explicitly REJECTED after verification (don't-agree-blindly): - "ARCHITECTURE.md not updated" — the admin/* row already exists (line 289). - "doc 06 R7 citation wrong" — R7 IS the Host/Origin hook; the comment is correct. - "demo has no mock-data warning" — it has a prominent banner. - token-zeroize / "doc 02 unreadable" — over-engineering / agent artifact. - HttpOnly-cookie handshake, custom write-header, query-ticket SSE auth — real, but v1 production-spec items (no mutating/stream endpoints in the POC); tracked in docs. Verified: fmt/clippy -D warnings/test green (455 lib tests; 13 admin); manual smoke test confirms upstream absent, nonce CSP present + page still renders/fetches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd
AZagatti
added a commit
that referenced
this pull request
Jul 2, 2026
Smoke-testing the reviewer on real PRs (#142, #100) surfaced a production bug and two under-sized limits: - Diff truncation sliced patches mid-character with no marker, so models mistook a budget cut for broken code and raised false "truncated code / compilation failure" findings. Now cut at a line boundary with an explicit "NOT a code defect" marker, and REVIEWER.md tells models never to flag truncation/omission as a defect. - Budgets were far too small (measured: real PRs are 60-180 KB of reviewable diff, vs an 18 KB cap that gutted them). Raise MAX_TOTAL_CHARS 18K->256K and MAX_PATCH_CHARS 3500->24000. 256 KB (~64K tok) fits every repo PR fully and sits under every panel/aggregator model's context window; it's a ceiling, so normal PRs are unaffected (~$0.03) and only a rare max-size PR pays ~$0.12. - REQUEST_TIMEOUT 120->180s for headroom on large-diff reviews. Verified on real PRs: #142 went from 2 false "compilation failure" findings to 2 genuine ones; #100 (180 KB) now assembles the full diff and reviewers (GLM/Gemini) handle it within timeout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UkrzdLbHDXwAjQx8iaDXEr
AZagatti
added a commit
that referenced
this pull request
Jul 2, 2026
… aggregator Selected the panel for COMPLEMENTARITY on real PRs (validated on two: a security-heavy POC and a Rust self-updater), not synthetic scores — synthetic rankings did not transfer (e.g. Gemini topped the planted-bug corpus but produced malformed JSON on large real diffs). Each member catches different real issues at its real-code-optimal reasoning level: - Panel: DeepSeek-V3.2 @off (thoroughness/tests/consistency, fastest), GPT-5-mini @Medium (security breadth), GLM-5.2 @fast (architecture/config, free via z.ai). 3 lineages; all reliable on both real PRs. DeepSeek-V4-Pro/Flash were dropped as reviewers (truncated on large diffs). - Aggregator: Gemini-3.5-Flash @Medium. The bench favoured DeepSeek-V4-Flash on small synthetic bundles, but end-to-end on a real PR it malformed its merge JSON and the run degraded to a single-model review; Gemini merges reliably (small input, distinct lineage, salvage backstop). - Mechanism: chat() now takes `extra` (merged into the payload) so each member runs at a chosen reasoning level (OpenRouter reasoning:{effort|enabled}, z.ai thinking:{type}). Production previously sent none, so members ran at wildly different defaults (Gemini off, others heavy) — and the level materially changes review quality. Verified end-to-end on real PR #100: panel 3/3, ~60s, aggregated with working consensus badges, complementary security/async/CI findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UkrzdLbHDXwAjQx8iaDXEr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
A cockpit control UI for trimwire: a browser web UI + a multi-platform app that control an installed trimwire daemon. This PR contains the research/plan (
docs/cockpit/, 11 docs), a working POC (src/admin/— a loopback control API + embedded web UI, off by default), a Tauri desktop-shell scaffold (app/), and a clickable static demo of the UI.https://raw.githack.com/AZagatti/trimwire/claude/trimwire-cockpit-ui-8s69wn/docs/cockpit/demo/index.html
A self-contained, content-free, mock-data preview of the Flightdeck cockpit (Live · Savings · Strategies · Sessions · Config). No daemon/backend/build — just click. (Source:
docs/cockpit/demo/; can also drop intosite/public/cockpit-demo/for a hosted/cockpit-demo/link on the site's Cloudflare deploy.)To run the real POC locally:
trimwire cockpit→ openshttp://127.0.0.1:8766(control API + web UI on a loopback admin listener; token at~/.trimwire/control.token).Why
Requested by the maintainer. Decisions incorporated: agents pick the framework (unanimous Tauri 2, as the desktop wrapper); full control scope; local-first, remote phased + ToS-gated. Plus three follow-up constraints: no Flutter/Dart; no paid app stores → PWA-first (Android tightening toward iOS-style developer verification, Sept 2026); CLI changes must not break the cockpit.
Key design points
manifest.webmanifest+ icon → installable today.127.0.0.1:8766), physically off the gateway port that transits the Anthropic OAuth token. Bearer token + Host/Origin/Sec-Fetch-Siteguards; content-free/stats//version//service+ SSE; CSP + atomic-0600 token./api/v1contract — never the CLI — and contract tests fail CI on shape drift, so CLI commands can change freely.upstreamnever writable, no detection-evasion, remote hard-gated.Docs (
docs/cockpit/)README + 01 grounding · 02 framework · 03 control-API · 04 web UX · 05 multi-platform (PWA-first) · 06 remote · 07 security/ToS red lines · 08 roadmap · 09 POC · 10 fresh-sources security · 11 API stability ·
demo/. Internal — not added to the site doc-sync allowlist.How it was tested
cargo fmt --checkcleancargo clippy --all-targets -- -D warningscleancargo test --all-featurespasses (452 lib tests; 10 insrc/admin/, incl. content-free/auth-guard/[admin]-global-only/API-contract/PWA-manifest tests)trimwire serveis byte-unchanged unless[admin] enabled/trimwire cockpitDocs touched
ARCHITECTURE.md—admin/*layer row addedSPIKE.md— n/aCHANGELOG.md— n/a (POC behind opt-in; maintainer's call when promoting)README.md— n/a yet (new surface documented underdocs/cockpit/)Conventional commit prefix
feat:/docs:🤖 Generated with Claude Code
https://claude.ai/code/session_01MddVm85jQ84pmmh5Xx8eDd