The High-Integrity Systems Standard (HISS)
The definitive formal specification for deterministic software engineering and autonomous agent governance in every repository Praetor governs.
The High-Integrity Systems Standard (HISS) defines 21 invariants across four governing families. The invariants below are policy requirements. Their implemented coverage and remaining proof gaps are recorded in the HISS refinement audit; a passing scanner does not establish every invariant for every language.
Text description
- Deterministic Execution: HISS-01 (Acyclic DAG Control Flow), HISS-02 (Bounded Loops & I/O Timeouts), HISS-03 (Zero Frame Malloc), HISS-04 (Complexity & Sizing Bounds), HISS-05 (Variable Scoping), HISS-06 (Bounded Concurrency).
- Memory & Error Integrity: HISS-07 (Checked Errors & Zero Unwrap), HISS-08 (Static Determinism & Banned Funcs), HISS-09 (Mandatory // SAFETY: Proofs), HISS-10 (5-Layer Zero-Warnings Cascade).
- Contracts & Fleet Governance: HISS-11 (Hermetic Supply Chain), HISS-12 (Secret Leak Prevention), HISS-13 (Monotonic Debt Ratchet), HISS-14 (Append-Only ABI & Migration), HISS-15 (3D Test Discipline), HISS-16 (Canonical AGENTS.md & Server Gates).
- Agent Operations & Evidence: HISS-17 (State Ledger Discipline), HISS-18 (Diff-Aware CI Efficiency), HISS-19 (Reuse Before Writing), HISS-20 (Replayable Enforcement Evidence), HISS-21 (Platform Neutrality).
- Deterministic Execution → Memory & Error Integrity → Contracts & Fleet Governance → Agent Operations & Evidence.
- The 21 invariants of the High-Integrity Systems Standard form four governing families from static determinism to agent operations.
1. Mathematical Formalism & Core Invariants
HISS-01: Acyclic Control Flow (Banned Recursion)
Call graphs must form a Directed Acyclic Graph (DAG): $$G = (V, E), \quad \forall v \in V, \, (v, v) \notin E^*$$ Direct and mutual recursion are strictly prohibited in production runtimes. All iterative algorithms must use bounded stacks or explicit iteration.
HISS-02: Bounded Loops & Mandatory I/O Timeouts
Every loop construct must possess a compile-time statically verifiable scalar upper bound:
$$\forall \text{loop} \, L, \quad \exists N_{\max} \in \mathbb{N} \quad \text{s.t.} \quad \text{iterations}(L) \le N_{\max}$$
Unbounded for {} or while (true) loops without static counter termination are rejected. All network and filesystem I/O operations must accept and enforce explicit context.Context deadlines.
A Go context without a deadline is accepted in four exact shapes that perform no unbounded I/O with it; the rule matching reference lists the evidence and the near misses each one still reports:
- Lifecycle-owned: a
context.WithCancelcontext used in the start function of a framework hook whose stop function cancels it (fx.HookOnStartandOnStop), asmain.mainowns the process lifetime. The cancel function may be stored in a variable or a field before the stop function calls it. - Sinks: the
log/slogfunctions and*slog.Loggermethods that take a context only for its values, and aselectwhose cases only send to or receive from channels. - Callee-bounded: a function of the same module that derives
WithTimeoutorWithDeadlinefrom the context before any other use, followed up to four calls deep. - Ignored by a third-party constructor: an allow-listed function, such as the OTLP gRPC
exporter constructors, at the versions whose source was read, as the module's
go.modstates.
A new shape is proposed in an issue that names the exact shape, its evidence at a named version, and a near miss the rule must keep reporting; it lands as one table entry with a negative and a positive fixture.
HISS-03: Zero Frame Malloc (Deterministic Memory)
Hot simulation loops and rendering ticks (e.g. 60Hz/120Hz pipelines) must maintain zero dynamic heap allocations: $$\Delta \text{HeapAlloc}_{\text{tick}} = 0$$ Memory must be pre-allocated during subsystem initialization. Any dynamic heap allocation detected during a frame loop causes immediate test failure.
HISS-04: Complexity Bounds & Modular Sizing
Functions must remain strictly bounded in complexity and scope:
| Metric | Upper Bound | Enforcement Tool |
|---|---|---|
| McCabe Cyclomatic Complexity | $\le 10$ | gocyclo / clippy / semgrep |
| Cognitive Complexity | $\le 15$ | gocognit / sonar |
| Function Length | $\le 60$ LOC | AST Scanner |
| Executable Statements | $\le 50$ Statements | Compiler AST |
Function Length is measured over the body: from the line carrying the opening brace to the line carrying the closing brace, both counted. The signature is not part of the measurement, so a definition written int f(void) / { on two lines is exactly as long as the same definition written int f(void) { on one, and a signature wrapped across a long parameter list -- the ordinary shape of a GPU kernel -- adds nothing to the count. A brace-delimited scanner may still recognise a function from its signature line, which is how it names one whose brace is elsewhere; recognition and measurement are separate. Reformatting must never move a function across the cap.
HISS-05: Variable Scoping
Identifiers must be declared in the smallest lexical scope that serves them:
- Narrow lexical scoping prevents accidental variable shadowing and state leakage.
- Variables should be declared immediately before their first use.
- Status: advisory until an executable AST scope analyzer is attached.
HISS-06: Bounded Concurrency
Worker pools, concurrent routines, and parallel fan-out must declare an explicit scalar upper bound:
- Goroutine pools and thread spawning must specify a maximum concurrency capacity.
- Unbounded queue workers or unbounded concurrency patterns are banned.
- Status: advisory; race-detector tests verify absence of data races but do not verify pool bounds.
2. Memory Safety, Error Handling & Static Verification
HISS-07: Checked Errors & Zero Unwrap
Production software must never panic or unwrap:
- Total ban on Rust
.unwrap()and.expect()in non-test code. - Total ban on unchecked Go error returns (
_ = doSomething()). - All error flows must handle the error or wrap it with domain context.
- Abort policy: library code returns an error instead of ending the process. The scanner reports
Go
panicandos.Exit; Rustpanic!,todo!,unimplemented!,unreachable!,process::exitandprocess::abort; and Pythonsys.exit. Tests and binary entry points may abort: Gomain.main, a top-level Rustfn main, and the Pythonif __name__ == "__main__":block or top-leveldef main. The assert family and exit wrappers such aslog.Fatalare recorded as gaps in.config/hiss/coverage.yaml, not enforced. - Go
panic(http.ErrAbortHandler)is allowed anywhere:net/httpdocuments it as the way a handler aborts its response, and the server recovers it. Only the exactnet/httpsentinel counts; rule matching lists the shapes.
HISS-08: Static Determinism & Banned Functions
Dynamic runtime code evaluation is strictly banned:
- Total ban on
eval(),exec(), and dynamic string compilation. - Total ban on insecure C runtime functions (
gets,strcpy,sprintf). - A process signal needs a target bounded above 1 (
killpg,kill(-pid), Gosyscall.Kill,unix.Kill, Nodeprocess.kill(-pid)). Signal calls to a process group or process must verify the target exceeds 1 or is guarded earlier in the scope. - Python guard shape:
if not isinstance(pgid, int) or isinstance(pgid, bool) or pgid <= 1 or pgid == os.getpgrp(): <refuse> - Go guard shape:
if pid <= 1 || pid == os.Getpid() || pid == syscall.Getpgrp() { <refuse> } - JavaScript / TypeScript guard shape:
if (child.pid <= 1) <refuse>
HISS-09: Reference Safety & Mandatory Safety Proofs
Unsafe pointer arithmetic and memory dereferencing require explicit rationale:
- Any
unsafeblock must be preceded by an explanatory// SAFETY:comment proving invariants. - In Rust the comment may stand directly above the statement holding the block, and an
unsafe fndeclaration documents its callers' contract in a rustdoc# Safetysection or a// SAFETY:comment. Rule matching lists the accepted shapes. - Missing
// SAFETY:comments trigger immediate AST check rejection.
HISS-10: 5-Layer Zero-Warnings Cascade
Warnings are treated as fatal errors across all operational layers:
- IDE Layer: Real-time language server diagnostics (
standards-lsp). - Pre-Commit: Fast local Git hooks (
lefthook). - Pre-Push: Local test suite and branch audit.
- CI Layer: Multi-platform status checks.
-
Pre-Apply: Admission controllers and deployment webhooks.
-
praetorctl auditand the MCPstandards_auditread the CI layer's build lanes: every workflow command that compiles C, C++, Rust or Go code must carry its toolchain's warnings-as-errors form (-Werror,/WX,CMAKE_COMPILE_WARNING_AS_ERROR,meson setup --werror,-D warningsor a[lints]deny for Cargo, ago vetstep and, with cgo files,CGO_CFLAGS: -Werror), and a lane without it fails the audit (Build-warnings gate). The gate reads workflow files, the rootCargo.toml's[lints]and which sources the repository holds; what a make target, script or other build file runs is not read. - A lane that cannot use the form yet is declared in the manifest's exceptions list (rule
HISS-10, the workflow, a reason and an expiry within the category interval (A: stated, at most 90 days; B: 3 days, C: 10 days, D: 120 days; uncategorized: 90 days)); an expired entry fails like a missing one.
3. Supply Chain, Fleet Governance & Testing
HISS-11: Hermetic Supply Chain
Every dependency manifest must be cryptographically pinned:
- Pinned lockfiles mandatory (
go.sum,Cargo.lock,pnpm-lock.yaml). - Zero floating tags (e.g.
:latest) in container deployments. - SLSA provenance at the declared
supply_chain.slsa_leveland Sigstore Cosign signatures on all released binaries. praetorctl auditand the MCPstandards_auditmeasure the SLSA Build level, cosign signing and SBOM generation the release workflows can produce, and fail when the policy declares more (How the audit measures the SLSA level). The measurement reads workflow files only; published attestations are not checked.- A gap the release workflows cannot close yet is declared in the manifest's exceptions list (rule
HISS-11, the workflow the measurement read, a reason and an expiry within the category interval (A: stated, at most 90 days; B: 3 days, C: 10 days, D: 120 days; uncategorized: 90 days)): the audit prints it with the declared and measured values and passes until the entry expires, and an expired entry fails like a missing one (Declaring a gap).
HISS-12: Secret Leak Prevention
Zero credentials in Git history:
- Automated secret detection (
make secrets/praetorctl security secrets) scans full repository history insideverify-all. - History scans must inspect merge commits using
--log-opts="--full-history --branches --tags --remotes=origin -m"because defaultgit log -pomits patches for merge commits (the repository's own branches, tags andoriginremote refs; history fetched from any other remote belongs to that repository's own scan). - API keys, private certificates, and credentials must never be committed.
- The scaffolded
.gitleaks.tomlextends the gitleaks defaults, which name GitHub and GitLab tokens, with rules for the forge token shapes the defaults lack: a Gitea or Forgejo access token (40 lowercase hex) assigned to a name that says so, sent in anAuthorization: tokenheader, or written as the password of an https URL (templates/native/.gitleaks.toml.tmpl,TestScaffoldedGitleaksConfigDetectsForgeTokens). The generic rule's entropy threshold misses a low-entropy token, and a 40-hex git object id stays quiet. - Secret scan exemptions must be declared in
.standards.yamlwithrule: HISS-12, targetpath,tool(the gitleaks rule id, e.g.generic-api-key), optional findingfingerprint, mandatory ISO-8601expiresdate, and rationale inreason. - A HISS-12
pathmay name a file that exists only in history (a secret removed from the tree but not from the log). The audit's exceptions check does not require it in the tree: the secret gate judges the entry against the scanned history and fails an entry no finding uses (cmd/standardsctl/audit_exceptions.go,TestAuditExceptionTargets_SecretsHistoryPath). - An expired exemption excuses nothing; an exemption that excuses no findings fails the gate ("excuses no finding: remove it"). Undated exemption files such as
.gitleaksignoreare prohibited.
HISS-13: Monotonic Debt Ratchet
Total recorded infractions never grow against the committed baseline:
- An increase in technical debt requires a deliberately recorded rationale.
- Evaluated against
.standards-baseline.jsonbypraetorctl baseline --verify(read-only),praetorctl auditand the gate's HISS stage. - A recorded infraction is identified by its rule, its file and the function that holds it (or, outside a function, the text of its line), never by its line number, so code that only moves stays baselined (A baseline entry survives a line shift).
- A rejection still fails when a check added after the baseline was recorded finds debt in unchanged code, but it attributes those findings to the check, not to the change, and names the deliberate re-record (A HISS rejection names the violations).
HISS-14: Append-Only ABI & Migration Footers
Public application binary interfaces must evolve safely:
- Public APIs are append-only.
- Any breaking change requires a conventional commit breaking indicator (
!) and a mandatoryMigration:footer documenting upgrade instructions.
HISS-15: 3D Test Discipline
All public methods require three-dimensional test coverage:
- Positive Tests: Assert correct results under valid operational inputs.
- Negative Tests: Assert correct error returns under invalid inputs.
- Boundary Tests: Assert correct handling at numeric, string, and buffer limits ($0, 1, N_{\max}$).
- Clean Rule: Any file modified in a pull request must have all historical debt resolved.
HISS-16: Agentic Fleet Governance & Server-Side Enforcement
Agent instructions originate from a single canonical source (AGENTS.md):
- All vendor harnesses (
CLAUDE.md, Cursor rules, Copilot) are compiled viastandardsctl compile-context. - Every line outside a
## <Vendor>heading is shared by all targets. A## <Vendor>section (Claude Code,Cursor,GitHub Copilot,Windsurf,Gemini,Codex) compiles into that target alone and is removed from the other five, so one agent's guidance never reaches another. - Authoritative verification executes inside non-root ephemeral sandboxes with cgroup limits and default-deny egress.
- The "## Text Register" block in AGENTS.md is generated from the
register:section of.standards.yamlbystandardsctl compile-contextand verified by--verify; hand edits between its markers are reported as drift. Repository conventions such as a changelog fragment lane render only whereregister.conventionsstates them or the repository keeps achangelog.d/directory that holds a file (Text register).
4. Agent Operations & Replayable Evidence
HISS-17: State Ledger Discipline
Every agent turn maintains the local .workingdir ledger rather than re-deriving state from scratch:
- Turn start reads
praetorctl state status(a bounded summary) and the open tasks in.workingdir/OPEN.md; the whole.workingdir/STATE.mdis never read at turn start. - In-flight work is tracked via
standardsctl state task add/complete/archive, never held only in an agent's own working memory. - Turn end runs
standardsctl state sync ., which records working-tree status, dirty count, open tasks and a cryptographic state hash intoSTATE.md. - The whole
.workingdirdirectory is private and Git-ignored; reviewed, sanitized material is published underdocs/instead.
HISS-18: Diff-Aware CI Efficiency
CI pipelines evaluate the git diff before choosing which gates to run:
standardsctl ci filterclassifies a change and exports the gates it requires.- A docs-only or session-state-only change skips the heavy race detector and security suites; every other change keeps full invariant coverage.
- The filter fails closed. A file kind no classifier recognises (an extensionless script, a Dockerfile, a template) counts as configuration and runs tests, linters and security. A dependency or build manifest (
package.json,package-lock.json,pnpm-lock.yaml,go.mod,go.sum,Cargo.toml,Cargo.lock,pom.xml, aMakefile,tsconfig*.json,CMakeLists.txt, and the piprequirements*andconstraints*files ending in.txtor.in) is configuration, not documentation, even underdocs/(TestBuildManifestTextIsConfiguration,TestDependencyManifestUnderDocsIsConfiguration). An unresolvable base ref or an unreadable manifest runs the full matrix. Every filecompile-contextwrites counts as agent text and runs the HISS-16 context check. Agent text also selects the documentation gates (run_docs), because the Markdown gate and the credits gate read it (TestCreditsGateInputsSelectTheCreditsGate;internal/cifilter/filter.go,internal/cifilter/cifilter_test.go). - Code is every extension the HISS scanner reads (
hiss.SupportsExtension: C, C++ with.h,.hppand.hhheaders, Objective-C++.mmread by the C/C++ rules, CUDA, HIP, Go, Python, Rust, JavaScript, TypeScript, Svelte and shell scripts with.shor.bash;.mis listed as unscanned objective-c where a marker shows the repository is Objective-C), plus Java, Dart, Protocol Buffers, Zig and shading-language sources: GLSL (.glsland the glslang stage suffixes such as.vert,.frag,.comp), HLSL, WGSL and Metal. A code change runs tests, linters and security without context sync. Files under atest/,tests/orbenches/directory at any depth, such as a Cargo crate'stests/, are tests; the directory names no file kind, so a script or fixture there still fails closed (internal/cifilter/kinds_test.go). A file the scanner claims only from its contents (an extensionless script, a systemd unit, an Ansible playbook) is not code here: a diff classifier reads paths, not bytes, so it keeps failing closed or classifying as configuration (TestUnclassifiedFileKindsRunHeavyGates). overrides.ciin.standards.yamlgoverns the filter. Settingdiff_aware_filtering: falseruns the full matrix for every change; settingskip_heavy_gates_on_docs_or_state: falseruns it for docs-only and state-only changes. A manifest without the block keeps both on; a declared block reads an omitted key asfalse.ci filter --confignames another manifest (internal/config/config.goEffectiveCI,internal/cifilter/changed_files_test.go).- A gate that is skipped by classification is distinct from a gate that fails: the filter's decision is itself part of the recorded evidence.
praetorctl auditand the MCPstandards_auditread the repository's own workflow triggers and report, as[WARN]lines naming the file and line, apushthat runs on every branch, a pull request job that runs its work on a draft, and a job that skips a draft with a job-level condition or through a need held back on the draft. The accepted shape is the hosted gates' (internal/ghworkflow/hostedgate.go). Findings warn rather than fail because this rule's failure action rejects nothing. A workflow that must run everywhere is declared in the exceptions list (ruleHISS-18, its path, a reason and an expiry within the category interval (A: stated, at most 90 days; B: 3 days, C: 10 days, D: 120 days; uncategorized: 90 days)) (Workflow trigger audit).
HISS-19: Reuse Before Writing
One behavior has exactly one implementation:
- Before writing a function, config loader, parser or command, the repository is searched for the capability first; an existing implementation is extended or called rather than reimplemented.
- Configuration formats are held to the same rule: a second config system beside an existing loader is the same defect, because the two silently drift apart.
praetorctl dedupe scan .enforces this with function-level clone and utility-sprawl detection, run bymake dedupeinsideverify-all. Any clone or sprawl finding fails the scan: a finding the verdict does not carry is a finding nobody resolves. In an adopted repository the sprawl check requires one git helper per repository and names that helper; inside the engine it names the audited internal/util helpers.- The native AST scan reads Go only. Polyglot code clone detection across other languages (C, C++, CUDA, Python, Rust, shell, YAML workflows, and other languages listed in
Unscanned) is delegated to the pinned clone detectorjscpd5.4.2 (tools/jscpd/package.json). The detector binary is resolved fromPRAETOR_JSCPD_BINwhen set, elsejscpdonPATH, verified under a 10s context timeout to output exactlyjscpd 5.4.2; if unavailable or mismatched, the foreign scan is skipped with the reason recorded inForeignSkippedwhile the Go AST scan continues. Cross-root clone detection is supported via--across DIR(repeatable), passing all roots to onejscpdrun and retaining groups spanning multiple roots plus groups in the main root. Languages scanned byjscpdenterForeignScanned(reported, not gated);Not Scanned(Unscanned) keeps naming every language the gate does not judge, andpartial: Go sources onlyremains set whileUnscannedis non-empty. Foreign duplicate groups are reported underForeign Duplicate Blocks(reported, not gated), but do not alterPassedorCleanlinessScorein this change (gating them requires a baseline). A repository with no Go source gets no verdict at all (UnscannedandPartialininternal/dedupe/dedupe.go;TestScanRepo_Positive_PolyglotVerdictIsPartialininternal/dedupe/coverage_test.go).--jsonprints the same report as JSON. - The clone key renames a function's parameters, receiver, results and locals by first use before hashing (
cloneKeyininternal/dedupe/dedupe.go), so a copy whose locals were renamed still matches, while a body that reads a different local or field does not. Bodies under three statements or five printed lines are not hashed. praetorctl dedupe cadencemakes a sweep due after 20 commits, or once 1,000 Go production lines or 10 Go production files have been added since the recorded sweep, whichever comes first (--threshold,--added-lines,--added-files;CheckCadenceininternal/dedupe/cadence.go).- Duplication that is genuinely unavoidable (such as toolchain-generated boilerplate that cannot be unified) is declared in the top-level
exceptionslist of.standards.yamlwith ruleHISS-19. The entry names one repository file bypath(a glob is refused), a reason, and an expiry within the category interval (A: stated, at most 90 days; B: 3 days, C: 10 days, D: 120 days; uncategorized: 90 days) (config.ExceptionRuleDedupeininternal/config/exceptions.go):
exceptions:
- rule: "HISS-19"
path: "api/v1alpha1/zz_generated.deepcopy.go"
reason: "controller-gen produces near-identical DeepCopyInto methods per type"
expires: "2026-11-01"
The category field takes precedence over a case-insensitive category D (or A, B, C) reason prefix. Caps run from entered when present, otherwise today; an earlier expiry is allowed. A requires its own explicit expiry without a further cap. See the exception fields and TestValidateExceptionsCategoryCaps.
To excuse one clone group in that file, set fingerprint to an 8–64 hexadecimal character prefix of the group's reported hash (dedupe scan --json). Matching is case-insensitive and accepts odd-length prefixes. To limit locations by line, set lines: "START-END": positive, 1-based, inclusive bounds on the location's start line. The block need not end inside the range. Both scopes must match when both are present; omitting both preserves whole-path matching. For example, this entry excuses only starts on lines 10 through 16 in groups whose hash starts with abcdef12:
exceptions:
- rule: "HISS-19"
path: "tests/common/mod.rs"
fingerprint: "abcdef12"
lines: "10-16"
reason: "shared fixture setup awaiting extraction"
expires: "2026-11-01"
A clone group is fully excused only when every location matches a live entry, including its scopes. Native groups are reported under Excepted Duplicate Function Blocks; foreign groups use ForeignExcepted (foreign_excepted in JSON). A native group with any unexcused member still fails. An expired scoped entry excuses nothing and annotates only matching locations. An entry is used only when its path and scopes match a duplicate location, even when another location keeps the group reported; a scoped entry that matches nothing remains stale. An unscoped entry keeps the existing whole-path behavior. Distinct scopes may name the same file; identical entries are refused. TestScanRepo_ScopedExceptions and TestLoadManifestDedupeScopeSchemaRoundTrip cover these contracts. The target must exist and be a regular repository file; generated files bearing the canonical // Code generated ... DO NOT EDIT. header and directories skipped by the HISS scanner (such as build and target trees) are excluded from the scan automatically.
- Unexcused duplication is justified in the commit body, not left silent.
HISS-20: Replayable Enforcement Evidence
A claim of coverage is reproducible, never merely asserted:
- Every enforcement claim in
.config/hiss/coverage.yamlis replayed against a fixture corpus bypraetorctl hiss coverage --verify, run insideverify-all. - The check runs in both directions: a claim of enforcement must reproduce each of its positive fixtures, and a claim of absence must leave its gap fixtures undetected.
- A rule that silently gains coverage fails the gate exactly as one that silently loses it, so the catalog cannot drift in either direction undetected.
- The coverage catalog may only declare evidence for a rule the HISS rule catalog defines (
internal/hisscatalog/catalog.go); an unregistered identifier failsCatalog.Validate(TestValidateRefusesUnregisteredRule). A coverage entry takes its name from that catalog too, andpraetorctl hiss coverageprints the catalog's name for every rule.title:may be omitted; a title that differs from the catalog's is a[WARN]line naming the catalog's current text, never a failure (TestValidateWarnsOnADriftedTitle,TestRunHissCoverage_Negative_DriftedTitleWarnsWithTheCatalogText), so a catalog retitle does not break a repository that repeats the earlier text.praetorctl hiss coverage --sync-titleslists each stale title as a dry run, and--sync-titles --writerewrites them in place, changing only each title's value (SyncTitlesininternal/hisscoverage/titles.go;TestRunHissCoverage_Positive_SyncTitlesFixesElevenDriftedTitles). The HISS rule catalog also feedsstandards_explain_rule, the generated wiki's HISS matrix and the invariant table of every adoptedAGENTS.md, so all of them name the same 21 rules.
HISS-21: Platform Neutrality
A repository's gates, hooks and generated templates run on Linux, macOS and Windows, or declare the platform they require and skip with a stated reason where it is absent:
- A gate has exactly two acceptable states: running, with its result standing as the platform's result; or skipped, with the reason printed and the alternate coverage source named.
- A check that silently does not run and reports success is prohibited — see the Platform Neutrality invariant for the incident history and enforcement detail.
- Enforced by the Platform Neutrality matrix in CI.