Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
the command, and the start of stderr. Before, `grep` exiting 2 on a missing
directory or `git` exiting 128 outside a repository was reported as a
network failure (#562).
- **BREAKING:** Witness / in-toto attestation verification moves out of
`repro_hermetic_build` into a new step type, `repro_witness_attestation`,
which runs first in RE-02.01 and can conclude only FAIL. It verifies the
attestations of the successful CI runs for the audited commit (`git
rev-parse HEAD`), with a signing policy bound to the repository and that
commit, instead of the latest run on the default branch. It reads network
events only from a statement whose predicate type is exactly
`https://in-toto.io/attestation/runtime-trace/v0.1` (`monitorLog.network`),
plus the existing Witness `command-run` installer scan; a `network` key on
any other predicate is ignored. A verified attestation that records
network access concludes RE-02.01 FAIL even when the repository also has a
Nix or Bazel strong signal. A verified clean trace is evidence only, no
longer a PASS signal: an empty network log is also what a monitor that
does not trace sockets records. A missing prerequisite (no `gh`, no
login, no run, no attestation, `sigstore` not installed) leaves the step
INCONCLUSIVE with the reason, as before (#553).
- **BREAKING:** the `verify_witness_attestations` step setting moves from
`repro_hermetic_build` to `repro_witness_attestation`. A pass override or
custom control that sets it on `repro_hermetic_build` now fails loading
under strict step settings; set it on the `repro_witness_attestation` step
instead (#553).

### Fixed

Expand Down
14 changes: 11 additions & 3 deletions docs/architecture/framework-design.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Darnit Framework Design Specification

> **Version**: 1.0.0-alpha.13
> **Version**: 1.0.0-alpha.14
> **Status**: Authoritative
> **Last Updated**: 2026-10-06
> **Last Updated**: 2026-10-07

This specification defines the authoritative design of the Darnit framework, including the sieve orchestrator, TOML schema, built-in pass types, remediation actions, and plugin protocol.

Expand Down Expand Up @@ -224,7 +224,7 @@ Every step type registers a **ceiling**: the set of outcomes (`pass`, `fail`) it
| `manual`, `manual_steps` | `{}` | -- |
| remediation handlers (`file_create`, `platform_setting`, `project_update`, `yaml_inject`) | `{}` | -- |

A plugin handler registers its ceiling with the handler (`registry.register(..., ceiling={"pass", "fail"})`). A plugin handler that registers no ceiling has the ceiling `{}`: its results are evidence only. A step type that decides from text or file-presence signals registers `{fail}`; the reproducibility framework's five step types (`repro_deps_pinned`, `repro_build_env_declared`, `repro_hermetic_build`, `repro_provenance_exists`, `repro_bit_for_bit`) do, so they conclude PASS only with a promotion, and their signals reach the control's later steps as evidence (feature 044, section 12).
A plugin handler registers its ceiling with the handler (`registry.register(..., ceiling={"pass", "fail"})`). A plugin handler that registers no ceiling has the ceiling `{}`: its results are evidence only. A step type that decides from text or file-presence signals registers `{fail}`; the reproducibility framework's five such step types (`repro_deps_pinned`, `repro_build_env_declared`, `repro_hermetic_build`, `repro_provenance_exists`, `repro_bit_for_bit`) do, so they conclude PASS only with a promotion, and their signals reach the control's later steps as evidence (feature 044, section 12). Its sixth, `repro_witness_attestation`, registers `{fail}` for a different reason: a Sigstore-verified in-toto runtime-trace attestation for the audited commit can show that the build accessed the network, but cannot yet show that it did not. Under the in-toto parsing rules an absent optional list is equivalent to an empty one, and what `monitorLog.network` records depends on the monitor's type and trace policy, so a monitor that does not trace sockets produces the same empty log as a build with no network access. A verified clean trace is therefore evidence, and PASS waits for an allowlist of monitor types backed by real attestations (#553).

**Step fields** (on any `[[controls."ID".passes]]` entry; none are passed to the handler except `fail_on_miss` and `fail_on_status`):

Expand Down Expand Up @@ -264,6 +264,12 @@ The orchestrator computes the effective set from the registry at dispatch time a
- **WHEN** a step declares `concludes = ["pass"]` on a step type whose ceiling does not include `pass`, without a promotion
- **THEN** loading the framework configuration MUST fail with an error naming the framework, control, step index, and outcome

#### Scenario: A runtime trace proves only network access
- **WHEN** a `repro_witness_attestation` step verifies an attestation for the audited commit whose runtime-trace `monitorLog.network` records one or more events
- **THEN** its FAIL MUST conclude the control
- **AND** when the verified trace records no network events, the step MUST NOT report PASS; its result MUST be recorded as evidence and evaluation MUST continue
- **AND** an attestation whose signing identity is not bound to the audited repository and the audited commit MUST NOT be used

### 3.0.2 Step Disposition Table

The disposition applied to each step, by handler outcome and whether the outcome is in the step's effective set:
Expand Down Expand Up @@ -1934,6 +1940,7 @@ Implementation-registered sieve handlers (non-exhaustive):
| `generate_threat_model` | `darnit-baseline` (remediation) | `{pass, fail}` |
| `gittuf_verify_policy`, `gittuf_commits_signed` | `darnit-gittuf` | `{pass, fail}` (cryptographic verification) |
| `repro_deps_pinned`, `repro_build_env_declared`, `repro_hermetic_build`, `repro_provenance_exists`, `repro_bit_for_bit` | `darnit-reproducibility` | `{fail}`: they decide from text and file-presence signals, so PASS needs a corpus-backed promotion (section 3.0.1) |
| `repro_witness_attestation` | `darnit-reproducibility` | `{fail}`: a verified runtime-trace attestation can show network access but, until monitor types are allowlisted, cannot show its absence (section 3.0.1, #553) |
| `csl_llm_if_present` | `darnit-csl` | `{fail}` |

The reproducibility ceilings are part of that framework's own registration, not its package name, so they hold under a rename of the package.
Expand Down Expand Up @@ -2318,6 +2325,7 @@ The following requirements have been superseded: by the handler dispatch archite

| Version | Date | Changes |
|---------|------|---------|
| 1.0.0-alpha.14 | 2026-10-07 | `repro_witness_attestation`: Witness/in-toto runtime-trace verification moves out of `repro_hermetic_build` into its own step type with ceiling `{fail}`, bound to the audited commit and reading only the runtime-trace predicate; a verified clean trace is evidence, not PASS (Sections 3.0.1, 12; #553) |
| 1.0.0-alpha.13 | 2026-10-06 | Error class `unexpected_exit`: an `exec` step whose undeclared exit code has no identified cause no longer reports `network`; exit code 127 reports `missing_tool` (Sections 3.3, 5.2; #562) |
| 1.0.0-alpha.12 | 2026-10-04 | Repository-level `.baseline.toml` is no longer read: one notice points at `darnit config migrate`, framework selection only by `--framework` or a tool argument (Sections 2.3, 10.5, 14.4, 15.1; Appendix C) |
| 1.0.0-alpha.11 | 2026-10-04 | Close remaining false-PASS paths (feature 044): an expression that cannot be evaluated or is not boolean makes the step ERROR, expression names per step type with usable `project` values and a repository-aware `file_exists`, load-time expression reference check (Section 3.7); step registration declares `settings` and `expression_names`, plugins cannot replace a registered step type, and unknown control keys, unknown step keys, and unregistered step types fail loading (Sections 2.3, 3.0.3); reproducibility step types conclude only FAIL (Sections 3.0.1, 12); `expr_decides`, an expression that decides on a handler PASS (Sections 3.0.3, 3.7); `gh_api` `evidence_fields`, required for personal records (Section 3.8); `file_must_exist` replaced by the registered `file_exists` (Section 3.2); field tables corrected to what each handler reads (Sections 3.3-3.5) |
Expand Down
Loading
Loading