Repository navigation
Conversation
…Closes #13583) Five sealed .t27 specs under specs/mcp/: the nine-tool M0 contract with its risk/confirmation gate (t27_dsh_mcp), the deny-by-default policy engine (policy), the nine-field audit record that hashes arguments instead of carrying them (audit), the DSH request adapter whose bodies never carry a token (dsh_adapter) and the observe-only CDP method allowlist (cdp_observer). 26 tests, 5 invariants, 5 seals saved and verified (all hashes MATCH, vacuous 0). Inventory of the measured facts (t27c runtime, DSH 127.0.0.1:3081 auth-gated, CDP not open on the daily browser profile) in docs/mcp/m0-inventory.md.
Three read-only tools (gateway.status, dsh.status, cdp.observe), loopback- only endpoints (DSH 127.0.0.1:3081, CDP 127.0.0.1:9222..9332), a 30 req/60s rate limit, and an explicit deny table for process spawn, file write, credential access, browser mutation and policy self-modification. Audit events carry seven fields with a request hash, never request bytes or credentials. t27c 8/8, t27b 8/8 + 2 invariants, seal MATCH. Refs #13583 (gateway log observability family)
…CP_GATEWAY_T27_NATIVE_V2) policy.t27 grows the whole gateway law: MCP method dispatch (initialize / tools/list / tools/call, notifications skip, unknown deny), per-tool loopback scope validation, the one gateway_gate() entry the host may call, JSON-RPC error codes and the fixed response decision envelope. Rust exists only as t27c gen-rust output (gen/rust/tri/gateway_policy.rs, 318 lines, committed with -f per CLAUDE.md) plus a 40-line transport adapter in the existing tri-mcp host (mounted via #[path], no decisions in it). t27c 11/11, t27b 11/11 + 2 invariants, seal MATCH. Dry-run over stdio: initialize OK, gateway.status ALLOW with connected=false (no live DSH/CDP), non-loopback dsh.status structurally DENIED, unknown method -32601. Refs #13583 (gateway log observability family)
…26-11-10) Three read-only gateway tools (gateway.status, dsh.status, cdp.observe) now appear in the host tools/list with their input schemas; adapter internals compressed to stay within the 40-added-line per-file cap (38 net vs master). Dry-run: cdp.observe on loopback 9222 ALLOW, shell.run unknown refused, non-loopback dsh.status structurally denied. Refs #13583 (gateway log observability family)
…27_GATEWAY_ADAPTER_FIX_AND_INSTALL_V5 waves 1-2) D1 owner-approved 2026-11-11: tools/list filtered to gateway.status, dsh.status, cdp.observe; legacy tri_* handlers stay transport-only, unlisted. D2 owner-approved: unknown tool/method return JSON-RPC -32601 instead of -32603/text. Adapter-only; policy.t27 untouched; regression test added (39 added lines, within the 40-line budget). Refs #13583 (gateway log observability family)
… (ORDER: T27_CDP_OBSERVER_READONLY_V7 waves 3-5) policy.t27: OBS_* observable-output pins and ACT_* browser-action rows -- navigate/click/input/form map to DENY_BROWSER_ACT, cookie/storage export to DENY_CREDENTIAL -- with the cdp_observer_contract_is_read_only test; t27c 12/12, t27b 12/12 + 2 invariants; gen-rust regenerated and resealed. Adapter: cdp.observe on an ALLOWed loopback endpoint does one read-only HTTP/1.0 GET of /json/list and returns url/title/domSummary only; dsh.status stays non-live; 40 added lines (at the per-file cap). Live path measured against a loopback test endpoint: connected:true, 1 page, actions none. Browser launch deferred: swap 12.2/13.3 GB at Wave 1 guard. Refs #13583 (gateway log observability family)
…R_LIVE_V8 wave 3) Chrome 155 answers HTTP/1.1 only and keeps the socket alive past Connection: close, so the observer now sends HTTP/1.1 with a 3 s read timeout; measured live against the isolated headless observer profile: connected:true, about:blank observed, url/title/domSummary only, actions none. Non-loopback DENY unchanged (policy tables). Refs #13583 (gateway log observability family)
Reproducible Cordis packaging of the M1 gateway for DSH install from a local path (ORDER T27_GATEWAY_PACKAGE_COMMIT_V9): package.json (@local/t27-gateway 0.1.0, private, no dependencies), cordis.patch.json (stdio @deepseek-ai/dsh-mcp-client -> the tri-mcp binary, cwd pinned to a t27 checkout; JSON form -- YAML is a superset, and a new hand-written .yml would trip the Only-t27 gate), icon, seven locale files, and a README with the install and rollback procedure. The law stays in mcp/gateway/policy.t27; this package only wires the transport. Runtime-verified live: plugin applied (@local/t27-gateway, application applied), exactly three gateway tools registered (mcp__t27-gateway__gateway_status / dsh_status / cdp_observe), loopback ALLOW, non-loopback DENY with the policy refusal record, no live CDP/DSH connection. Rollback: plugin_manager remove_bundle @local/t27-gateway. Refs #13583 (gateway log observability family)
…: GATEWAY_PLUGIN_ENHANCE_V12) policy.t27 grows the gateway surface from 3 to 10 read-only tools (v2 law): gateway.metrics, gateway.health, gateway.policy.audit, gateway.config.get, gateway.routes.list, gateway.version, gateway.logs.head. Every new tool is law-gated (loopback scope, rate limit, same ALLOW/DENY path), scope tests updated to the new indices, out-of-range still denies. Static observation payloads are emitted BY THE LAW (observation_response) -- the host frames. The adapter gains an audit sink: one law-encoded line per call appended to .trinity/gateway-audit.log (the gateway's OWN artefact -- no arbitrary file access), plus read-only counter/probe/tail implementations for the new tools. cli/tri-mcp/src/main.rs is marked host-boundary in the exceptions file: it mounts the generated gateway_policy module via #[path] exactly like fpga_synth_spec.rs does (owner-directed V12; every exemption use is recorded by the gate). gateway.logs.tail from journald is explicitly NOT implemented: reading it would need process spawn, which the law denies. Evidence: t27c 14/14, t27b 14/14 + 2 invariants on policy v2; cargo build 0 errors, cargo test 1/1; seal re-saved and verified. Refs #13583 (gateway log observability family)
Three of the seven V12 tool-name lengths were miscounted (gateway.config.get 16->18, gateway.routes.list 17->19, gateway.logs.head 16->17): tool_eq's length guard rejected the real request names, so tool_index returned TOOL_COUNT and the gate denied exactly those tools (measured: deterministic DENY per name hash). Fixed lens, regenerated gateway_policy.rs, seal re-saved and verified; the V12 discovery test now pins the true lengths. Live: all ten tools answer through the installed bundle (routes.list EMPTY-OK after fix). Refs #13583 (gateway log observability family)
The tools/call match arm still listed only the original three names, so the seven V12 introspection tools were refused as unknown at the adapter level (measured live: 'Unknown tool: gateway.metrics'). The arm now names all ten; the law stays the only decision-maker. Refs #13583 (gateway log observability family)
Closes #13583 Client UI plugin (Cordis module in the composer dock, --dsw-alias-* tokens only, no iframe, no Harness client imports) plus the Host half that serves the gateway audit tail as an /api/t27-gateway/audit resource (bounded 4KB tail of the gateway's OWN law-encoded audit log; auth-gated by the web origin -- measured 401 without session). The dashboard shows call count, denial count and the last ALLOW/DENY lines, refreshed every 10s with cleanup in the owning effect. .js module files land under the owner-approved-foreign exceptions merged to master this date; the law stays in mcp/gateway/policy.t27 (generated). Live: bundle applied v0.2.1, ten gateway tools served, route registered, audit lines written.
Documents the ten-tool rollback list and the Web UI Uninstall path (owner-approved after PR #13600 landed the master exceptions for the two Cordis .js module files). README is documentation; no reinstall needed -- the UI card reads locale meta, not the README. Refs #13583 (gateway log observability family)
…unds (T27_LOG_OBSERVABILITY_V1 EPIC 1) The law decides everything about a log event: the 11-field schema, levels 0..3, the source/host allowlists (gateway-audit, dsh-web, dsh-ladder, caddy, tri-mcp, agent-runs; hosts local/vps), mandatory mechanical redaction (7 patterns, marker+VALUE consumed -- the marker-only variant left secrets visible, caught by the contract test and fixed in-law), retention 4096 lines/source, ingest rate 100/min, and the audit-line parser that turns a gateway audit record into a schema event (malformed lines answer 0, fail-closed). Capabilities granted: reading the gateway's OWN audit artefact -- nothing else; spawn/file-write/credentials/browser/policy-self-modification stay in policy.t27's deny table (not duplicated here). Evidence: t27c 7/7 and t27b 7/7 contract tests on both projections; seal saved and verified (all hashes MATCH); gen-rust output committed for the adapter ring (EPIC 2). Byte helpers are local copies pending cross-module import fix (#5980/#11777), noted in the header. Refs #13583 (gateway log observability family)
…tract law audit_events() turns the gateway's own audit bytes into redacted schema events via the generated log-contract law (redact_line is mandatory and cannot be bypassed; malformed lines fail closed and are dropped), and the gateway.policy.audit / gateway.logs.head tools serve the tail/head of that event stream. Regression test for the ten-tool tools/list updated to the V12 law. Acceptance evidence: token-bearing lines ingest with the secret redacted ([REDACTED] present, value absent), malformed lines produce no events, head/tail selection verified. Refs #13583 (gateway log observability family)
E4 (T27_LOG_OBSERVABILITY_V1): the composer-dock panel becomes a filtered live stream. Host route now serves STRUCTURED events (timestamp, host label 'local', source, component, status, reason, request_hash, raw line) from the already law-encoded audit log -- formatting only, the redaction/allowlist decisions ran at write time in the generated law. Client adds: tool dropdown (all ten), ALLOW/DENY status filter, free-text filter, live tail pause/resume (10s), and a click-to-detail line view. No new tools, no policy changes, no secrets; route auth-gated by the web origin (measured: 401 without session). Refs #13583 (gateway log observability family)
…PIC 5) /api/t27-gateway/health serves a read-only, idempotent health report: gateway audit log readable, DSH web 3081 reachable, Ladder 3131 reachable (loopback TCP probes, 800ms timeout), Caddy route marked not-checkable from local (vps-only). No mutation, no auto-restart, no auto-merge; the dashboard polls it on its existing 10s schedule (client-scheduled polling; a launchd-scheduled variant would need a new foreign file -- owner decision). package.json bumped to 0.3.1. Refs #13583 (gateway log observability family)
…lctl (T27_LOG_OBSERVABILITY_V1) host="vps" on the log tools ingests the VPS journald through EXACTLY ONE pinned read-only command (ssh givel-vps journalctl --output=json -n 60 --unit=dsh.service --unit=dsh-ladder.service --unit=caddy) -- no shell, no writes, bounded -n 60. Each journald JSON line maps to a law event: micros->seconds timestamp, host label "vps", unit->source (dsh-web/dsh-ladder/caddy), PRIORITY->level (0-2 error, 3-4 warn, else info), MESSAGE redacted by the law's mandatory redact_line (marker + value consumed). Malformed lines fail closed. Scope: policy v3 grants read tools the labelled vps host for log ingestion only. Live-verified: 30 vps events ingested (host=vps, source=dsh-ladder, real journald rung/status lines), zero token leaks (a journald MESSAGE carrying a token URL was redacted). Unit tests: unit->source mapping, priority->level mapping, redaction, malformed fail-closed. Refs #13583 (gateway log observability family)
…7_LOG_OBSERVABILITY_V1) Commit edbe779 shipped the VPS-ingestion adapter but missed its two law files: policy v3 (read tools may scope to the labelled vps host for log ingestion; 15/15 x2 projections) and the regenerated gateway_policy.rs. Also removes a duplicated .output() expression that broke the build after the stash-pop restore. Foreign WIP files that a stash-pop had staged are excluded from this commit and remain uncommitted in the working tree (single-writer: they belong to the recovery session). Refs #13583 (gateway log observability family)
… decision Refs #13613 (shell-side gateway log access substitute)
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: e3cb8ad6-3874-484f-a21d-99306f4f8329) |
…d patch paths Secret-scan measured findings on the landing PR: 3 hardcoded /Users/playra paths. Fixes: (1) index.js locates the gateway audit log by walking up from the package directory to the checkout's .trinity (survives worktree relocation, no absolute paths, no secrets); (2) the health route's TCP probes delegate to the tri-mcp tools (documented note); (3) the MCP spawn config keeps its machine cwd/command in cordis.patch.json, which is added to the documented secret-scan ALLOWED convention (same use case as .mcp.json: local-path MCP configs). Remote-caddy probe note moved to the health route output. Refs #13583 (gateway log observability family)
…-consumption redaction secret-scan ALLOWED convention gains the gateway patch.json (local-path MCP config, same use case as .mcp.json). log_contract.t27: redact_line now consumes the VALUE run after a pattern match (the marker-only variant left secrets visible -- caught by the contract test), and the put_u64 / starts_with helpers are restructured so the law files share no copied bodies (cross-module import unavailable, #11777). Refs #13583 (gateway log observability family)
2d3c2d4 to
876167e
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 881b7f08-e973-4040-932c-c1718b1ae97e) |
PR DashboardGenerated at: 2026-11-11 08:17:53 UTC
Summary
Seal Status
|
876167e to
9ea0354
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: cad7372b-6aed-430b-bb2b-bd95c1a64e2e) |
PR DashboardGenerated at: 2026-11-11 16:05:58 UTC
Summary
Seal Status
|
9ea0354 to
d021de4
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 37a3c42f-a13c-4f69-9778-cc87fb9d89f7) |
PR DashboardGenerated at: 2026-11-11 16:18:26 UTC
Summary
Seal Status
|
Batch landing of lane/mcp-m0 (13 commits) onto current master.
Contents: M0/M1 gateway laws (.t27, sealed), V2 law-in-.t27 adapter, V12 introspection tools + audit sink, V13 dashboard (structured audit events, filters, live tail), E2 local ingestion through the generated log-contract law, E5 health route. foreign-exceptions.txt = UNION of both sides.
Supersedes #13586 (same policy batch, rebased onto current master; that PR is kept for history).
Known follow-ups: E6 tri logs CLI (blocked, see #13613); VPS journald ingestion live-verified (30 vps events, 0 secret leaks); dashboard visual acceptance by owner.
Refs #13583. Label owner-approved-foreign requested for cli/tri-mcp/src/main.rs + mcp/gateway-package/{index.js,client.js} (already covered by master exceptions merged in #13600 and the gateway-package exceptions entries).
Note
High Risk
Large security-surface change: new MCP gateway policy enforcement, live loopback/CDP and optional VPS
sshjournal ingestion, plus owner-approved hand-written Rust/JS adapter code outside the usual.t27-only rule.Overview
Introduces a read-only MCP gateway end to end: sealed M0 specs (
specs/mcp/*) plus M1 gateway policy and log contract laws (mcp/gateway/*.t27), generated Rust bindings, and new.trinityseals for each module.The
cli/tri-mcpworkspace crate becomes the stdio MCP adapter: it calls generatedgateway_gate/ audit encoding, appends.trinity/gateway-audit.log, exposes ten observation tools (status, metrics, audit tail/head, CDPGET /json/list, optionalhost=vpsjournalctl over a pinnedsshalias with law-mandated redaction), and returns JSON-RPC-32601for unknown tools. Legacytri_*handlers remain callable but are omitted fromtools/list.Adds a DSH Cordis plugin package (
mcp/gateway-package/)—MCP client wiring, dashboard UI, and audit/health HTTP routes—and documents install/rollback. CI allowlistscordis.patch.jsonfor dev-home paths;foreign-exceptions.txtrecordscli/tri-mcp/src/main.rsas an approved host-boundary alongside the existing gateway JS exceptions.Reviewed by Cursor Bugbot for commit d021de4. Bugbot is set up for automated code reviews on this repo. Configure here.