Skip to content

Commit 27f7b1f

Browse files
audit: classify Track C panic-attack findings (#138) (#271)
## Summary Triages all 8 panic-attack Track C findings from the 2026-05-26 estate sweep. Creates \`audits/assail-classifications.a2ml\` (ephapax did not yet have this audit registry — sister boj-server has had one since the FFI sweep #154 / #155). | File:line | Category | Classification | Why | |---|---|---|---| | flake.nix | SupplyChain | legitimate-template-scaffold | Dormant placeholder flake (\`{project-description}\`, \`*REMINDER:*\`), no workflow consumes it. Pinning before activation is premature — activate-then-pin should be one PR. | | ephapax-package/src/registry.rs:98 | UnboundedAllocation | legitimate-user-config-file | Reads local registry index — user's own \`.ephapax/registry/index.json\` | | ephapax-package/src/registry.rs:261 | UnboundedAllocation | legitimate-local-hash-walk | Inside \`compute_directory_hash\`; reads files this process just wrote to disk | | ephapax-package/src/manifest.rs:130 | UnboundedAllocation | legitimate-user-manifest | Reads user's own \`ephapax.toml\` | | ephapax-repl/src/lib.rs:170 | UnboundedAllocation | legitimate-repl-load-command | REPL \`:load <path>\` — interactive user input | | ephapax-cli/src/main.rs:245 (+ 257, 327) | UnboundedAllocation | legitimate-cli-arg-path | CLI arg path read; standard CLI tool pattern | | ephapax-cli/src/import_resolver.rs:125 (+ 195) | UnboundedAllocation | legitimate-project-source | Import resolver reading project source files | | ephapax-tools/src/formatter.rs:311 (+ documenter.rs:211) | UnboundedAllocation | legitimate-cli-source-input | \`ephapax fmt\` / \`ephapax doc\` reading user-supplied paths | ## Sister-issue parallelism Same template + vocabulary as boj-server#155 (merged 2026-06-01 11:31Z) so cross-repo audit summaries read fluently. Same trust-boundary reasoning ports cleanly: - \`legitimate-user-config-file\` (registry.rs:98) ≈ \`legitimate-user-config-file\` (tray/src/server.rs:130 in boj-server#155) - The flake.nix branch in both — but boj-server's flake.lock IS present (\`legitimate-flake-lock-pinned\`) while ephapax's flake.nix is template-scaffold (\`legitimate-template-scaffold\`). ## Test plan - [x] String-aware paren balance check on the new a2ml file (62 = 62) - [ ] CI parses the new file (whatever a2ml-validation workflow ephapax runs) - [x] Spot-check each cited line in the live source Closes #138 Refs hyperpolymath/panic-attack#32, hyperpolymath/boj-server#155 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c9a893a commit 27f7b1f

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

audits/assail-classifications.a2ml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
;; SPDX-License-Identifier: PMPL-1.0-or-later
2+
;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
;;
4+
;; Assail Classifications — ephapax
5+
;; See panic-attack/.claude/CLAUDE.md § "User-Classification Registry".
6+
7+
(assail-classifications
8+
(metadata
9+
(version "1.0.0")
10+
(project "ephapax")
11+
(last-updated "2026-06-01")
12+
(entries 8)
13+
(status "active"))
14+
15+
;; ─────────────────────────────────────────────────────────────────
16+
;; Track C — 8 findings from the 2026-05-26 panic-attack estate
17+
;; sweep (#138 / panic-attack#32). All 8 triaged 2026-06-01 — none
18+
;; require code changes today. Each entry below records *why*, so a
19+
;; future sweep on the same line does not require re-investigation.
20+
;; Parallel triage of boj-server#155 (sister issue, same campaign).
21+
;; ─────────────────────────────────────────────────────────────────
22+
23+
(classification
24+
(file "flake.nix")
25+
(category "SupplyChain")
26+
(classification "legitimate-template-scaffold")
27+
(audit "ephapax#138 (2026-06-01)")
28+
(rationale "ephapax's flake.nix is dormant scaffolding — it still carries the placeholder `description = \"ephapax - {project-description}\"` and `*REMINDER:* Update inputs` comments, and no workflow (`abi-verify.yml`, `boj-build.yml`, `rust-ci.yml`, etc.) invokes `nix develop`/`nix-shell`/`nix build`. There is no `flake.lock` to pin against because nothing consumes the flake. Pinning a flake whose only purpose is template-future use would be premature; activate-then-pin should be one PR. Re-classify to a real-finding if/when the flake is wired into CI."))
29+
30+
(classification
31+
(file "src/ephapax-package/src/registry.rs")
32+
(line 98)
33+
(category "UnboundedAllocation")
34+
(classification "legitimate-user-config-file")
35+
(audit "ephapax#138 (2026-06-01)")
36+
(rationale "`std::fs::read_to_string(&index_path)` where index_path is the local package-registry index (user's own `.ephapax/registry/index.json` or equivalent). Owned by the user; not attacker-controlled remote input. Same trust-boundary classification as boj-server#155's tray/src/server.rs:130 prefs.json pattern."))
37+
38+
(classification
39+
(file "src/ephapax-package/src/registry.rs")
40+
(line 261)
41+
(category "UnboundedAllocation")
42+
(classification "legitimate-local-hash-walk")
43+
(audit "ephapax#138 (2026-06-01)")
44+
(rationale "`std::fs::read(&path)` inside `compute_directory_hash` (BLAKE3 / SHA-256 of a registry directory tree). `path` comes from a `fs::read_dir` walk of files the registry installer just wrote locally — same machine, same process, written moments earlier. Bounded by the registry's own writes."))
45+
46+
(classification
47+
(file "src/ephapax-package/src/manifest.rs")
48+
(line 130)
49+
(category "UnboundedAllocation")
50+
(classification "legitimate-user-manifest")
51+
(audit "ephapax#138 (2026-06-01)")
52+
(rationale "`std::fs::read_to_string(path)` reads the user's own `ephapax.toml` (or analogous) manifest. Manifests are project-local files the user authored. CLI tooling assumes the user is not trying to OOM their own machine; if they wrote a 4GB manifest they have bigger problems."))
53+
54+
(classification
55+
(file "src/ephapax-repl/src/lib.rs")
56+
(line 170)
57+
(category "UnboundedAllocation")
58+
(classification "legitimate-repl-load-command")
59+
(audit "ephapax#138 (2026-06-01)")
60+
(rationale "REPL `:load <path>` command — reads a path the user just typed into their own interactive REPL. The REPL is an interactive single-user environment; the path is whatever the user typed. No remote attacker surface."))
61+
62+
(classification
63+
(file "src/ephapax-cli/src/main.rs")
64+
(line 245)
65+
(category "UnboundedAllocation")
66+
(classification "legitimate-cli-arg-path")
67+
(audit "ephapax#138 (2026-06-01)")
68+
(rationale "`fs::read_to_string(&path)` reads a file path the user passed as a CLI argument. Standard CLI tool pattern: trust the user to point at sensible files. Same applies to lines 257 and 327 in the same file — all three are CLI-arg path reads."))
69+
70+
(classification
71+
(file "src/ephapax-cli/src/import_resolver.rs")
72+
(line 125)
73+
(category "UnboundedAllocation")
74+
(classification "legitimate-project-source")
75+
(audit "ephapax#138 (2026-06-01)")
76+
(rationale "Import resolver reads `.eph` source files from the user's project tree during import-graph construction. Paths come from `import` statements in the user's own source files (which the user just wrote and pointed the resolver at). Bounded by the project's own source-file inventory. Line 195 in the same file is the same pattern."))
77+
78+
(classification
79+
(file "src/ephapax-tools/src/formatter.rs")
80+
(line 311)
81+
(category "UnboundedAllocation")
82+
(classification "legitimate-cli-source-input")
83+
(audit "ephapax#138 (2026-06-01)")
84+
(rationale "`std::fs::read_to_string(path)` reads a source file the formatter was asked to format — typically via `ephapax fmt path/to/file.eph` or `ephapax fmt .`. User-supplied path to user-owned source. The companion finding in `src/ephapax-tools/src/documenter.rs:211` (`ephapax doc path/to/file.eph`) is the same pattern."))
85+
)

0 commit comments

Comments
 (0)