Repository navigation
Closed
Labels
laptopThe local (laptop) tool: install, abctl, the numbersThe local (laptop) tool: install, abctl, the numbers
Description
Part of #1714 · phase A, delivery step 2 · Sections 1, 2 and 3 · design in #1717 (docs/superpowers/specs/2026-11-07-praxis-mode-design.md)
Goal
Make Praxis record what it sees, and make Cortex accept it. The endpoint lands with its producer.
Scope
cortex_observe, one filter that parses (withcortex_parsefrom Praxis mode 1/8: Add the Rust workspace and port the inference parser #1718) and then records (the modulecortex_record) in each hook. Praxis runs response hooks in reverse chain order, so two filters would record before parsing.cortex_recordwrites request and response rows in Cortex's event schema, with the documented field meanings. Deferred rows throughemit_deferred_record:client_canceled,upstream_error, 413 withproxy_errorfor a body limit (as direct mode), andgateway_refusedfor other Praxis refusals.access_logafter it in the chain, because Praxis emits deferred records only then. It readsX-Cortex-Egress-Errorfrom the egress listener into the error kind.cortex_attribution: refuses a request without a valid token with 403, before anything is recorded or dialed, andcortex_recordwrites no row for it. With a valid token it acceptsX-Cortex-Attribution. Before the upstream it removes only the internal hop headers (the sevenwire.goheaders,X-Cortex-Attribution,-Request-Id,-Probe), and keepsX-Cortex-DestandX-Cortex-Tokenfor the egress listener. An application's ownX-Cortex-…headers go through.- The emitter: a queue bounded by 4096 lines and by 256 MiB, and one streaming
POST /v1/ingest. Over the byte limit it drops captures before rows. It never holds up traffic. Each line hasstartedAt. - Captures as direct mode keeps them: a decoded response capture only for
Content-Encoding: gzip(other responses as they came), and request headers as the gateway receives them, without the hop headers (a known difference from direct mode). - A capture only for inference rows. When a line with its capture would go over the 64 MiB line cap, the capture is dropped and the row stays.
- The binary
cortex-gateway(praxis/server) onpraxis-proxy =0.8.0, registered withregister_filters!. POST /v1/ingest(Go), only whenpraxis.enabledandbind_loopback_only. It has:- a bearer token and the
DELETE /v1/sessionsguards. - erase marks, in praxis mode only: a line whose
startedAtis before an erase of its session is dropped, and its tunnel join is released. - no response capture without the same request's capture.
- line format v1.
- captures only for inference rows, with credentials removed again.
- settle at ingestion, with a producer's cost record removed.
Atset when the row is appended, for agentop's page-order check.
- a bearer token and the
- Captures: credential removal ported from
core/redactand tested on the same cases.
Known edge cases to handle or accept (from the PR #1717 review)
- The erase mark is in memory, so a Cortex restart loses it.
- The erase check and the append are not one atomic step. A full fix is a check under the store's lock.
- A stream longer than the 10-minute mark can still record after an erase. Direct mode has the same window for a response in flight at an erase.
- With
Atset at append, a naming request that arrives before an earlier pending request could change which rows are linked to the session.
Done when
- The replay test: an NDJSON capture through
/v1/ingestgives the same/v1/sessionsand/v1/usageas the live run. - In direct mode
/v1/ingestanswers 404 and no token file exists. - A mid-body abort gives
client_canceled, and a body-limit refusal gives 413 withproxy_error, as in direct mode (spec [V 5]). - The CPU and heap of both processes are measured on a long Claude Code session with subagents, against direct mode. A request line is about 7–12 MiB (Tracker: Move the laptop data plane to Praxis when the upstream gaps close #1714, "Performance").
Depends on
#1718 (the inference parser).
Assisted-By: Claude (Anthropic AI) noreply@anthropic.com
Metadata
Metadata
Assignees
Labels
laptopThe local (laptop) tool: install, abctl, the numbersThe local (laptop) tool: install, abctl, the numbers
Type
Projects
- StatusShow more project fieldsDone
Activity
Fix: Read every member of a gzip body, and remove unused functions
Fix: Check the CRC32 and ISIZE of each gzip member
Docs: Add the plan for praxis mode step 2 (gateway and ingestion)
Feat: Add the praxis.enabled config switch
Feat: Add the cortex-gateway crate and the record module scaffold