|
1 | 1 | // SPDX-License-Identifier: PMPL-1.0-or-later |
| 2 | +// Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
2 | 3 | = polysafe-gitfixer — Show Me The Receipts |
3 | 4 | :toc: |
4 | 5 | :icons: font |
| 6 | +:author: Jonathan D.A. Jewell |
5 | 7 |
|
6 | | -The README makes claims. This file backs them up. |
| 8 | +The README makes claims. This file backs them up, traces the critical paths, |
| 9 | +and tells a reviewer exactly where to look. |
| 10 | + |
| 11 | +== Claim 1: Capability-Based Security With Tamper-Evident Audit Log |
| 12 | + |
| 13 | +[quote, README] |
| 14 | +____ |
| 15 | +A polyglot implementation of a git backup merger tool, where each component is |
| 16 | +written in the language that provides the strongest safety guarantees for that |
| 17 | +component's concerns. |
| 18 | +____ |
| 19 | + |
| 20 | +*How it works:* |
| 21 | +The Rust `capability` crate (`crates/capability/`) is the security foundation |
| 22 | +for the entire tool. It exposes two primitives, documented in `src/lib.rs`: |
| 23 | + |
| 24 | +`DirCapability` — an unforgeable path-restriction token. Created from a root |
| 25 | +directory, it canonicalises the root at creation time. Every subsequent |
| 26 | +`resolve(relative_path)` call verifies the result is still under the canonical |
| 27 | +root, returning `CapabilityError::PathTraversal` if it escapes. Capabilities can |
| 28 | +also be *attenuated*: a write-capable token can spawn a read-only sub-token for |
| 29 | +a nested directory. The `Permissions` bitmask (`read`, `write`, `delete`) is |
| 30 | +checked before each operation. This makes CWE-22 (path traversal) structurally |
| 31 | +impossible — not just checked. |
| 32 | + |
| 33 | +`AuditLog` — a cryptographic ledger. Each `LogEntry` is chained to the SHA-256 |
| 34 | +hash of the previous entry, so any deletion or reordering of entries is |
| 35 | +detectable by re-hashing the chain. Operations are typed via the `Operation` enum. |
| 36 | + |
| 37 | +The crate is `#![forbid(unsafe_code)]`. |
| 38 | + |
| 39 | +*Honest caveat:* |
| 40 | +The hash-chaining in `AuditLog` uses the `ring` crate for SHA-256. Formal |
| 41 | +verification (SPARK) of the chaining invariant is listed in `PROOF-NEEDS.md` |
| 42 | +but has not been written yet. The current guarantees are runtime, not |
| 43 | +proof-level. |
| 44 | + |
| 45 | +== Claim 2: Polyglot Orchestration — Each Component in Its Strongest Language |
7 | 46 |
|
8 | 47 | [quote, README] |
9 | 48 | ____ |
10 | 49 | We welcome contributions! See link:CONTRIBUTING.adoc[CONTRIBUTING] for: |
| 50 | +the Tri-Perimeter Contribution Framework (TPCF), development setup instructions, |
| 51 | +code style guidelines, and how to submit merge requests. |
11 | 52 | ____ |
12 | 53 |
|
| 54 | +*How it works:* |
| 55 | +The five-layer architecture assigns each concern to the language with the |
| 56 | +strongest guarantee for that concern: |
| 57 | + |
| 58 | +- **Rust** (`crates/capability/`, `crates/fs_ops/`, `crates/git_ops/`) — memory |
| 59 | + safety and RAII for filesystem and git operations. |
| 60 | +- **Haskell** (`haskell/diff-engine/`, `haskell/tui/`) — totality checking for |
| 61 | + the diff engine; Brick Elm Architecture for exhaustive TUI event handling. |
| 62 | +- **Elixir/OTP** (`elixir/`) — OTP supervision trees for fault isolation; if |
| 63 | + the diff engine crashes, the supervisor restarts only that worker. |
| 64 | +- **Idris 2** (`idris/`) — dependent types enforce typestate: the workflow |
| 65 | + state machine makes it a compile-time error to call `merge` before `diff`. |
| 66 | +- **Nickel** (`config/`) — schema-validated configuration; type contracts fire |
| 67 | + at `nickel eval` time, before the binary starts. |
| 68 | + |
| 69 | +Rust NIFs expose the capability and FS operations to Elixir via `crates/polysafe_nifs/` |
| 70 | +(Rustler). End-to-end integration tests live in `crates/polysafe_e2e/`. |
| 71 | + |
| 72 | +*Honest caveat:* |
| 73 | +The Haskell and Idris 2 components are further behind than the Rust crates. |
| 74 | +The TUI (`haskell/tui/`) compiles but is not wired to the Elixir orchestrator |
| 75 | +yet. The Idris 2 typestate machine (`idris/`) compiles but is not yet called |
| 76 | +from Elixir. Integration is the primary remaining work. |
| 77 | + |
| 78 | +== Dogfooded Across The Account |
| 79 | + |
| 80 | +[cols="2,3,1"] |
| 81 | +|=== |
| 82 | +| Repo / System | How polysafe-gitfixer is used | Status |
| 83 | + |
| 84 | +| `hypatia` (CI) | The `DirCapability` pattern is the reference implementation for safe path handling in Hypatia rule plugins | Reference |
| 85 | +| `robot-repo-automaton` | Planned: use polysafe-gitfixer to safely merge backup branches during automated repo fixes | Planned |
| 86 | +| Developer workflow | Intended for managing the hundreds of `*-backup` branches that accumulate during agentic sessions | Intended |
| 87 | +| `gitbot-fleet` | sustainabot and echidnabot may call polysafe-gitfixer NIFs for safe backup pruning | Design stage |
| 88 | +|=== |
| 89 | + |
13 | 90 | == File Map |
14 | 91 |
|
15 | | -[cols="1,2"] |
| 92 | +[cols="1,3"] |
16 | 93 | |=== |
17 | 94 | | Path | What's There |
18 | 95 |
|
19 | | -| `test(s)/` | Test suite |
| 96 | +| `crates/capability/src/lib.rs` | **Critical path.** Exposes `DirCapability`, `AuditLog`, `Permissions`, `CapabilityError` |
| 97 | +| `crates/capability/src/dir_capability.rs` | `DirCapability` implementation: canonicalisation, path-traversal prevention, attenuation |
| 98 | +| `crates/capability/src/audit_log.rs` | Hash-chained `AuditLog` ledger; `LogEntry`, `Operation`, `IntegrityError` |
| 99 | +| `crates/fs_ops/src/` | Transactional filesystem operations (atomic moves, rollback on failure) |
| 100 | +| `crates/git_ops/src/` | Git repository operations via `git2-rs` |
| 101 | +| `crates/polysafe_nifs/src/` | Rustler NIFs exposing Rust crates to Elixir/OTP |
| 102 | +| `crates/polysafe_e2e/src/` | End-to-end integration test suite |
| 103 | +| `haskell/diff-engine/` | Streaming tree/file diff engine (Haskell, totality-checked) |
| 104 | +| `haskell/tui/` | Terminal UI (Haskell, Brick framework, Elm Architecture) |
| 105 | +| `idris/` | Idris 2 workflow typestate machine; enforces correct operation ordering |
| 106 | +| `elixir/` | OTP orchestrator and supervision tree; supervises all worker processes |
| 107 | +| `config/` | Nickel configuration schemas with type contracts |
| 108 | +| `test/` | Cross-language integration tests |
| 109 | +| `PROOF-NEEDS.md` | Formal verification backlog for this repo |
| 110 | +| `Justfile` | Build recipes: `just build`, `just rust`, `just haskell`, `just elixir`, `just test` |
| 111 | +| `flake.nix` / `guix.scm` | Reproducible environment (includes GHC, Idris2, Elixir, Rust) |
| 112 | +| `contractiles/` | Contractile trust/dust/intend check files |
| 113 | +| `.machine_readable/6a2/` | A2ML state, meta, ecosystem, agentic, neurosym, playbook manifests |
20 | 114 | |=== |
21 | 115 |
|
22 | 116 | == Questions? |
|
0 commit comments