Skip to content

fix(pr-100): Ossprey review hardening + frontline phases 3–6 - #101

Merged
neomatrix369 merged 8 commits into
mainfrom
fix/pr-100-review
Aug 22, 2026
Merged

fix(pr-100): Ossprey review hardening + frontline phases 3–6#101
neomatrix369 merged 8 commits into
mainfrom
fix/pr-100-review

Conversation

@neomatrix369

@neomatrix369 neomatrix369 commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • Review hardening (PR feat: scanner dispatch extensions + monitoring — phases 3-6 (Ossprey, CLI monitoring, full-chain validation) #100 nw-reviewer report): narrow malware stdout negation regex, claude -p wall-clock timeout in full-chain harness, OSSPREY_API_KEY-only credential gate, scanner timeout budget CI gate, Ossprey binary pin v0.12.0, live CLI reconcile notes on slice 35/36
  • Phase 3: Ossprey malware-scanner adapter — credential-gated, RESEARCH-labeled
  • Phase 4: tripwire status — read-only agent-hook + dispatch observability (slice 37)
  • Phases 5–6: full-chain validation harness + FE/BE target-architecture note
  • docs(slice-44): DIVIO rewrites — vendor procurement table + capability table
  • ci: repo-lint compliance (shellcheck SC2088/SC2015), ruff format on scan_app.py / ossprey tests

Supersedes review gaps called out on PR #100. Coordinate merge with upstream frontline-hack-phases-3-6 to avoid duplicate landings.

Test Results

Backend (sandbox)

  • 234 passed, coverage 97.03% (≥95% gate)
  • Command: uv run pytest sandbox/tests/ --cov=sandbox --cov-fail-under=95

Backend (guard)

  • 111 passed (via pre-commit fast gate on commit)

Frontend (CLI)

  • 138 passed, eslint clean
  • Command: cd cli && npm test && npm run lint

Quality Gates

Check Result
Scanner timeout budget PASS — scripts/check-scanner-timeout-budget.sh
ruff format PASS (fixed in c078806)
mypy (sandbox) PASS
eslint (cli) PASS

Documentation

  • docs/ARCHITECTURE.md — scanner timeout budget table
  • docs/user-guide/env-vars.mdOSSPREY_API_KEY contract
  • Slice stubs 35/36 — live CLI reconcile After-Checks

Checklist

  • ./scripts/quality-gates.sh passes locally (pre-commit fast gate + push hooks on commit)
  • New tests added or updated
  • Docs updated where applicable
  • No secrets or credentials committed

Test plan

Made with Cursor

Complexity

Automatically refreshed by CI for product-code changes.

Scope Tool Result
Python (sandbox/) Radon highest CC 28 (rank D), 258 blocks
CLI (cli/) ESLint 0 function(s) above CC 10
Functions above the JavaScript threshold
  • CLI: no functions exceed cyclomatic complexity 10.

devanshkaria88 and others added 7 commits August 21, 2026 14:35
…SEARCH-labeled (Phase 3)

Second dispatch extension per ADR-0005/ADR-0017, registered after DepShield
in SCANNER_GROUPS (applies_to both):
- run_ossprey: `ossprey scan <workdir> -o <ossbom.json>` subprocess adapter.
  Credential gate FIRST — skipped_missing_credential is the default runtime
  path today (OSSPREY_API_KEY / API_KEY absent; Ossprey access provisioning
  is OPEN, slice 35 BLOCKED). Adapter activates when a key lands.
- Exit-code disambiguation (vendor contract: 0 = clean/skipped, 1 = malware
  OR scan failure): exit 0 is authoritative-clean; nonzero emits red
  'malware' findings ONLY on a positive signal (malicious OSSBOM component,
  or an unambiguous verdict line with negation guard) — a scan failure
  degrades to unreachable, never a phantom red that would block a clean
  artifact. OSSBOM parsing tolerates list and {components|packages:[...]}
  shapes with defensive access.
- RESEARCH evidence label per the module's discipline: OSSBOM schema and
  verdict wording are vendor-doc-sourced, NOT live-probed — needs
  reconciliation against the pinned ossprey-cli before VERIFIED.
- Trust-strip gate deliberately preserved: no Ossprey mention in README/
  QUICKSTART/CONTRIBUTING/STATUS/ARCHITECTURE (no user-usable capability
  yet — "badges only when functionality exists"). Documented instead in
  scanner-output-adapters.md §8, DECISIONS rows, ADR-0017 addendum,
  OPTIONAL_SCANNER_KEYS + env-vars (key marked access-OPEN).
- Modal image: guarded best-effort release-binary install (absent binary
  degrades to unreachable, acceptable while provisioning is OPEN).

Rebased onto post-merge main (PR #83 + slices 40-43). Gates: 232 sandbox
tests @ 97.03% coverage, 111 guard, 129 cli; ruff/mypy/bandit clean; xenon
split ceilings met; trust-strip rg clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ility (Phase 4, slice 37)

CLI monitoring per slice-37's spec (operator observability, extending the
existing CLI — not a second truth store):
- `tripwire status [--json] [--limit <n>]`: hooks state (~/.tripwire/config.json
  enable/validity, PreToolUse registration in ~/.claude/settings.json, Supabase
  monitoring_enabled/threshold, §3 two-switch disagreement warning, and a
  tamper callout when the hook is registered but config.json is missing —
  that state DENIES all matched tools); items heatmap distribution via
  per-status head-counts (immune to PostgREST's 1000-row cap); recent
  scan-run health with fleet-wide stranded-running detection (dedicated
  head-count query, not page-local — a strand older than the newest --limit
  runs is exactly the busy-system case) naming the reconcile remedy;
  per-scanner latest status with unreachable/skipped tallies.
- GWT 2 (enforcement unchanged) proven by test: recorded Supabase calls are
  select-family only (zero insert/update/upsert/delete/rpc), zero fs writes.
- GWT 3: invalid --limit exits nonzero with an actionable example; missing
  Supabase env degrades to local-hooks-only output (exit 0) instead of
  hard-failing observability.
- Docs: user-guide monitoring section + troubleshooting, DECISIONS rows
  (surface choice; Bash-interception explicitly not slice-37 scope — the
  upstream handler already gates skills-path Bash), slice-37 Before-Check
  name-sketch ticked (gate status left PLANNED for maintainer rituals),
  CHANGELOG entry.

Adversarial verify confirmed 1 major (stranded pagination blind spot) +
4 minors (row-cap counts, missing-config understatement, prototype-key
drop, user-scope-only registration claim) — all fixed with regression
tests. Gates: 138 cli tests pass, eslint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ecture note (Phases 5-6, slices 38-39)

Phase 5 (slice 38): scripts/full-chain-validation.sh — staged checklist with
a single accountable result (exit 0 only when every required stage passes):
preflight, credentials, hooks-installed, demo-artifacts, scan-dispatch,
verify-status, depshield-dispatch, ossprey-dispatch, cli-monitoring, and a
LIVE /tw-self-check stage invoked via `claude -p` (never mocked, output
captured into evidence) per the slice-38 GWTs and the original SEQUENCE-13
expectation. `ossprey-dispatch: SKIPPED(access)` is explicit while slice 35
remains BLOCKED. Stages needing Supabase/Modal creds report BLOCKED(.env)
honestly; degraded-mode run verified on this machine (evidence JSON written
to .test-results/full-chain-evidence.json; gate evidence stays a maintainer
ritual — the script never fabricates it).

Phase 6 (slice 39): deferred by default per the slice's own spec (Could,
hackathon-too-large). Deliverable is docs/research/fe-be-target-architecture.md:
current three-plane boundary map, the two pressures worth solving on pull-in
(single-implementation six-state machine; anon read path to retire the
client-side service-role key), and pinned non-goals.

DECISIONS rows recorded for both; slice files left at maintainer-owned
gate states.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…chain harness, escaped pipes in a DECISIONS table row

- scripts/full-chain-validation.sh: interpolate $CONFIG_JSON instead of a
  quoted tilde path (SC2088); move `|| true` outside the command
  substitutions so the A && B || C pattern disappears (SC2015)
- docs/plan/DECISIONS.md: escape regex pipes in the slice-37 HOOK_MATCHER
  code span — raw pipes split the markdown table cells (MD056/MD038)

Verified locally via `uvx pre-commit run --all-files`: shellcheck,
markdownlint, actionlint, gitleaks, ruff(+format), mypy, bandit, xenon,
vulture, pylint, pytest-testmon, CLI node tests + ESLint all pass. The
eslint-dashboard hook fails only locally (dashboard node_modules not
installed on this machine); untouched by this branch and green on main CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ability table

env-vars: Vendor procurement quick-steps converted from procedural numbered
steps to a reference table (Vendor → Keys → Setup guide link). Step-by-step
account creation stays in vendor setup pages per the file's own preamble.

prerequisites: Capability-specific notes collapsed from narrative Explanation
prose to a 4-row reference table (Capability → Requires). Removes the
procedural 'Copy .env.example...' steps and 'Create a disposable project...'
instructions that contradict the Reference doc type.

Both were pre-existing DIVIO purity violations flagged by nw-documentarist
review (2026-08-21) and resolved here per DECISIONS row (APPROVED WITH
FOLLOW-ON, same-branch rewrite).
…lidation harness

Harden malware stdout parsing, cap live self-check wall clock, enforce OSSPREY_API_KEY-only gating, and add scanner timeout budget CI guard before Ossprey activation.
@github-actions

github-actions Bot commented Aug 22, 2026

Copy link
Copy Markdown

code-review-graph review

Overall risk: 0.60 (MEDIUM) — 103 changed function(s)/class(es), 3 affected flow(s), 49 test gap(s)

Risk-scored changes

Risk Level Symbol Location Tested
0.60 medium cli/src/statusCommand.js::isTripwireHookCommand cli/src/statusCommand.js:47 no
0.59 medium cli/src/statusCommand.js::isStranded cli/src/statusCommand.js:170 no
0.55 medium cli/src/statusCommand.js::h cli/src/statusCommand.js:61 no
0.54 medium cli/src/statusCommand.js::run cli/src/statusCommand.js:223 no
0.45 medium cli/src/statusCommand.js::runStatus cli/src/statusCommand.js:353 no
0.40 medium cli/src/statusCommand.js::unwrap cli/src/statusCommand.js:95 no
0.40 medium cli/src/statusCommand.js::twoSwitchDisagreement cli/src/statusCommand.js:234 no
0.40 medium scripts/full-chain-validation.sh::record scripts/full-chain-validation.sh:30 no
0.35 low cli/src/statusCommand.js::parseLimit cli/src/statusCommand.js:32 no
0.35 low cli/src/statusCommand.js::isPlainObject cli/src/statusCommand.js:42 no

Affected execution flows

  • scan_item — criticality 0.35, 14 node(s) across 2 file(s)
  • h — criticality 0.32, 2 node(s) across 1 file(s)
  • run — criticality 0.24, 2 node(s) across 1 file(s)

Test gaps

  • cli/src/statusCommand.js::parseLimit (cli/src/statusCommand.js:32)
  • cli/src/statusCommand.js::isPlainObject (cli/src/statusCommand.js:42)
  • cli/src/statusCommand.js::isTripwireHookCommand (cli/src/statusCommand.js:47)
  • cli/src/statusCommand.js::readHookRegistration (cli/src/statusCommand.js:54)
  • cli/src/statusCommand.js::entry (cli/src/statusCommand.js:60)
  • ...and 44 more without direct tests

Token savings: this graph-backed report used ~69,099 fewer tokens (~83%) than reading every changed file in full (estimated, chars/4 approximation).


Powered by code-review-graph — local-first analysis; no code leaves the CI runner.

@neomatrix369 neomatrix369 changed the title feat(sandbox): Ossprey malware-scanner adapter — credential-gated, RESEARCH-labeled (Phase 3) fix(pr-100): Ossprey review hardening + frontline phases 3–6 Aug 22, 2026
@neomatrix369
neomatrix369 merged commit c078806 into main Aug 22, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants