First public release

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 14:49:02 -04:00
co-authored by Claude Opus 5.5
commit 0526dc283a
14 changed files with 2102 additions and 0 deletions
+227
View File
@@ -0,0 +1,227 @@
/**
* QuietDeploy — check a deployment plan against a network-signature budget
* before it runs.
*
* A deployment is observable. On a constrained or monitored link, the volume,
* the destinations and the timing of what a rollout pulls are themselves a
* signal, and the failures are consistently the same three:
*
* 1. **The unbudgeted pull nobody counted.** A build that "just pulls a base
* image" moves hundreds of megabytes to a third-party registry. It is
* invisible in the plan because it is not a step anyone wrote — it is a
* consequence of one.
*
* 2. **Egress to destinations outside the declared set.** An allowlisted
* egress firewall exists precisely because a deploy that reaches an
* unexpected host is either a supply-chain problem or a leak. A plan
* that cannot enumerate its destinations cannot be checked against one.
*
* 3. **A burst that fits the budget in total and not in any window.** Ten
* targets pulling 200 MB each inside one minute is a very different
* signature from the same traffic spread over an hour, and a total-only
* budget passes both. Peak rate is checked separately from volume.
*
* `retry` is treated as multiplying its step's cost, not as a footnote: a
* step budgeted at its first-attempt size is budgeted at its best case.
*
* Pure: no network, no clock. It sends nothing.
*/
import {
type CapabilityReport,
type Finding,
type FormatOptions,
evidence,
formatReport as renderReport,
} from '@extant2000/evidence-record'
export interface DeployStep {
name: string
/** Host contacted. Checked against the allowlist. */
destination: string
/** Bytes moved per attempt. `null` when unknown — never assumed zero. */
bytes: number | null
/** Seconds this step occupies. Used for the peak-rate check. */
durationSeconds?: number
/** Maximum attempts. A step budgeted at one attempt is budgeted at best case. */
retries?: number
/** Where the step is defined — a CI file, a compose file, a script. */
where: string
}
export interface SignatureBudget {
/** Total bytes the whole rollout may move. */
maxTotalBytes?: number
/** Peak bytes per second in any single step. */
maxBytesPerSecond?: number
/** Hosts this rollout is permitted to contact. */
allowedDestinations?: string[]
/** Steps that may run at once — concurrency multiplies the peak. */
concurrency?: number
}
const fmt = (n: number): string =>
n >= 1e9 ? `${(n / 1e9).toFixed(1)} GB`
: n >= 1e6 ? `${(n / 1e6).toFixed(1)} MB`
: n >= 1e3 ? `${(n / 1e3).toFixed(1)} kB`
: `${n} B`
/** Worst-case bytes for a step: every attempt counts. */
export function worstCaseBytes(s: DeployStep): number | null {
if (s.bytes === null) return null
return s.bytes * Math.max(1, s.retries ?? 1)
}
/** Peak bytes/second for a step, `null` when either input is missing. */
export function peakRate(s: DeployStep): number | null {
if (s.bytes === null || !s.durationSeconds) return null
return Math.round(s.bytes / s.durationSeconds)
}
function stepEvidence(s: DeployStep) {
return evidence.file(s.where, undefined,
s.bytes === null ? 'volume unknown' : fmt(worstCaseBytes(s)!),
`${s.destination}${s.retries && s.retries > 1 ? `, up to ${s.retries} attempts` : ''}`)
}
function stepFinding(s: DeployStep, budget: SignatureBudget): Finding {
const id = s.name
const allowed = budget.allowedDestinations
// Checked first: an unexpected destination is a different KIND of problem
// from a large one, and it stays a finding however small the transfer is.
if (allowed && allowed.length > 0 && !allowed.includes(s.destination)) {
return {
id,
summary: `${s.name} contacts ${s.destination}, which is not in the declared set`,
determination: 'fail',
severity: 'critical',
detail: 'An egress allowlist exists because a deploy reaching an unexpected host is either a supply-chain problem or a leak. Volume is irrelevant here.',
evidence: [stepEvidence(s)],
}
}
if (s.bytes === null) {
return {
id,
summary: `${s.name} moves an unknown volume to ${s.destination}`,
determination: 'not-assessed',
severity: 'high',
detail: 'An unmeasured transfer is not a small one. It cannot be counted against the budget, so the budget below is a lower bound, not a total.',
evidence: [stepEvidence(s)],
}
}
const rate = peakRate(s)
if (rate !== null && budget.maxBytesPerSecond && rate * (budget.concurrency ?? 1) > budget.maxBytesPerSecond) {
return {
id,
summary: `${s.name} peaks at ${fmt(rate * (budget.concurrency ?? 1))}/s`,
determination: 'fail',
severity: 'high',
detail: `Above the ${fmt(budget.maxBytesPerSecond)}/s ceiling${(budget.concurrency ?? 1) > 1 ? ` at concurrency ${budget.concurrency}` : ''}. The same bytes spread over a longer window would pass — the total is not the problem, the shape is.`,
evidence: [stepEvidence(s)],
}
}
if (rate === null && budget.maxBytesPerSecond) {
return {
id,
summary: `${s.name} has no duration, so its peak rate cannot be checked`,
determination: 'not-assessed',
severity: 'medium',
detail: 'A rate ceiling is declared and this step cannot be tested against it.',
evidence: [stepEvidence(s)],
}
}
return {
id,
summary: `${s.name} — ${fmt(worstCaseBytes(s)!)} to ${s.destination}`,
determination: 'pass',
severity: 'info',
evidence: [stepEvidence(s)],
}
}
/**
* The total, computed over WORST-CASE bytes.
*
* Reported as its own finding, and reported as a lower bound when any step's
* volume is unknown — a total assembled from partial measurements presented
* as a total is the way a budget check reassures without checking.
*/
function totalFinding(steps: DeployStep[], budget: SignatureBudget): Finding | null {
if (!budget.maxTotalBytes) return null
const known = steps.filter(s => s.bytes !== null)
const unknown = steps.length - known.length
const total = known.reduce((n, s) => n + worstCaseBytes(s)!, 0)
const over = total > budget.maxTotalBytes
if (unknown > 0 && !over) {
return {
id: 'total',
summary: `${fmt(total)} of ${fmt(budget.maxTotalBytes)} accounted for, with ${unknown} step(s) unmeasured`,
determination: 'not-assessed',
severity: 'high',
detail: 'This is a lower bound, not a total. The unmeasured steps could put it over, and a partial sum presented as a total is how a budget check reassures without checking.',
evidence: [evidence.measurement('worst-case egress', total, known.length, { unit: ' B' })],
}
}
return {
id: 'total',
summary: over
? `${fmt(total)} exceeds the ${fmt(budget.maxTotalBytes)} budget`
: `${fmt(total)} within the ${fmt(budget.maxTotalBytes)} budget`,
determination: over ? 'fail' : 'pass',
severity: over ? 'critical' : 'info',
detail: over
? 'Computed over worst-case bytes: every retry counts. A step budgeted at one attempt is budgeted at its best case.'
: undefined,
evidence: [evidence.measurement('worst-case egress', total, known.length, { unit: ' B' })],
}
}
/** Check a deployment plan against a signature budget. */
export function checkPlan(steps: DeployStep[], budget: SignatureBudget = {}): CapabilityReport {
const list = steps ?? []
if (list.length === 0) {
return {
capability: 'QuietDeploy',
scope: 'no steps described',
examined: 0,
findings: [],
notes: ['No deploy steps were described, so no signature was estimated. An unenumerated step still moves bytes.'],
}
}
const total = totalFinding(list, budget)
const destinations = [...new Set(list.map(s => s.destination))].sort()
return {
capability: 'QuietDeploy',
scope: `${list.length} step(s) across ${destinations.length} destination(s)`,
examined: list.length,
findings: [...(total ? [total] : []), ...list.map(s => stepFinding(s, budget))],
notes: [
`destinations: ${destinations.join(', ')}`,
...(budget.allowedDestinations?.length
? []
: ['No destination allowlist was supplied, so no step could be checked against one.']),
],
}
}
/** Render a signature check for a terminal, CI log or review. */
export function formatPlan(
steps: DeployStep[],
budget: SignatureBudget = {},
opts: FormatOptions = {},
): string {
return renderReport(checkPlan(steps, budget), opts)
}
export { fmt as formatBytes }