KeiSeiKit-1.0/_primitives
Parfii-bot c0d900a943 fix(security): cortex /term env_clear + bind guard, agent-stub-scan stdin, magiclink revoke
Three independent security hardenings from cross-cutting audits.

1. cortex /term PTY env leak + bind guard (HIGH — Sonnet Cross-cutting + Opus)
   - kei-cortex/src/handlers/term_pty.rs: PTY spawn was inheriting daemon's
     full process env (KEI_AUTH_KEY, ANTHROPIC_API_KEY, FAL_KEY, etc.) into
     every authenticated /term shell. Combined with default cors_origin =
     https://keisei.app, one stored XSS on keisei.app + one bearer token =
     full local shell with all daemon secrets.
     Added apply_safe_env() helper: env_clear() + re-set only HOME, PATH,
     USER, LANG, TERM. Spawn helper invokes it before spawn_command.
   - kei-cortex/src/main.rs: extracted build_config() helper; added
     enforce_loopback_or_local_cors() guard called before serve.bind. Refuses
     to start if bind addr is non-loopback AND cors_origin is a public
     domain — prevents the XSS-to-shell scenario in production.

2. agent-stub-scan.sh stdin parsing (HIGH — multiple audits)
   - hooks/agent-stub-scan.sh: previously read $CLAUDE_AGENT_TRANSCRIPT env
     var which Claude Code does NOT set on PostToolUse:Agent. Hook silently
     exited 0 — RULE 0.16 enforcement was dead-code in production.
     Rewrote to read stdin JSON via jq, flatten .tool_response recursively
     (string|array|object via the same pattern as agent-event-done.sh),
     guard on .tool_name == "Agent" and command -v jq. Maintained WARN-tier
     exit-0 with TODO marker for ENFORCE flip on 2026-05-05 (per RULE 0.16
     §2 ladder).

3. magiclink revoke() silent no-op (HIGH — Opus Rust + Sonnet Cross-cutting)
   - kei-auth-magiclink/src/{error,provider}.rs: revoke() previously returned
     Ok(()) without doing anything. Operators expecting "revoke a session"
     semantics from the AuthProvider trait got false success. Stolen magic-
     link URLs remained valid until the 15-minute TTL.
     Added Error::Unsupported variant. revoke() now returns
     Err(Unsupported(...)) with explicit guidance: "rotate KEI_MAGICLINK_HMAC_
     KEY to invalidate all live tokens, or maintain a deny-list at the caller
     layer". Test provider_revoke_returns_unsupported_error confirms the
     error variant is wired.

Tests: cargo check + cargo test both PASS. 444 functional tests across
kei-cortex (428 lib) + kei-auth-magiclink (16 lib + smoke). Pre-existing
openai_loop_wiring.rs 502 failures in routes/openai/{chat,responses}.rs are
NOT introduced by these fixes — separate unrelated triage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 15:38:23 +08:00
..
_rust fix(security): cortex /term env_clear + bind guard, agent-stub-scan stdin, magiclink revoke 2026-05-03 15:38:23 +08:00
templates feat(live-graph): WebSocket activity stream — orchestrator-centric live view 2026-05-02 13:30:24 +08:00
design-scrape.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
figma-tokens.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
frontend-inspect.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
harden-base.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-ci-lint.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-docs-scaffold.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-doctor.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-sleep-queue.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-sleep-setup.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
kei-sleep-sync.sh feat(sleep-sync): mirror time-metrics + ledger snapshots, surface in Phase B report 2026-05-02 04:02:28 +08:00
live-preview.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
log-ship.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
MANIFEST.toml KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
metrics-scrape.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
provision-hetzner.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
provision-vultr.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
README.md KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
screenshot-decode.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00
tomd.sh KeiSeiKit-public — clean state 2026-05-01 12:09:03 +08:00

_primitives — first-class building blocks

_primitives/ holds standalone utilities that agents, hooks, and skills (including /compose-solution) depend on. Unlike _blocks/ (behavioral markdown) or _manifests/ (agent TOML), primitives are executable shell programs installed at $HOME/.claude/agents/_primitives/ by install.sh.

Current primitives

Primitive Purpose Invocation
tomd.sh Universal non-native-format → markdown converter (PDF, DOCX, XLSX, PPTX, CSV, images, code). ~/.claude/agents/_primitives/tomd.sh <file>

tomd.sh is a first-class primitive. Universal non-native-format → markdown converter with configurable cache directory (KEISEI_TOMD_CACHE) and KeiSeiKit-style error tags ([tomd]).

Hook integration

hooks/tomd-preread.sh is a PreToolUse(Read) hook that auto-redirects Claude to the converted markdown when a Read targets .docx / .doc / .xlsx / .pptx / .csv. Cached under $KEISEI_TOMD_CACHE (default /tmp/keisei-tomd-cache).

/compose-solution discovery

Phase 3 prior-art sweep greps _primitives/ alongside _blocks/, _manifests/, skills/, _bridges/, hooks/. If a user task involves file-format parsing, the meta-composer surfaces tomd automatically — reuse over rewrite (RULE "No Patching").