fix(security): Track C cleanup — closes #99#115
Merged
Conversation
Addresses the 23 Critical/High panic-attack findings tracked at
idaptik#99. Mix of real refactors, intentional-use classifications,
and stale-doc cleanup.
## What changed
### UnsafeDeserialization × 7 → 1 refactor + 3 source classifications
The one real fix:
- `src/app/screens/BalanceAnalyserModel.res:217` — was raw
`JSON.parseExn(jsonStr)->JSON.Classify.classify`; now wraps in
`SafeJson.parse` (`Result<JSON.t, ProvenError.provenError>`-returning)
with an `Error(_) => empty` arm. Malformed report JSON now degrades to
the empty record instead of throwing into the host (escape-hatch /
PanLL panel).
The three intentional uses, classified in
`audits/assail-classifications.a2ml`:
- `src/app/proven/SafeJson.res:32` — IS the canonical safe-parse wrapper
(try/catch around `parseExn`; returns `Result`). The finding here is
what the fix above consumes.
- `vm/lib/ocaml/benchmark.res:139` — benchmark-fixture measuring raw
parser throughput against a hardcoded valid JSON string. SafeJson would
measure try/catch overhead, wrong instrument.
- `lib/ocaml/SafeJson.res` — build-mirror of the source-side SafeJson.
The remaining lib/ mirrors of BalanceAnalyserModel.res auto-regenerate
on the next ReScript compile (the BS- and lib-mirror copies pick up the
new `SafeJson.parse` shape).
### DynamicCodeExecution × 2 → 2 classifications
Vite-emitted bundles in `main-game/dist/assets/`:
- `index-Cdt-JTFK.js` (SPA bootstrap)
- `webworkerAll-DNs-UuZS.js` (web-worker bundle)
Both classified as `compiled-output`. DOM manipulation / dynamic-script
patterns are inherent to SPA + web-worker initialisation, not
user-controlled execution. Filenames are content-hashed → entries will
need refreshing when the bundles rotate. Tracked as a follow-up.
### ExcessivePermissions × 1 → tightened invocation + doc cleanup
- `Justfile`: `just run` and `just run-full` recipes now use the scoped
permission set instead of `--allow-all`:
`deno run --allow-read=. --allow-env --allow-run=deno,git,which,xdg-open,open,start --allow-net=127.0.0.1 run.js`
- `run.js`: header comment + `--help` output rewritten to document the
scoped invocation as canonical; `--allow-all` is now explicitly NOT
recommended in the header.
- The residual `--allow-all` mention in the discouragement text is
classified as `documentation-mention-only` in
`audits/assail-classifications.a2ml` so the static analyzer doesn't
flag the warning text itself.
Per-API audit captured inline in the run.js header:
- `--allow-read=.`: Deno.readTextFile + Deno.stat on tree-relative paths
- `--allow-env`: Deno.env.get + Deno.env.toObject for child-env passthru
(narrowing requires rewriting the passthrough to a whitelist — tracked)
- `--allow-run=...`: spawns deno/git/which + platform browser opener
- `--allow-net=127.0.0.1`: Deno.listen({port}) probing only (loopback)
### HardcodedSecret × 12 → no change
All 12 are already classified `game-content-fixture` in
`assail-classifications.a2ml` from PR #112's S-expr→TOML conversion.
Re-verified during this PR; no additions needed.
## Out of scope (follow-ups noted)
- Refresh `main-game/dist/assets/` exact-hash classifications on each
release rebuild, OR gitignore `main-game/dist/` and let CI regenerate.
- Narrow `--allow-env` in run.js by rewriting `Deno.env.toObject()`
child-env passthrough to a whitelist (currently passes the whole env).
## Closes
closes #99
Signed-off-by: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com>
🔍 Hypatia Security ScanFindings: 71 issues detected
View findings[
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in build-validation.yml",
"type": "missing_timeout_minutes",
"file": "build-validation.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in cflite-pr.yml",
"type": "missing_timeout_minutes",
"file": "cflite-pr.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in containers.yml",
"type": "missing_timeout_minutes",
"file": "containers.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in containers.yml",
"type": "missing_timeout_minutes",
"file": "containers.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dco.yml",
"type": "missing_timeout_minutes",
"file": "dco.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
3 tasks
hyperpolymath
added a commit
that referenced
this pull request
Jun 1, 2026
…tion, changelog (#117) ## Summary A multi-subagent audit of idaptik's human-readable and machine-readable documentation against the actual repo state on 2026-06-01 surfaced several stale counts, broken paths, and missing classifications. This PR brings the canonical docs back in sync. ## Human-readable corrections | File | What was wrong | Now | |---|---|---| | `README.adoc` | "Idris2 (15 modules)" + "Zig (12 exports)" | "17 in `idaptik-ums/src/abi/` + 1 in `src/abi/Types.idr`" + "11 source files, 12 C-ABI exports" | | `EXPLAINME.adoc` | Same counts; root `src/abi/Types.idr` undocumented in the file map | Same corrections + file-map entry for the root main-game ABI module | | `PROOF-NEEDS.md` | Path `src/abi/*.idr` was right for one file, missed the 17 UMS modules entirely; no layer classification | Full L1/L2/L3/L4 classification + echo-types verdict recorded | | `PANIC-ATTACK-ANALYSIS-SUMMARY.md` | Looked authoritative but dated 2026-03-20, well before the 2026-05-26 panic-attack re-scan + the PR #115 cleanup | Marked as historical baseline pending re-run after PR #115 lands | ## Machine-readable corrections `0-AI-MANIFEST.a2ml`: | Key | Was | Now | Reason | |---|---|---|---| | `dev-port` | `8080` | `1984` | Matches `vite.config.js` `server.port: 1984, strictPort: true`. Playwright config also corrected in PR #114 to align with this. | | `escape-hatch` (canonical-location) | `escape-hatch/` | `idaptik-developers/src/escape-hatch/` | The top-level path was a phantom — escape-hatch only lives under `idaptik-developers/src/`. Confirmed via repo tree walk. | | `modding-studio` | `Tauri 2 (idaptik-ums)` | `Gossamer (idaptik-ums) — Ephapax-based webview shell; replaced Tauri` | Matches `.machine_readable/6a2/STATE.a2ml` line 13 which already recorded the Tauri → Gossamer pivot. | | Tier-0 ref to `.claude/CLAUDE.md` | Listed in `[context-tiers]` | Removed | File does not exist in the repo (404 from gh api). | ## Provenance `CHANGELOG.md` had no entry for any 2026-04, 2026-05, or 2026-06 work — last entry was 2026-03-14. Backfilled the 2026-06-01 block covering PR #112 (baseline sweep), PR #114 (Playwright fundamental fix), PR #115 (Track C security cleanup), issue #116 (idaptik-ums .res corruption), and the echo-types audit. Future sessions inherit this as the seam. ## Echo-types audit Per the 2026-06-01 owner directive "every proof in ephapax (and any sibling repo with an echo-types link) must first audit `hyperpolymath/echo-types`, reuse if applicable… L1/L4-only obligations audit-and-record-as-not-relevant": - 17 Idris2 modules in `idaptik-ums/src/abi/` + 1 root `src/abi/Types.idr` + ProvenBridge.idr's dependency on `proven` — all classified - 17 modules L1 (region-local validation, entity placement, IP-reference integrity, level-data invariants); 1 module L4 (`Multiplayer.idr` — asymmetric co-op via enums + records, no temporal echo claims); zero L3 - Zero hits for "echo"/"Echo" in idaptik codebase; zero echo-types links in the `proven` dependency surface idaptik uses - **Verdict: RECORD-AS-NOT-RELEVANT** — recorded in PROOF-NEEDS.md so future sessions don't re-derive the audit ## Subagent reports backing this PR - `a22e2f5` — docs truthfulness audit (14 files surveyed) - `aa58c61` — idaptik-ums `.res` corruption sweep (10/11 corrupt; filed as #116) - `af5fac9` — cross-estate idaptik reference audit (3 stale refs identified) - `a0b4a4e` — echo-types layer classification (per-module verdict above) ## No risk to LIVE This PR only touches documentation files. No code, no CI workflow, no `rescript.json`/`deno.json`/`vite.config.js`. Builds and tests are not affected. ## Test plan - [x] All 6 files committed are GPG-signed + DCO-signed-off - [x] `git diff` confirms only doc files modified - [ ] No required-check regression (all 16 required-on-main checks should pass — only doc changes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses the 23 Critical/High panic-attack findings tracked at #99. Mix of one real refactor, four intentional-use classifications, and an ExcessivePermissions tighten + doc cleanup.
HardcodedSecretgame-content-fixtureinassail-classifications.a2mlfrom PR #112's S-expr→TOML conversion — re-verified, no additions neededUnsafeDeserializationBalanceAnalyserModel.res→SafeJson.parse) + 3 source-level classifications (canonical wrapper, benchmark fixture, build mirror) — remaining lib/ mirrors auto-regenerateDynamicCodeExecutioncompiled-output(Vite-emitted SPA bootstrap + web-worker bundle) — content-hashed filenames will need refreshing on rotationExcessivePermissionsJustfilerecipes +run.jsheader to a scoped permission set; onedocumentation-mention-onlyclassification covers the residual --allow-all warning textThe one real refactor
src/app/screens/BalanceAnalyserModel.res:217was rawJSON.parseExn(jsonStr)->JSON.Classify.classify— a malformed balance report file would throw into the host (escape-hatch / PanLL panel). Now wrapped inSafeJson.parse(returnsResult<JSON.t, ProvenError.provenError>); theError(_)arm degrades cleanly toempty.deno task res:buildstill compiles 0 errors after the change.ExcessivePermissions tighten
Justfile:Per-API audit (now captured inline in
run.jsheader):--allow-read=.—Deno.readTextFile+Deno.staton tree-relative paths (node_modules, lib/bs, dist)--allow-env—Deno.env.get(...)for WAYLAND_DISPLAY/DISPLAY +Deno.env.toObject()to propagate env into spawneddeno task dev/deno task dev:all. Narrowing this requires rewriting the child-env passthrough to a whitelist — tracked as follow-up.--allow-run=deno,git,which,xdg-open,open,start—Deno.Commandspawns ofdeno,git,which, + platform browser openers--allow-net=127.0.0.1—Deno.listen({port})port-probing for Vite port + fallbacks (loopback only)Out-of-scope follow-ups (called out in commit body)
main-game/dist/assets/exact-hash classifications on each release rebuild, OR gitignoremain-game/dist/and regenerate per CI--allow-envby rewritingDeno.env.toObject()passthrough to an explicit whitelistCloses
closes #99
Test plan
deno task res:buildexit 0 after the SafeJson refactor (3 modules compiled, 0 errors)panic-attack assailre-run shows 0 Critical / 0 High in idaptik (post-merge)just runandjust run-fullsmoke-test launch the game with the tightened permissions🤖 Generated with Claude Code