Expand description
The one rule set that makes text a run printed fit to publish.
Evidence carries text nobody wrote for a reader outside the machine it ran on: the reason
a case skipped, the tail of a failure, a command’s captured output. Any of it can hold a
credential the command echoed or a path that names the account it ran under, and once it
is on a public page it cannot be taken back. public_text is the rule for that text;
wiring the evidence publication to it is I1955, and until then nothing calls it.
redact_secrets alone is applied today wherever this process hands back or sends text
it did not write (I2161): every HTTP error body (http::router::error_response, which
http::router::Response::error returns), every JSON-RPC error (mcp::protocol::error)
and MCP tool refusal (mcp::surface::Surface::call_from), the request fields the server
logs (http::router::Router::foreign_origin, http::server::answer_http), every field of
every event and span the log writes, whoever logged it (logging::redact, I2708), a
handover body before it is signed into the mesh journal and replicated in clear
(mesh::handover::to_body), and the free text of a review as it is signed
(mesh::cooperation::redacted, I2708). Two records use it to find a credential rather than to send
one: continuity::record::portability refuses a continuity record that carries one, and
reasoning::store::redact takes it out of a reasoning record before the record is kept.
These are all of its callers; no_answer_carries_a_credential holds this list to the code
in both directions.
The credential shapes are not a second table. They are a port of MJ_CAPTURE_SECRETS and
MJ_CAPTURE_SECRET_ASSIGN in lib/capture.sh, the table the prompt archive has redacted
with from the start, applied the way mj_capture_redact applies it: each shape in table
order over the whole text, every leftmost-longest match replaced by a marker naming the
shape, and then the assignment rule, which keeps the name a value was assigned to. Two
tests hold the port to the table: one reads lib/capture.sh and compares the shapes, and
one fixture, test/fixtures/redaction/shapes.tsv, is run through both implementations.
The crate has no regular-expression engine, so the shapes are matched by the small
hand-written matcher below, which knows exactly the constructs the table uses.
Two neighbours are different concerns and stay apart: execution::redact removes the
fields a capability’s input schema marks sensitive, and generate::forbidden_in is the
last word on a published artifact, which public_text asks after it has done its work.
Before asking, public_text refuses a text that still carries a secret no shape covers:
one whose announcing shape fired, in this call or in an earlier redaction whose marker
the text carries, and one whose armour or name is left once the shapes have run. Redacting
the announcement is what would let the rest past that check.
use majordomus_cli::redaction::redact_secrets;
// assembled at run time, so that no committed file carries a credential's shape
let token = format!("{}{}", "ghp_", "a".repeat(24));
let out = redact_secrets(&format!("pushing with {token} failed"));
assert_eq!(out.text, "pushing with [redacted:github-token] failed");
assert_eq!(out.kinds, ["github-token"]);Structs§
- Redacted
- Text after
redact_secretsorpublic_text, with the shapes that fired in it.
Functions§
- normalise_
machine_ paths - The repository root written as
<repo>and the home directory as<home>. - public_
text - Text fit to publish: machine paths normalised, then credentials redacted, then checked.
- redact_
secrets - Every credential in
textreplaced by a marker that names its shape. - shape_
names - The names of the credential shapes, in the order they are applied, then
assignment.