| Copyright | (c) 2026 Jared Tobin |
|---|---|
| License | MIT |
| Maintainer | Jared Tobin <jared@ppad.tech> |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Censor.Runner.Manifest
Contents
Description
A declarative battery for the censor CLI: run-wide defaults and
a list of cases, each naming a target symbol and the workspace
layout to drive it with. One invocation opens the library once and
emits one censor/report-v3 object covering every case.
The format is line-oriented. Blank lines and # comments are
ignored; every other line is either a run-wide directive
(key value) or a case (case NAME key=value...):
# ppad-secp256k1 scalar surfaces meter wall alpha 1e-6 budget 20000 warmup 500 target-prefix censor_target_ workspace 128 case mul secret=0:32 case sign workspace=96 secret=0:32 public=32:32 case ecdh secret=0:32 context=32:32 case inv secret=0:32 replicates=3
A case's target symbol is target-prefix ++ its name unless
target= overrides it outright.
Synopsis
- data Manifest = Manifest {
- mfDefaults :: !Defaults
- mfCases :: ![ManifestCase]
- data Defaults = Defaults {}
- data ManifestCase = ManifestCase {}
- data Range = Range {}
- data BatchSpec
- = BatchFixed !Int
- | BatchAuto
- parseManifest :: String -> Either String Manifest
- emptyDefaults :: Defaults
- readRange :: String -> Maybe Range
- readSeed :: String -> Maybe Word64
- checkLayout :: Int -> [Range] -> [Range] -> [Range] -> Maybe String
Types
A parsed manifest.
Constructors
| Manifest | |
Fields
| |
Run-wide directives. Every field is optional; Nothing defers
to the runner's own default (or a command-line override).
Constructors
| Defaults | |
Fields
| |
data ManifestCase Source #
One case: a display name, the symbol to resolve, the workspace layout, and how many times to replicate it.
Constructors
| ManifestCase | |
Fields
| |
Instances
| Show ManifestCase Source # | |
Defined in Censor.Runner.Manifest Methods showsPrec :: Int -> ManifestCase -> ShowS # show :: ManifestCase -> String # showList :: [ManifestCase] -> ShowS # | |
| Eq ManifestCase Source # | |
Defined in Censor.Runner.Manifest | |
A byte range within the workspace: off:len.
How a case picks its cfgBatch. Foreign targets genuinely
recompute on every repetition, so BatchAuto is meaningful
here in a way it is not for a pure Haskell target.
Constructors
| BatchFixed !Int | pin the batch. |
| BatchAuto | calibrate it per case. |
Parsing
parseManifest :: String -> Either String Manifest Source #
Parse a manifest. Returns a message naming the offending line on failure.
Case order is preserved. A manifest with no cases is an error: it is far more likely a typo than an intent.
emptyDefaults :: Defaults Source #
All directives unset.
Layout validation
Arguments
| :: Int | workspace bytes |
| -> [Range] | secret ranges |
| -> [Range] | public ranges |
| -> [Range] | context ranges |
| -> Maybe String |
Check a workspace layout: every declared range must fit inside
the workspace, and the three roles must be pairwise disjoint.
Nothing when the layout is sound; otherwise a message naming
the first problem, for the caller to place in context.
Both entry points validate through this — a manifest case and the single-case command line — so the two cannot drift on what they accept.
Overlapping roles are rejected rather than resolved by
precedence. A byte is pinned in class A only (mcSecret),
pinned in both for the run (mcPublic), refreshed per pair in
both (mcContext), or freshly random in each class; asking for
two of those at once has no coherent reading, and whichever
overlay happened to land last would silently pick one. That is
how a public range could mask the context it overlapped,
turning a per-pair refresh into a constant without saying so.