Skip to content

Commit d024a9e

Browse files
hyperpolymathclaude
andcommitted
docs: record user-classification registry + Rocq scaffold classifier
CHANGELOG.md: Unreleased section captures the two 2026-04-18 features (classification registry + Rocq scaffold classifier), the pipeline change, test coverage, and the 007-end verified drop from 8 active findings to 0. .claude/CLAUDE.md: ProofDrift bullet updated with the Rocq-specific refinement (Section-awareness + module-level `Parameter` classifier); new "User-Classification Registry" section documents the file format, lookup paths, public API, pattern intent, and cites 007 as the reference implementation. No code changes — purely authoritative documentation for the 315917b + 6d6822a features shipped this week. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 315917b commit d024a9e

2 files changed

Lines changed: 83 additions & 1 deletion

File tree

.claude/CLAUDE.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,44 @@ Three self-contained modes — none requires the others:
178178
## v2.5.0 Detection Categories (COMPLETE — 25 categories total)
179179

180180
All five detection categories shipped in v2.5.0 (2026-04-12):
181-
- **ProofDrift (PA021)**: Proof escape hatches in Isabelle/Coq/Lean/Agda/Idris2; Julia mirror patterns; Obj.magic in Coq-extracted OCaml (distinguished from hand-written via `type __ = Obj.t` marker)
181+
- **ProofDrift (PA021)**: Proof escape hatches in Isabelle/Coq/Lean/Agda/Idris2; Julia mirror patterns; Obj.magic in Coq-extracted OCaml (distinguished from hand-written via `type __ = Obj.t` marker). Rocq-specific refinement (2026-04-18): the detector is Section-aware (`Variable`/`Hypothesis`/`Parameter` inside a `Section ... End` are discharged, not counted) and classifies module-level `Parameter` declarations by stated type (carrier types, decidability witnesses, non-Prop function symbols are abstractions; Prop-valued remains counted). See `count_rocq_unverified_postulates` in `src/assail/analyzer.rs`.
182182
- **CryptoMisuse (PA022)**: Weak hash (MD5/SHA-1) in security context; timing-unsafe == on secrets; JWT sig bypass — `dangerous_insecure_decode` (Rust), `ParseUnverified` (Go), `verify_signature:False`/`algorithms=["none"]` (Python), `jwt.decode` without `jwt.verify` / `decodeJwt` without `jwtVerify` (JS)
183183
- **SupplyChain (PA023)**: Unpinned deps, absent lock files, unverified manifests
184184
- **InputBoundary (PA024)**: Unchecked CBOR/MessagePack (Rust), JSON.parse without try-catch (JS/Julia)
185185
- **MutationGap (PA025)**: No cargo-mutants config (Rust), all-type-only assertions (Julia), no property testing (Elixir)
186186

187+
## User-Classification Registry (2026-04-18)
188+
189+
Optional project-local classification file that flips audited findings
190+
to `suppressed = true` after the kanren structural-suppression pass:
191+
192+
- Path: `<project>/audits/assail-classifications.a2ml` (preferred) or
193+
`<project>/.panic-attack-classifications.a2ml` (fallback).
194+
- Format (A2ML S-expression):
195+
```
196+
(assail-classifications
197+
(classification
198+
(file "crates/foo/src/bar.rs")
199+
(category "UnsafeCode")
200+
(audit "audits/audit-ffi-unsafe.md §1")
201+
(rationale "one-line summary")))
202+
```
203+
- Public API: `UserClassification`, `load_user_classifications(root)`,
204+
`apply_user_classifications(&mut report, root)` in `src/assail/mod.rs`.
205+
- Called automatically by `analyze()` / `analyze_verbose()` after
206+
`apply_suppression`.
207+
208+
**Pattern intent**: the registry lives in a separate file from the
209+
source under scan, so adding a new unsafe block cannot self-suppress —
210+
the registry edit is a reviewable companion change. This keeps
211+
suppressions non-gameable by single-side edits while still letting
212+
repositories record honest audits of legitimate-FFI and other
213+
genuinely-sound residuals.
214+
215+
**Reference implementation**: `hyperpolymath/007`
216+
`audits/assail-classifications.a2ml` (cross-references
217+
`audits/audit-ffi-unsafe.md §1` for `zig_bridge.rs` UnsafeCode).
218+
187219
## Integration Points
188220

189221
- **panicbot**: gitbot-fleet verifier bot — invokes `panic-attack assail --output-format json`, translates WeakPoints to Findings (PA001-PA025). Directives at `.machine_readable/bot_directives/panicbot.scm`

CHANGELOG.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
# Changelog
22

3+
## [Unreleased] — 2026-04-18
4+
5+
### Added
6+
- **User-classification registry** (`assail::UserClassification`,
7+
`load_user_classifications`, `apply_user_classifications`): panic-attack
8+
now reads an optional project-local classification file at every assail
9+
pass and flips matching findings to `suppressed = true` after the kanren
10+
structural-suppression pass. Two lookup paths:
11+
- `<project_root>/audits/assail-classifications.a2ml` (preferred)
12+
- `<project_root>/.panic-attack-classifications.a2ml` (fallback)
13+
File format is a simple A2ML S-expression with `(classification (file …)
14+
(category …) (audit …) (rationale …))` blocks; `;;` line comments
15+
ignored. The registry pattern lets repositories record audited findings
16+
out-of-band from the source under scan so a PR adding a new unsafe
17+
block cannot self-suppress without a reviewable companion edit to
18+
the registry.
19+
- **Rocq scaffold classifier** (`analyze_coq` +
20+
`count_rocq_unverified_postulates` + `is_rocq_abstraction_parameter`):
21+
the Rocq detector no longer counts Section-scoped `Variable` /
22+
`Hypothesis` / `Parameter` declarations (they discharge at `End
23+
Section`) and classifies module-level `Parameter` declarations by
24+
stated type: carrier types (`Type`, `Set`), decidability witnesses
25+
(`forall _, { _ = _ } + { _ <> _ }`), and function types with a
26+
concrete non-Prop codomain are treated as abstraction parameters.
27+
Prop-valued declarations (classical excluded-middle, choice,
28+
unresolved theorem statements) remain counted. Removes the
29+
false-positive stream that surfaced on every canonical-proof-suite
30+
scaffold.
31+
32+
### Changed
33+
- **Suppression pipeline**: `analyze()` and `analyze_verbose()` now
34+
chain `apply_suppression``apply_user_classifications` in that
35+
order; the explicit post-analyze calls in `assail::analyze` and
36+
`assail::analyze_verbose` at the module boundary are retained for
37+
API-contract clarity but are no-ops when an `Analyzer` pass has
38+
already run.
39+
- **Rocq test coverage**: 12 new unit tests across `analyzer.rs`
40+
(Section-scoped Variables / module-level Type carriers / decidable
41+
equality / concrete-codomain functions / Prop-valued axioms /
42+
missing type annotation / full scaffold shape — 7 tests) and
43+
`mod.rs` (missing-registry / single-entry / multiple-entry /
44+
comment handling / end-to-end suppression-flip — 5 tests).
45+
46+
### Verified
47+
- 007 canonical-proof-suite scan: active finding count **8 → 0**
48+
(the 6 scaffold ProofDrifts via the detector enhancement, the 2
49+
`zig_bridge.rs` UnsafeCode findings via the classification registry
50+
pointing at `audits/audit-ffi-unsafe.md §1`). No in-source
51+
suppression markers added to either repo.
52+
353
## [2.5.0] - 2026-04-12
454

555
### Added

0 commit comments

Comments
 (0)