ICapturePolicy Type
A consumer-supplied, typed seam that shapes each decoded line **just before it enters the capture
backlog** — the redaction-at-capture extension point, set with `Command.CapturePolicy`.
For every framed line handed to a capture, `OnCapture` runs *before* the line is retained, so the
text it returns — never the raw line — is what lands in the backlog, and therefore in
`ProcessResult.Stdout`/`Stderr` and `Finished.Stderr`. That is what the observing
`Command.OnStdoutLine`/`OnStderrLine` handlers cannot do: they run *alongside* capture and can see
a line, not shape what is kept.
**Scope and boundaries (read before relying on it for secret hygiene).** This seam shapes the
in-memory capture backlog and nothing else. It deliberately does **not** reach the independent
observation sinks, each of which keeps its existing contract and sees the line **unshaped**:
- the per-line handlers `Command.OnStdoutLine`/`OnStderrLine` and the tees
`Command.StdoutTee`/`StderrTee` — they exist to observe the real output; if you also write to a
log or a file there, redact in that sink too;
- the **streaming** verbs, which hand each line to a live consumer rather than retaining it:
`RunningProcess.StdoutLinesAsync`, `OutputEventsAsync`, `WaitForLineAsync`, the byte-chunk
streams, `PtySession`'s window/transcript, `ContentLengthSession`'s frames, and the stderr
readiness probes. (`FinishAsync`'s retained *stderr* on those same sessions **is** backlog, and
is shaped.)
- a **raw byte** capture, which has no decoded line to shape: `OutputBytesAsync`'s stdout. A bytes
run's line-pumped **stderr** is still shaped.
A `Pipeline` captures nothing but raw bytes — its final stdout and every stage's stderr — so it
cannot shape anything at all; a stage carrying a policy is therefore **rejected** by `Pipe`
(`ArgumentException`) rather than run with the seam quietly inactive. Run such a command on its own.
**A failing policy fails closed.** If `OnCapture` throws — or returns `null` — the offending line
is retained **empty**, never the raw line it was meant to scrub, and the policy stays active for
the lines that follow. A redactor that throws blanks its output rather than leaking it. Nothing
else reports that failure, so prefer a policy that cannot throw.
**It must be thread-safe.** One policy instance serves both of a run's streams, whose pumps are
independent tasks, so `OnCapture` can be called for a stdout line and a stderr line at the same
time (and for several concurrent runs sharing one policy). A pure transform of its argument — the
shape this seam is for — needs nothing extra; a policy that keeps mutable state has to guard it.
**What it does not decide.** *How much* is retained, and what is evicted on overflow, remain
`OutputBufferPolicy`'s job; the two compose orthogonally — this decides each retained line's
content, that decides how many survive. Retention bookkeeping (the retained-byte total, the
`DropNewest` seal, `Truncated`/`TooLarge`) is computed from the text you return, while the
cumulative line counters and the raw-pipe byte counters (`RunningProcess.StdoutBytesSeen`) are
taken before this seam and are untouched by it.
Instance members
| Instance member |
Description
|
Full Usage:
this.Name
Returns: string
Modifiers: abstract |
A short, stable, human-readable name for this policy (`"redact-tokens"`, say), surfaced by `Command.ConfiguredCapturePolicyName` so a configured policy is introspectable in a test or a diagnostic dump rather than an anonymous callback.
|
Full Usage:
this.OnCapture
Parameters:
CaptureStream
line : string
Returns: string
Modifiers: abstract |
Shape one decoded `line` from `stream` just before it enters the capture backlog, returning the text to retain: the line itself to keep it unchanged, a rewrite to redact it, or `""` to blank it while keeping its slot (and the line/byte counters). The line arrives with its terminator already stripped — the shape `StdoutLinesAsync` yields. Keep it cheap: it runs on the capture pump, in front of every retained line.
|
ProcessKit API Reference