Skip to content

v0.106.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 23:24

What

The authority release. Two flag-days land in the same window, and both
change what an existing file MEANS. The envelope's value forms split into the
four authorities β€” vars: and env: are dead, inputs: Β· config: Β·
const: Β· secrets: are the whole family β€” and a permits: block stops
being optional: absent is now the EMPTY boundary, not the unconfined floor.
Around them the attestation lane arrives whole: a run declares its entropy and
its clock, boots from a manifest, seals what it covered, signs, anchors to a
public transparency log, and exports a pack an auditor reads without trusting
us. This is the first release where a workflow written yesterday can refuse to
check today. The migration is the front page, not a footnote β€” nika check --fix applies the mechanical half and STOPS untouched rather than guess at
the rest.

⚠️ Migration

1 Β· The value authorities β€” vars: and env: are dead (R3a Β« the E-split Β» Β· #669)

The law is classify-not-rename: every old entry moves to the authority its
ROLE commands, never to one bulk destination.

Dead form Classify it as Refusal
vars: entry Β· a typed parameter a caller supplies inputs: (typed Β· required: Β· default:) NIKA-VALUES-001
vars: entry Β· a fixed value baked into the file const: (bare literal, or { type, value }) NIKA-VALUES-001
env: entry Β· non-sensitive runtime configuration config: (typed Β· deployment-supplied) NIKA-VALUES-002
env: entry Β· a credential secrets: (a store reference Β· never a literal) NIKA-VALUES-002
env: entry Β· a name a child process must see permits: { env: [NAME] } (exact names) NIKA-VALUES-002
${{ vars.X }} Β· ${{ env.X }} the authority the role commands -001 Β· -002
${{ anything_else.X }} the family is closed: inputs Β· config Β· const Β· secrets NIKA-VALUES-003

nika check --fix migrates the vars: half mechanically β€” comment-preserving,
idempotent, and class-aware (the name→class map comes from the file's own
block, never a blind rename). It leaves the file UNTOUCHED and names the reason
on a credential-shaped name, a typed-only declaration, a flow-style
vars: {…} header, a required: true entry without type:, or an empty
block: atomic-or-nothing, the codemod never guesses. env: has no
mechanical repair
β€” re-shaping a flat string map into typed config:
declarations is a human classification, and the teaching says so at the point
of refusal.

Two consequences worth reading twice Β· config: resolves ONLY against the
declared block, so the engine never silently falls back to the OS environment
(every value a workflow depends on is visible in the file); and --var now
names inputs: β€” the flag keeps its spelling, its target moved.

2 Β· The boundary β€” absent permits: is zero authority (F-O8 Β· NEP-0003 Β· #691)

A missing permits: block used to be the unconfined floor. It is now the
EMPTY boundary: a body carrying any effect with no block refuses
NIKA-AUTH-006 at check β€” before a token is spent β€” and the runtime gates
refuse before any spawn. Only a pure-compute body stays clean, and it gets a
hint teaching permits: {}, the legal zero. The 39 embedded workflows that
shipped with this repo β€” examples, showcase tiers, templates, battery files β€”
each had to declare its inferred block: that is the blast radius, measured
rather than guessed. The repair is one command β€”
nika check --infer-permits prints the tightest block, and the round-trip law
holds (the inferred block re-checks clean).

Four more refusals ride the same window. Each was previously admitted:

Refusal What it now refuses
NIKA-AUTH-007 an interpolation reaching a permit BOUND (host Β· glob Β· program Β· env name) β€” a bound MUST be a literal, or the boundary is self-serve
NIKA-AUTH-008 an untrusted value whose canonical resolved form escapes the step's permit (the static twin of the runtime re-gate)
NIKA-AUTH-009 a permits: env: entry naming a dangerous-floor variable β€” the engine strips it unconditionally, so the grant is an inert dead grant
NIKA-AUTH-010 *.example.com in permits.net.http β€” the *. subdomain wildcard delegates the boundary to the zone operator (every host under the suffix, present and future). Name exact hosts, or the bare * when allow-all is genuinely intended
NIKA-SEC-008 a nika:fetch whose resolved URL path names a code-bearing class with no inert: door declared β€” the read hides an execution sink (NEP-0006)

And one law that carries no code but changes what a child process SEES Β· a
spawned child no longer inherits the engine environment
. Its environment is
COMPOSED from a cleared slate β€” the runner floor βˆͺ the names declared in
permits: env: βˆͺ the task's own env: map, the dangerous names stripped last
(F-O4 Β· NEP-0005). A workflow that relied on an ambient variable reaching an
exec: child must now name it.

3 Β· The embedder cut β€” nika-schema β†’ nika-check (#683 Β· no re-export shims)

Before After
nika_schema::{analyze, AnalyzedWorkflow} nika_check::{analyze, AnalyzedWorkflow}
nika_schema::{check, check_composed, infer_permits} nika_check::{…}
nika_vocab::VarType (the flat 6-enum) the full TypeExpr of spec 09
NIKA-PARSE-019 (entropy Γ— clock) NIKA-PARSE-026 Β· -027 Β· -028
NIKA-PARSE-015 (malformed typed vars:) retired Β· never reused β€” what it refused is admitted by TypeExpr; what stays outside the grammar refuses NIKA-TYPE-001

nika-schema keeps its blueprint shape (THE PARSER: AST + raw + error +
keysets). Every consumer inside this repo β€” cli Β· lsp Β· runtime Β· dap Β· mcp Β·
verb-agent Β· lints Β· graph Β· display Β· onboard Β· the fuzz harness β€” already
points at nika_check; what migrates is the embedding code outside this repo.
The cut is clean by choice: a shim would have kept two names for one judgment.

The retired and re-minted codes count as breaking for anyone FILTERING on
them β€” a tool watching NIKA-PARSE-019 for the entropy Γ— clock contradiction
will never see it pass again.

4 Β· The predicates and the type grammar (R5 Β· #677 Β· R3b Β· #673)

Dead form The respelling Refusal
after: { t: succeeded } after: { t: success } NIKA-DAG-005
after: { t: failed } after: { t: failure } NIKA-DAG-005
type: boolean type: bool β€” the one boolean spelling, no alias NIKA-TYPE-001
bare type: array Β· type: object { array: T } Β· { object: { … } } NIKA-TYPE-001
a default: that does not fit its own type: fix the value, or the type NIKA-DEFAULT-001

skipped and terminal are unchanged. nika check --fix applies the
predicate respelling 1:1 β€” flow and block after: forms, quoted values,
comments preserved, idempotent; a when: status comparison is the
NIKA-DAG-007 class and is never touched. NIKA-DEFAULT-001 closes a real
soundness hole: a declared default that could never satisfy its own type used
to sail through.

Added

  • nika-check β€” the static judgment crate (new L0 member Β· split from
    nika-schema at the 15k crate-size wall; the nika-graph/nika-dap
    precedents): the workflow analyzer (analyze Β· AnalyzedWorkflow Β· the ONE
    derived-DAG-edge computation every surface projects) plus the whole nika check ladder (check Β· check_composed Β· cost ceiling Β· secret-leak IFC Β·
    capability-escape fit Β· trifecta Β· policy Β· gate reachability Β· the
    RunCertificate Β· infer_permits). Static judgment without the CLI, for
    the embedder/SDK surface (Β§Migration 3 for the import map).

  • run: β€” the run declares its entropy and its clock (F-P3 Β· NEP-0010 Β·
    #711) β€” a new envelope block with two keys: entropy: (ambient Β· none Β·
    { seeded: <n> }) and clock: (system Β· virtual). A declared pair that
    contradicts itself refuses at parse (NIKA-PARSE-026 ambient Γ— virtual Β·
    NIKA-PARSE-027 none|seeded Γ— system), and an entropy: none that
    nevertheless consumes a structural randomness source refuses at check
    (NIKA-PARSE-028). ambient is the default when run: is absent β€” the
    honest status quo, so nothing that ran before changes. Determinism becomes a
    declaration the engine holds you to, not a hope.

  • The run's lifecycle is attested (F-P2 Β· NEP-0011 draft Β· #718) β€” the
    workflow_started prologue becomes a boot manifest (spec_pin Β·
    stamper_kind Β· the resolved clock Β· seed under a determinism demand);
    the run seal's covers extends additively with the folded receipt_digest,
    the consumed budgets and the exercised effects (the classic four-field seal
    stays byte-identical); a journal that never reached a lifecycle-terminal
    frame verifies INCOMPLETE β€” the verifier's finding, never the dying
    run's silence; and a check report stamped with a different semantic hash
    than the booting workflow refuses before the first event (the
    judged-vs-booted binding Β· exit 2 Β· semantic grain).

  • The receipt fortress β€” bounds are code (F-P1 Β· NEP-0012 draft Β· #721) β€”
    the verifier is the one component guaranteed to parse attacker-supplied
    bytes, so its bounds became named constants on every profile: 1 MiB per
    document, a string-aware pre-parse depth scan at 32, proof-bearing arrays at
    64, identifier strings at 256. The chain walk refuses an over-long line
    BEFORE the parse (the new LineOverLong verdict, rendered as a FILE refusal
    by trace verify and an honest refusal by the evidence pack), and the
    anchor sidecar loads through the same door.

  • nika sign Β· nika key Β· run --require-signature (S3 Β· #660 Β· #655) β€”
    workflow author-binding. nika sign <file> mints <file>.minisig
    (--check verifies); nika key is the run-signing key lifecycle (mint Β·
    TOFU fingerprint Β· rotate β€” old public halves stay verifiable); nika run --require-signature refuses an unsigned or invalidly-signed workflow at
    exit 2. Runs emit a signed run_sealed event under run-key custody.

  • nika trace anchor (#665) β€” notarize the journal head OUTSIDE the
    journal: the post-seal head, signed with the run key, submitted to the
    public Sigstore Rekor v2 transparency log plus an RFC 3161 timestamp,
    writing a detached <trace>.anchor.json sidecar. An explicit NETWORK act β€”
    this verb IS the opt-in. nika trace verify now climbs a four-tier ladder
    and reports the highest honestly-attained tier: chain OK Β· SEALED (the
    run_sealed signature verifies against a custody key) Β· ANCHORED (the
    sidecar verifies fully offline) Β· REPLAYED (--replay compares a fresh
    run; verify never re-executes).

  • nika evidence (#662) β€” export the evidence pack for one run: journal +
    manifest + receipt + a VERIFY.md that tells an auditor what to run.

  • The permit-decision witness (F-O6 Β· NEP-0007 Β· #701) β€” every permit
    decision is recorded in the journal, granted and refused alike, so
    trace verify can judge the boundary a run actually rode; and the
    check ⇔ run equivalence oracle proves the two agree. trace_format stays 2
    (the witness rides existing frames Β· no wire bump).

  • MCP tool pinning β€” TOFU + fail-closed drift (#657) β€” a configured MCP
    server that changes its tool definitions after you approved them is the rug
    pull. Per-tool pins (blake3 over a domain-separated canonical pre-image)
    land in .nika/mcp_pins.json (mcp_pins_format: 1) beside a reviewable
    snapshot; first contact enrolls loudly, a match proceeds silently, ANY drift
    fails closed with a diff naming the CHANGED field and returns no tools. A
    hand-edited lockfile is NIKA-MCP-004, never a silent re-TOFU.
    nika mcp approve <server> re-pins after human review.

  • The exec sandbox is wired (ADR-095 L6 Β· #642) β€” permits: jails the
    child (seatbelt on macOS Β· landlock/bubblewrap on Linux), the
    SandboxSpec network arm becomes a tri-state (#658), MCP stdio servers are
    spawned inside the same confinement (#667), and the loopback egress
    proxy
    makes the sandbox's network arm the exact projection of
    permits.net.http (#663 Β· #706 Β· F-P5 Β· NEP-0008).

  • Two new task fields β€” inert: (the declared door for a nika:fetch
    whose payload is data, never code Β· the NIKA-SEC-008 sanction) and
    declassify: (from Β· to Β· because Β· the audited secret-flow
    sanction).

  • Registry client v0.2 signatures (#648) β€” minisign + TOFU on registry
    pulls (NIKA-REG-006 Β· NIKA-REG-007).

  • NIKA-DRIFT-001 β€” declared-but-unused hints in check (#661) β€” a
    declared name or a permits: entry nothing in the body references. Advisory:
    it never fails the audit (the reverse direction, used-but-undeclared, is the
    hard refusal surface).

  • Two new journal event kinds β€” declassify and run_sealed. Additive:
    trace_format stays 2, but a consumer matching the kind vocabulary
    exhaustively must learn them.

  • Spec 17 Β· trace β€” the journal dialect becomes normative in the embedded
    pack (the NDJSON frame grammar chained by sha256, the prologue manifest, the
    closed kind vocabulary), and the pack ships the law + registries JSON
    schemas.

Changed

  • run: declared-pair refusals ride their dedicated mints β€” the
    parse-level entropy Γ— clock contradictions stamp NIKA-PARSE-026 (ambient Γ—
    virtual) and NIKA-PARSE-027 (none | seeded Γ— system), and the check-side
    entropy: none Γ— structural-source judgment stamps NIKA-PARSE-028 β€” was
    the registered generic NIKA-PARSE-019; the NEP-0010 mints landed with the
    87f764a spec pack resync.

  • The lethal-trifecta judge asks a better question (trifecta v2.0 Β·
    NEP-0002 Β· #643) β€” v1.1 asked Β« could this workflow complete the trifecta? Β»
    over the declared capability set. v2.0 asks Β« does untrusted content
    actually REACH an egress? Β», the integrity half of the flow lattice. The
    inversion that matters: an infer:/agent: output carries the taint when
    its prompt saw it β€” a summary of an attacker's page carries the payload.
    v2.0 findings βŠ† v1.1, so nothing that passed before starts failing.

  • permits.tools is enforced at run (#639) β€” the last check-only axis
    closes. A tool call outside the boundary now refuses at dispatch, not only
    at check.

  • NIKA-SEC-005 is core-visible β€” law 5 at every tier (#708) β€” the
    net-egress floor was already emitted by check; only the core-tier
    conformance filter hid it. The core verdict now matches the reference
    oracle.

  • nika trace verify exit 0 means Β« the highest attained tier holds Β» β€”
    the verdict is tiered, not binary (exit 2 broken or forged Β· exit 3
    unchained or a missing input).

  • The embedded spec pack catches up to the spec branch β€” NEP-0004 through
    NEP-0012 land in the pack nika spec serves, along with the 6-namespace
    substitution family, the 25 error namespaces / 96 error codes, and the
    17-provider catalog count.

Fixed

  • A planted symlink can no longer pivot an fs: grant (H2 Β· NEP-0009 Β·
    #710 Β· the CVE-2024-42472 class) β€” the mount-projection arm followed a
    symlinked bind SOURCE where the kernel path-walk arm refuses at open, so an
    upstream task that replaced /ws/data with a link to $HOME/.ssh made a
    later task's fs.read: [/ws/data] bind the wrong tree. Every grant's
    literal prefix is now re-judged as its EFFECTIVE path identity at dispatch,
    before the jail is built: a legitimately-symlinked ANCESTOR is absorbed, the
    final component stays lexical, and an identity that redirects outside the
    judged path is refused before spawn (NIKA-SEC-004) β€” never mounted under
    the judged name, never rewritten to the resolved form. The receipt does not
    lie.

  • A forged CheckReport cannot buy authority (#656 Β· NIKA-1707) β€” the
    runtime re-derives the boundary subset at run start; a clean report over
    different bytes is not clean.

  • Resolved secrets are redacted from the journal, and journals are 0600
    (#640).

  • Pulled model weights are sha256-verified against the Hub's declaration
    (#641).

  • Security-boundary refusals never feed back to the model (#638 Β·
    NIKA-468) β€” a mid-loop refusal is the boundary's word, not another turn's
    context.

  • A required: true input with neither a default: nor a --var refuses
    at admission
    (#674 Β· NIKA-1708) β€” before the DAG spends a task, not
    mid-run.

  • Key trust reads the public half only (#668) β€” no decrypt on the print
    path.

  • The red team's residuals close (#702 Β· #703 Β· #704) β€” four permit edge
    cases, three exec-runner residuals, decode-then-trim, and the finally
    attestation.

  • The taught flow bindings quote their islands (#717) β€” an unquoted
    ${{ }} in a YAML flow mapping is NIKA-PARSE-001; the shipped teaching
    surfaces no longer hand it to you.

Install

brew install supernovae-st/tap/nika          # macOS Β· Linux
curl -LsSf https://nika.sh/install.sh | sh   # script install
docker run --rm ghcr.io/supernovae-st/nika:0.106.0 --version

Tarballs below: macOS arm64 / x64 Β· Linux x64 / arm64, plus SHA256SUMS.

Verify: three independent proofs

# 1 Β· checksum: the bytes you hold are the bytes CI hashed
sha256sum -c SHA256SUMS --ignore-missing     # macOS: shasum -a 256 -c

# 2 Β· attestation: GitHub-signed build provenance for this exact artifact
gh attestation verify nika-<platform>-0.106.0.tar.gz --repo supernovae-st/nika

# 3 Β· SLSA provenance: the intoto asset, verifiable offline
slsa-verifier verify-artifact nika-<platform>-0.106.0.tar.gz \
  --provenance-path multiple.intoto.jsonl \
  --source-uri github.com/supernovae-st/nika --source-tag v0.106.0

Provenance

Built from tag v0.106.0 by release.yml
on GitHub-hosted runners. Provenance is published twice: GitHub's native
build attestation (proof 2) and the SLSA generator's multiple.intoto.jsonl
release asset (proof 3). The release itself is a claim on the
machine-verified timeline: https://nika.sh/timeline

What's Changed

  • chore(public-api): regenerate the nika-onboard baseline (tool skew) by @ThibautMelen in #644
  • fix(nika-runtime): permits.tools enforced at run β€” the last check-only axis closes by @ThibautMelen in #639
  • feat(nika-schema): trifecta v2.0 β€” the realized-flow judge (NEP-0002) by @ThibautMelen in #643
  • fix(nika-verb-agent): security-boundary refusals never feed back to the model by @ThibautMelen in #638
  • fix(nika-runtime): resolved secrets are redacted from the journal Β· journals 0600 by @ThibautMelen in #640
  • fix(nika-models): pulled weights are sha256-verified against the Hub's declaration by @ThibautMelen in #641
  • feat(nika-runtime): the exec sandbox is wired β€” permits: jails the child (ADR-095 L6) by @ThibautMelen in #642
  • feat(nika-registry-client): v0.2 signatures β€” minisign + TOFU (NIKA-REG-006/007) by @ThibautMelen in #648
  • fix(ci): least-privilege tokens + patched deps β€” scorecard palier 1 by @ThibautMelen in #650
  • feat(ci): slsa provenance asset + security insights β€” scorecard palier 2 by @ThibautMelen in #652
  • feat(nika-cli): signed run seals β€” run_sealed event + run-key custody by @ThibautMelen in #655
  • fix(nika-runtime): the runtime re-derives the boundary subset β€” a forged CheckReport cannot pass by @ThibautMelen in #656
  • docs(lineage): the eras return to the public record β€” exploration, brouillon, diamond by @ThibautMelen in #654
  • feat(release): the release front page β€” what Β· install Β· verify Β· provenance by @ThibautMelen in #664
  • feat(nika-mcp): tool pinning β€” TOFU + fail-closed drift (anti-rug-pull) by @ThibautMelen in #657
  • test(nika-runtime): the deterministic adversarial suite β€” F1..F5 + mock hijack by @ThibautMelen in #659
  • feat(nika-cli): declared-vs-used drift hints in check β€” NIKA-DRIFT-001 by @ThibautMelen in #661
  • feat(nika-cli): nika sign + run --require-signature β€” workflow author-binding (S3) by @ThibautMelen in #660
  • feat(nika-kernel-core): SandboxSpec network tri-state β€” deny / allow / allowlist (C11 part 1) by @ThibautMelen in #658
  • refactor(nika-cli,nika-dap): descend the trust plane + drift compute to nika-dap β€” the 15k wall by @ThibautMelen in #666
  • feat(nika-cli): the evidence pack β€” nika evidence exports what an auditor needs by @ThibautMelen in #662
  • feat(nika-exec-runner): the loopback egress proxy β€” sandbox allowlist arm enforced (C11 part 2, srt model) by @ThibautMelen in #663
  • security(nika-mcp): confine spawned stdio servers in the exec OS sandbox by @ThibautMelen in #667
  • chore(deps): Bump the github-actions group across 1 directory with 15 updates by @dependabot[bot] in #653
  • fix(nika-dap): key trust reads the public half only β€” no decrypt on the print path by @ThibautMelen in #668
  • feat(nika-cli): nika trace anchor (Rekor v2 + RFC 3161) + tiered trace verify (OK/SEALED/ANCHORED/REPLAYED) by @ThibautMelen in #665
  • chore(deps): Bump the rust-minor-patch group across 1 directory with 19 updates by @dependabot[bot] in #649
  • chore(deps): Bump syn from 2.0.117 to 3.0.2 by @dependabot[bot] in #619
  • feat(nika-schema): the inputs:/const: flag-day β€” vars dies by @ThibautMelen in #669
  • chore(deps): Bump serde-saphyr from 0.0.23 to 0.0.29 by @dependabot[bot] in #616
  • docs(roadmap): the roadmap rejoins the canon β€” un-numbered next major, no dates, one status truth by @ThibautMelen in #670
  • feat(nika-schema): the R3b TypeExpr widen + NIKA-DEFAULT-001 by @ThibautMelen in #673
  • fix(nika-runtime,nika-cli): the required-input admission preflight β€” refuse before the DAG by @ThibautMelen in #674
  • fix(nika-cli): shed 16 prod LOC β€” the #673Γ—#674 merge crossed the 15k wall by @ThibautMelen in #676
  • feat(nika-vocab,nika-schema,nika-migrate,nika-cli): after: speaks success Β· failure (R5) by @ThibautMelen in #677
  • docs(count-truth): the 42-crate ghost is dead β€” ADR-037's 50-90 horizon, projected counts everywhere by @ThibautMelen in #678
  • test(nika-cli): the wizard PTY colour env is hermetic β€” the macOS flake dies by @ThibautMelen in #679
  • docs(nika-onboard): the authoring floor speaks the four authorities β€” W7 by @ThibautMelen in #680
  • chore(pack): the pack follows the spec β€” resolve #607's held merge (spec 9803e93) by @ThibautMelen in #681
  • chore(deps): phf family 0.13 β†’ 0.14 β€” codegen, shared and runtime phf in lockstep by @ThibautMelen in #682
  • feat(nika-check): the static judgment descends from nika-schema β€” parser there, judgment here by @ThibautMelen in #683
  • feat(nika-runtime,nika-dap,nika-cli): the run-cluster descent β€” compute descends, render stays by @ThibautMelen in #684
  • ci(release): every release opens its thread β€” the announcements door by @ThibautMelen in #672
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #608
  • docs(roadmap): the whole connectome crosses the launch line by @ThibautMelen in #686
  • docs(roadmap): the third pre-condition named β€” the hundred-year machinery by @ThibautMelen in #687
  • docs(readme): the lineage names the rendered record by @ThibautMelen in #688
  • docs(release): the release matrices speak the voice, no em-dash authored by @ThibautMelen in #690
  • feat(permits): absent permits block = zero authority (F-O8) by @ThibautMelen in #691
  • feat(permits): the permit-parameterization taint (F-O1 Β· NEP-0004) by @ThibautMelen in #697
  • feat(permits): the env permit dimension (F-O4 Β· NEP-0005) by @ThibautMelen in #699
  • feat(permits): the data-as-code sink (F-O7 Β· NEP-0006) by @ThibautMelen in #700
  • fix(cap,schema): close the 4 edge cases the red team found by @ThibautMelen in #702
  • fix(exec-runner,cap): close 3 residuals the red team found (rebinding Β· port floor Β· suffixes) by @ThibautMelen in #703
  • feat(runtime+cli): the permit witness Β· trace verify finding Β· the check-run equivalence oracle (F-O6) by @ThibautMelen in #701
  • fix(cap,runtime): the final review's two catches (decode-then-trim + finally attestation) by @ThibautMelen in #704
  • chore(pack): the pack follows the spec by @github-actions[bot] in #705
  • feat(exec-runner,check): the egress proxy is the exact projection of net.http (F-P5) by @ThibautMelen in #706
  • feat(estate): the E0 observation manifest β€” schema 2, the glob estate by @ThibautMelen in #689
  • fix(check): nika-sec-005 is core-visible β€” law 5 at every tier by @ThibautMelen in #708
  • chore(estate): the manifest follows the tree by @ThibautMelen in #709
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #707
  • feat(nika-runtime): the fs permit names an effective path identity (H2 Β· NEP-0009) by @ThibautMelen in #710
  • feat(schema,runtime): the run declares its entropy and clock (F-P3) by @ThibautMelen in #711
  • chore(pack): the pack follows the spec by @github-actions[bot] in #712
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #713
  • chore(pack): the pack follows the spec by @github-actions[bot] in #715
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #716
  • feat(schema,check): the run-decl refusals ride their dedicated mints by @ThibautMelen in #714
  • fix(agents): the taught flow bindings quote their islands by @ThibautMelen in #717
  • feat(runtime,dap,cli): the run lifecycle is attested (F-P2) by @ThibautMelen in #718
  • chore(pack): the pack follows the spec by @github-actions[bot] in #719
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #720
  • feat(nika-dap): the receipt fortress β€” bounds are code (F-P1) by @ThibautMelen in #721
  • chore(estate): the manifest follows the tree by @ThibautMelen in #722
  • chore(spec-pin): the tests leg follows the spec by @github-actions[bot] in #723
  • chore(deps): Bump the github-actions group across 1 directory with 7 updates by @dependabot[bot] in #724
  • chore(deps): Bump atspi from 0.29.0 to 0.30.0 by @dependabot[bot] in #726
  • chore(deps): Bump expectrl from 0.8.0 to 0.9.0 by @dependabot[bot] in #727
  • chore(deps): Bump rstest from 0.22.0 to 0.26.1 by @dependabot[bot] in #728
  • chore(deps): Bump nix from 0.30.1 to 0.31.3 by @dependabot[bot] in #729
  • chore(deps): Bump the rust-minor-patch group across 1 directory with 7 updates by @dependabot[bot] in #730

Full Changelog: v0.105.0...v0.106.0