Documentation
¶
Overview ¶
Package collector is L4 of the SigComply CLI. For each planned policy it invokes the bound source plugins, validates the records against the registered evidence-type schemas, signs one envelope per (slot, source) pair, and writes the envelope to the vault. Per the KISS-no-DRY axiom, there is no record cache spanning policies: N policies → N invocations of Collect even if the same (plugin, slot) recurs.
See docs/architecture/02-layers.md §L4 and 04-source-plugins.md.
Package collector is L4 of the SigComply CLI: executes per-policy source fetches, validates records against their evidence type schemas, and writes one signed envelope per (slot, source) pair via the vault. Each policy is processed independently — there is no record cache spanning policies (KISS-no-DRY).
See docs/architecture/02-layers.md for the full layer contract.
Index ¶
Constants ¶
const EnvelopeFormatVersion = "envelope.v1"
EnvelopeFormatVersion is stamped on every envelope produced by the collector. Mirrors what auditors and the SPA verifier key against.
Variables ¶
var ( RetryPR = RetryPolicy{ MaxAttempts: 5, Backoff: []time.Duration{ 5 * time.Second, 15 * time.Second, 45 * time.Second, 2 * time.Minute, 5 * time.Minute, }, } RetryScheduled = RetryPolicy{ MaxAttempts: 3, Backoff: []time.Duration{ 10 * time.Second, 30 * time.Second, 90 * time.Second, }, } RetryNone = RetryPolicy{MaxAttempts: 1} )
Per-mode default policies. Total wall-clock budget per slot: PR mode = ~8 min, scheduled = ~2 min, none = 0.
Functions ¶
This section is empty.
Types ¶
type Input ¶
type Input struct {
Plan *planner.RunPlan
// Sources is the populated source-plugin registry.
Sources *registry.Registry[core.SourcePlugin]
// EvidenceTypes is the registered evidence-type catalog. The
// collector validates every emitted record's payload against its
// type's schema before signing — a schema mismatch is treated as a
// collection error and tagged on the policy. When nil (legacy
// callers, tests that don't exercise validation), validation is
// skipped.
EvidenceTypes *registry.Registry[core.EvidenceType]
// Vault is where envelopes land.
Vault core.Vault
// RunRoot is the framework-prefixed root inside the vault for this
// run, e.g. "soc2/2026-Q1/run_20260215T140000Z_a3f8b2c1".
RunRoot string
// SlotParamsExtras is appended to each binding's SlotParams before
// invoking Collect. The orchestrator uses this to inject period_id,
// period_start, period_end, now — values the planner knows but the
// project config does not.
SlotParamsExtras map[string]any
// Now is the run's reference time for envelope ProducedAt.
Now time.Time
// RetryPolicy controls per-slot retry behavior. Zero value (or
// MaxAttempts <= 1) is the legacy no-retry behavior. The
// orchestrator selects a mode-appropriate policy (PR=generous,
// Scheduled=fast-fail, Manual=none) and threads it through here.
RetryPolicy RetryPolicy
}
Input carries everything the collector needs.
type Output ¶
type Output struct {
// RecordsByPolicy[policyID][slotName] holds the union of all bound
// sources' records for that slot.
RecordsByPolicy map[string]map[string][]core.EvidenceRecord
// EnvelopesByPolicy[policyID] holds the relative vault paths of the
// envelopes written for that policy. Used by the evaluator to
// populate PolicyResult.EvidenceEnvelopes.
EnvelopesByPolicy map[string][]string
// CollectErrorsByPolicy[policyID] is set when at least one bound
// source returned an error. The evaluator turns this into a
// status=error result.
CollectErrorsByPolicy map[string]error
}
Output is what L5 (evaluator) consumes.
type RetryPolicy ¶ added in v0.21.0
RetryPolicy controls per-slot retry behavior in the collector. The orchestrator picks the policy from the run mode: PR runs use generous retry (blocking a developer's PR on a 30s AWS hiccup is worse than waiting), scheduled runs use fast-fail (the next scheduled run will pick up what was missed), manual runs do not retry (current behavior, single attempt).
MaxAttempts counts the total number of tries including the first. 0 or 1 disables retry. Backoff[i] is slept after the i'th failure (zero-indexed). When the schedule is shorter than the attempt count the final value is reused for the remaining waits.