v0.106.0
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-schemaat 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 wholenika checkladder (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> }) andclock:(systemΒ·virtual). A declared pair that
contradicts itself refuses at parse (NIKA-PARSE-026ambient Γ virtual Β·
NIKA-PARSE-027none|seeded Γ system), and anentropy: nonethat
nevertheless consumes a structural randomness source refuses at check
(NIKA-PARSE-028).ambientis the default whenrun: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_startedprologue becomes a boot manifest (spec_pinΒ·
stamper_kindΒ· the resolvedclockΒ·seedunder a determinism demand);
the run seal'scoversextends additively with the foldedreceipt_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 newLineOverLongverdict, rendered as a FILE refusal
bytrace verifyand 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
(--checkverifies);nika keyis the run-signing key lifecycle (mint Β·
TOFU fingerprint Β· rotate β old public halves stay verifiable);nika run --require-signaturerefuses an unsigned or invalidly-signed workflow at
exit 2. Runs emit a signedrun_sealedevent 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.jsonsidecar. An explicit NETWORK act β
this verb IS the opt-in.nika trace verifynow climbs a four-tier ladder
and reports the highest honestly-attained tier: chain OK Β· SEALED (the
run_sealedsignature verifies against a custody key) Β· ANCHORED (the
sidecar verifies fully offline) Β· REPLAYED (--replaycompares a fresh
run; verify never re-executes). -
nika evidence(#662) β export the evidence pack for one run: journal +
manifest + receipt + aVERIFY.mdthat 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 verifycan judge the boundary a run actually rode; and the
check β run equivalence oracle proves the two agree.trace_formatstays 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 isNIKA-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
SandboxSpecnetwork 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 anika:fetch
whose payload is data, never code Β· theNIKA-SEC-008sanction) 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 incheck(#661) β a
declared name or apermits: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 β
declassifyandrun_sealed. Additive:
trace_formatstays 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 thelaw+registriesJSON
schemas.
Changed
-
run:declared-pair refusals ride their dedicated mints β the
parse-level entropy Γ clock contradictions stampNIKA-PARSE-026(ambient Γ
virtual) andNIKA-PARSE-027(none | seeded Γ system), and the check-side
entropy: noneΓ structural-source judgment stampsNIKA-PARSE-028β was
the registered genericNIKA-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: aninfer:/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.toolsis 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-005is core-visible β law 5 at every tier (#708) β the
net-egress floor was already emitted bycheck; only the core-tier
conformance filter hid it. The core verdict now matches the reference
oracle. -
nika trace verifyexit 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 packnika specserves, 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/datawith a link to$HOME/.sshmade a
later task'sfs.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
CheckReportcannot 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: trueinput with neither adefault:nor a--varrefuses
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 thefinally
attestation. -
The taught flow bindings quote their islands (#717) β an unquoted
${{ }}in a YAML flow mapping isNIKA-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 --versionTarballs 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.0Provenance
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