On 2026-08-25, a command that was supposed to print secret names printed secret values instead. By the end of that day, fifteen credentials had to be rotated. Six days later, the rule written because of it was broken again. Both incidents are logged. Only one of them is closed, and it isn't the one you'd expect.
What happened
The incident is tracked as P33-0580, and its state as of this writing is PARKED — not closed. An agent session ran a command meant to produce a names-only listing of stored secrets. Instead, KEY=VALUE pairs for three environments went straight into the session transcript, where a human or log could read them.
Why the fix made it worse
Why doesn't redacting secrets after they're printed work?
Redaction only filters output after it has reached its destination. A positional filter also cannot split name=value: the equals sign makes one token, so "the first field" returns the whole line, secret included.
Fifteen credentials
What should you do the moment a credential leaks?
Rotate it immediately, and rotate every credential the exposure could have reached — not just the ones you can prove were used. Log the exposure as an incident that stays open until the response is verified, rather than treating a rotated value as the same thing as a closed case.
The total — fifteen credentials requiring rotation — isn't a number from the issue tracker. It's recorded in the operator's own global rules file, in the changelog entry that introduced the rule this incident produced. That entry attributes it to two sessions: the first is the one described above, later itemized as a GitHub personal access token exposed across three environments, five connector keys, a VPS root SSH password, and two production database connection strings. The second — the redaction failure — leaked ten more the same day. The same entry notes that the exposed root password reached a host running seven unrelated stacks: one value, seven systems downstream of it.
The rule: never produce the output
How do I stop AI agents leaking secrets into terminal output?
Stop the value from ever being printed in the first place — a command that might emit KEY=VALUE output has no safe redaction step after the fact. Route secret values through an environment variable set and consumed by reference, and prefer a tool's names-only listing mode whenever one exists.
The rule is INV-0.001, NO_SECRET_IN_THE_OPEN: names, never values, anywhere a human or log can read them. Set and consume a value through an environment variable in the same statement; never echo or pipe it into output. Prefer a tool's names-only mode:
How should a script handle an API key safely?
Assign the value to an environment variable in the same statement that fetches it, then reference that variable by name — never echo or interpolate it directly into a command line.
credential_cli.py resolve --project P56 --format env
I looked for a hook that enforces this the way a hook enforces a blocked deploy — something that would stop a command like the one on 2026-08-25 before it ran. I didn't find one. There's a hook that scans a deploy payload for secret-shaped files before it ships, which is a different check for a different moment. There is nothing today that inspects a command's output for a value mid-session and stops it. This rule, right now, is prompt-level: written down, and binding only because it's followed.
Six days later
On 2026-08-31, two new rows were filed:
Both are open as I write this — not resolved, not closed, no fixer or verifier recorded against either one yet. The rule was written on 2026-08-26. It held for five days before the next violation, filed six days after the original incident.
I'm not going to describe that as fixed, because it isn't. A prompt-level rule with no hook behind it lasted less than a week against ordinary work before it was broken again, in a shape the first incident hadn't covered — not a command's output this time, but a file written to disk and left there. A related row, P33-0704, filed the same day and currently TRIAGED, notes that the secrets tool itself changed underneath the safe pattern — it now prepends multi-line notices to its output, which breaks any script that was capturing a value by its position in that output. Even the workaround needs to be re-verified against a moving target.
What to copy
Prefer names-only output. Otherwise move values by reference through an environment variable; do not dump and filter afterward. A prompt-level rule is only as durable as the next person's attention span, and mine lasted six days.