Skip to content

Commit 007c7c2

Browse files
Dashboard-vs-STATE CI gate + Phase B (CNO-law proptest, delete legacy tree, honest obliteration) (#81)
Two threads of estate-honesty work in januskey. All changes build clean and are test-verified. ## Thread 1 — `dashboard-check`: make "dashboards that lie" a build failure New Rust workspace crate `crates/dashboard-check` (Rust = policy-preferred CLI language) that reads the machine-readable **source of truth** (`.machine_readable/6a2/STATE.a2ml`) and fails CI when a hand-maintained dashboard diverges from it — the structural fix for the estate's #1 recurring defect (the historical `TOPOLOGY.md` "100% Production Ready" vs `STATE.a2ml` 60%/Grade-D). - `a2ml` is TOML, so it parses with the `toml` crate (no bespoke reader). Extracts `completion-percentage` / `crg-grade` / `last-updated` (tolerating januskey's quoted `"60"`/`"D"` and other repos' bare integers); asserts they match `TOPOLOGY.md` (`OVERALL: …%`, `Grade X`) and `READINESS.md` (`CRG Grade: X`), and that the dashboard isn't older than STATE. - **8 unit tests** (quoted+bare parsing, every drift class, aligned-pass, and a prose-shadowing regression). - **Verified end-to-end:** passes on this repo; catches an injected 100%-vs-60% drift with the exact `completion mismatch` message. - Wired as `just check-dashboard` + CI job **Dashboard Check** (SPDX header, `contents: read`, SHA-pinned actions). Prototyped here; designed to be vendored estate-wide. ## Thread 3 — Phase B honesty/tests - **B5 — runnable reversibility evidence.** A property test asserting the CNO round-trip law `execute∘undo ≡ identity` on the filesystem, across all supported operations over random content (temp tree + stores, snapshot → execute → undo with a fresh executor → assert byte-for-byte restored). The honest substitute for the "formal proofs pending" badge. Chown excluded (undo unimplemented); tests the filesystem effect, not the deliberately non-involutive `OperationType::inverse`. - **B2 — delete the legacy `src/januskey/` monolith** (non-workspace, pre-extraction duplicate of `crates/januskey-cli`, labelled LEGACY). Every reference repointed (README, ARCHITECTURE, EXPLAINME, docs/wiki, `idrisiser/*.tsig`); the two contractile checks that scanned it simplified (they already preferred `crates/januskey-cli`). `src/abi/*.idr` (Idris ABI) untouched. No dangling references remain. - **B8 — stop overstating obliteration.** The doc-comment claimed content is "cryptographically unrecoverable"; overwrite-in-place can't guarantee physical erasure on SSD/CoW/journaling media (the caveat already lived in `threat-model.a2ml`). Mirrored that honest wording into `obliteration.rs` and softened the README claim, with the obliteration exception called out. ## Verification - `cargo build --workspace` — clean. - `cargo test -p januskey --lib` — **26 passed**; `--test property_tests` — **4 passed** (incl. the new CNO-law case); `cargo test -p dashboard-check` — **8 passed**. - `dashboard-check --check .` — green on this repo; clippy clean on the new crate. ## Context Threads 1 & 3 of a three-thread follow-up (Lean mirror merged in #110; this is the januskey pair). Draft pending human review. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz --- _Generated by [Claude Code](https://claude.ai/code/session_015qwVESTcbfanY2iJPQNoSz)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 65e1376 commit 007c7c2

35 files changed

Lines changed: 649 additions & 7230 deletions
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# dashboard-check.yml — fail the build when a hand-maintained status dashboard
5+
# (TOPOLOGY.md / READINESS.md) diverges from the machine-readable STATE.a2ml.
6+
# Structural defence against the "dashboards that lie" failure mode.
7+
name: Dashboard Check
8+
9+
on:
10+
pull_request:
11+
branches: ['**']
12+
push:
13+
branches: [main, master]
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
dashboard-check:
20+
name: STATE vs dashboard reconciliation
21+
runs-on: ubuntu-latest
22+
timeout-minutes: 15
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
26+
27+
- uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
28+
29+
- name: Reconcile dashboards against STATE.a2ml
30+
run: cargo run -q -p dashboard-check -- --check .

.machine_readable/contractiles/Adjustfile.a2ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Standard: WCAG-2.2-AA (CLI/TUI profile).
7777

7878
### panic-pattern-drift
7979
- description: No regression of the 2026-04 unwrap()/expect("TODO") sweeps in security-critical modules
80-
- tolerance: 0 new bare unwrap() in crates/*/src and src/januskey/src
80+
- tolerance: 0 new bare unwrap() in crates/*/src
8181
- corrective: Run `just assail` (panic-attacker pre-commit scan)
8282
- severity: advisory
8383

.machine_readable/contractiles/Trustfile.a2ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ unjustified, it has no place here. Trust never overrides MUST.
117117
# OR the file does not exist. Fails while the home-rolled pattern is present.
118118
if [ -f crates/januskey-cli/src/attestation.rs ]; then \
119119
! grep -qE 'Sha256::new\(\).*update.*key.*update.*data' crates/januskey-cli/src/attestation.rs; \
120-
elif [ -f src/januskey/src/attestation.rs ]; then \
121-
! grep -qE 'Sha256::new\(\).*update.*key.*update.*data' src/januskey/src/attestation.rs; \
122120
else true; fi
123121
- severity: critical
124122

@@ -129,7 +127,7 @@ unjustified, it has no place here. Trust never overrides MUST.
129127
# Passes if ed25519-dalek or x25519-dalek is a real dependency, OR if
130128
# Ed25519 / X25519 are not listed in any KeyAlgorithm enum.
131129
cargo tree 2>/dev/null | grep -qE '(ed25519-dalek|x25519-dalek)' || \
132-
! grep -rqE '(Ed25519|X25519)' crates/januskey-cli/src/ src/januskey/src/ 2>/dev/null
130+
! grep -rqE '(Ed25519|X25519)' crates/januskey-cli/src/ 2>/dev/null
133131

134132
## Secrets-hygiene (memory rule: SOPS at-rest / Rokur runtime / RGTV LLM-broker)
135133

ARCHITECTURE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ januskey/
4242
│ ├── delta — Differential operations
4343
│ ├── main — jk CLI binary
4444
│ └── keys_cli — jk-keys CLI binary
45-
46-
└── src/januskey/ ← LEGACY (pre-extraction, superseded by crates/)
4745
```
4846

4947
## reversible-core: The Shared Foundation

Cargo.lock

Lines changed: 93 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell
33

44
[workspace]
5-
members = ["crates/reversible-core", "crates/januskey-cli"]
5+
members = ["crates/reversible-core", "crates/januskey-cli", "crates/dashboard-check"]
66
resolver = "2"
77

88
[workspace.package]

EXPLAINME.adoc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ The README makes claims. This file backs them up.
1010

1111
=== Claim 1: "100% Reversible - Every operation can be undone, always"
1212

13-
**How it works:** JanusKey implements architectural reversibility by storing inverted operations alongside each mutation. The delete operation, implemented in `src/januskey/src/obliteration.rs`, calculates and stores a full restoration record before removing file content. The `delta.rs` module generates inverse metadata that sufficient to reconstruct the pre-operation state. Every operation in the transaction layer (`src/januskey/src/metadata.rs`) maintains a "prior state" record, enabling perfect reversal through the `undo` pathway.
13+
**How it works:** JanusKey implements architectural reversibility by storing inverted operations alongside each mutation. The delete operation, implemented in `crates/januskey-cli/src/obliteration.rs`, calculates and stores a full restoration record before removing file content. The `delta.rs` module generates inverse metadata that sufficient to reconstruct the pre-operation state. Every operation in the transaction layer (`crates/januskey-cli/src/metadata.rs`) maintains a "prior state" record, enabling perfect reversal through the `undo` pathway.
1414

1515
**Caveat:** Reversibility is strong only when the operation log remains intact. If `.jk/` metadata store is corrupted or lost, recovery becomes impossible. The system trades **write amplification** (each operation doubles metadata I/O) for guaranteed recoverability.
1616

17-
**Evidence:** `src/januskey/src/lib.rs` (public API) delegates to `obliteration.rs` and `delta.rs` for operation logic; see `Reversible` trait (if present) or reversibility-proof comments in `attestation.rs`.
17+
**Evidence:** `crates/januskey-cli/src/lib.rs` (public API) delegates to `obliteration.rs` and `delta.rs` for operation logic; see `Reversible` trait (if present) or reversibility-proof comments in `attestation.rs`.
1818

1919
=== Claim 2: "Complete Audit Trail - Every change tracked automatically"
2020

21-
**How it works:** The metadata store (`src/januskey/src/metadata.rs`) maintains an append-only operation log. The `attestation.rs` module calculates cryptographic commitments (SHA256 hashes) of each operation, creating a tamper-evident chain. Content-addressed storage (`src/januskey/src/content_store.rs`) ensures deduplication by content hash, preventing duplicate storage while maintaining full history.
21+
**How it works:** The metadata store (`crates/januskey-cli/src/metadata.rs`) maintains an append-only operation log. The `attestation.rs` module calculates cryptographic commitments (SHA256 hashes) of each operation, creating a tamper-evident chain. Content-addressed storage (`crates/januskey-cli/src/content_store.rs`) ensures deduplication by content hash, preventing duplicate storage while maintaining full history.
2222

2323
**Caveat:** The audit trail is only as trustworthy as the append-only mechanism. If the log is truncated or rewritten on-disk, the chain breaks. For forensic-grade auditing, integrate with an external append-only store (database, blockchain).
2424

25-
**Evidence:** `src/januskey/src/metadata.rs` defines the log structure; `attestation.rs` computes cryptographic bindings; `content_store.rs` handles SHA256 hashing.
25+
**Evidence:** `crates/januskey-cli/src/metadata.rs` defines the log structure; `attestation.rs` computes cryptographic bindings; `content_store.rs` handles SHA256 hashing.
2626

2727
== Technology Choices
2828

@@ -41,15 +41,15 @@ The README makes claims. This file backs them up.
4141
|===
4242
| Path | Purpose
4343

44-
| `src/januskey/src/main.rs` | CLI entry point, command dispatch (delete, modify, move, copy, undo, begin, commit, rollback, preview)
45-
| `src/januskey/src/lib.rs` | Public API: init, delete, modify, move, copy, undo, transaction logic
46-
| `src/januskey/src/obliteration.rs` | Delete operation with restoration metadata
47-
| `src/januskey/src/delta.rs` | Computes inverse operations (modify undo, move undo, copy undo)
48-
| `src/januskey/src/metadata.rs` | Append-only operation log, transaction tracking, rollback state
49-
| `src/januskey/src/content_store.rs` | SHA256 content hashing, deduplication, storage management
50-
| `src/januskey/src/attestation.rs` | Cryptographic commitments, audit trail, tamper detection
51-
| `src/januskey/src/keys.rs` | Cryptographic key management (if key-based reversibility)
52-
| `src/januskey/src/error.rs` | Error types and propagation
44+
| `crates/januskey-cli/src/main.rs` | CLI entry point, command dispatch (delete, modify, move, copy, undo, begin, commit, rollback, preview)
45+
| `crates/januskey-cli/src/lib.rs` | Public API: init, delete, modify, move, copy, undo, transaction logic
46+
| `crates/januskey-cli/src/obliteration.rs` | Delete operation with restoration metadata
47+
| `crates/januskey-cli/src/delta.rs` | Computes inverse operations (modify undo, move undo, copy undo)
48+
| `crates/januskey-cli/src/metadata.rs` | Append-only operation log, transaction tracking, rollback state
49+
| `crates/januskey-cli/src/content_store.rs` | SHA256 content hashing, deduplication, storage management
50+
| `crates/januskey-cli/src/attestation.rs` | Cryptographic commitments, audit trail, tamper detection
51+
| `crates/januskey-cli/src/keys.rs` | Cryptographic key management (if key-based reversibility)
52+
| `crates/januskey-cli/src/error.rs` | Error types and propagation
5353
|===
5454

5555
== Dogfooted Across The Account

Justfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ fmt:
3131
lint:
3232
cargo clippy --workspace -- -D warnings
3333

34+
# Fail if a hand-maintained dashboard diverges from STATE.a2ml (source of truth)
35+
check-dashboard:
36+
cargo run -q -p dashboard-check -- --check .
37+
3438
# Run benchmarks
3539
bench:
3640
cargo bench --workspace

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ pending).
3838

3939
- **Instant Rollback** - Undo changes in milliseconds
4040

41-
- **Data loss impossible by construction** - the architectural goal the
42-
pending proofs are to establish
41+
- **Data loss resistant by construction** - reversibility is the
42+
architectural goal the pending proofs are to establish. (Note: *secure
43+
obliteration* is the deliberate exception and is best-effort only —
44+
overwrite-in-place cannot guarantee physical erasure on SSD/CoW/journaling
45+
media; see the threat model.)
4346

4447
- **Complete Audit Trail** - Every change tracked automatically
4548

@@ -51,8 +54,7 @@ pending).
5154

5255
```bash
5356
# Build from source (requires Rust)
54-
cd src/januskey
55-
cargo build --release
57+
cargo build --workspace --release
5658

5759
# Initialize JanusKey in your project
5860
jk init
@@ -125,10 +127,10 @@ Every operation stores sufficient metadata for perfect inversion:
125127
```bash
126128
# Clone the repository
127129
git clone {url-github}
128-
cd januskey/src/januskey
130+
cd januskey
129131

130132
# Build release binary
131-
cargo build --release
133+
cargo build --workspace --release
132134

133135
# Install to PATH
134136
cargo install --path .

TOPOLOGY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
5757
> CRG grade **D**) and `READINESS.md` (Grade **D — Alpha, Unstable**). This
5858
> dashboard is a human-readable summary of those files; if they disagree,
5959
> they win. Percentages below are qualitative, not measured coverage.
60+
> This agreement is now **machine-enforced**: `just check-dashboard`
61+
> (crate `crates/dashboard-check`, CI job `Dashboard Check`) fails the build
62+
> if the `OVERALL` percentage or grade here drifts from STATE.a2ml.
6063
6164
```
6265
COMPONENT STATUS NOTES

0 commit comments

Comments
 (0)