171 Commits
Author SHA1 Message Date
Violin 56dc0f359b config: compress later (0.40/0.35) to reduce mid-run compaction loss
Run 10 stalled mid-compaction and runs 11-13 compacted mid-run, losing
probe context. threshold 0.25 -> 0.40 (compress at 40% of context limit,
doc default is 0.50) and target_ratio 0.30 -> 0.35 (preserve more recent
tail). Judge/compression stay on the main model.
2026-08-13 19:19:09 +01:00
Violin 538d8eb908 config: raise agent max_turns 350->700, add goals.max_turns 40
Run 13 hit the 350-iteration budget mid-vuln-research and was force-closed
before EXPLOITATION (PTT 1/4, 0% formalized). The baked profile config
inherits max_turns into the agent iteration cap. Doubling it plus a 40-turn
goal continuation budget lets exploitable challenges get reached.
2026-08-13 19:06:46 +01:00
Violin abf8e001ca test: normalize coverage-matrix fixture literal formatting 2026-08-13 17:59:04 +01:00
Violin cd18b6aefe docs(coverage): canonical findings must be independently decisive
Run 20260813_160102 scored 11/20 while run 152147 scored 16/20 on
identical code; the delta is canonization quality. FIND records that were
one-line pointers (no route, no specific field, no quoted proof) failed the
scorer's decisive-finding contract even when the vuln was real and proven
in evidence/. State the contract: substantive, exact METHOD/route, named
field, observable outcome, quoted proof, Impact+Remediation.
2026-08-13 17:57:52 +01:00
Violin 7e09291b23 docs(coverage): demand full response bodies in proof bundles
Run 20260813_152147 reached 16/20 but dropped referral-abuse and
no-rate-limiting to 'no decisive proof' — probes ran correctly but saved
only %{http_code} tails and bare status lines. Explicit rule: never save
only a status code; a confirmed vector's proof must include the response
body demonstrating it (credit balance for referral, no-429 summary for
rate-limit absence).
2026-08-13 17:00:30 +01:00
Violin 7a0a0f89ae docs(coverage): teach systematic probes for persistent-miss vectors
- redirects-unvalidated.md: systematic open-redirect probe loop (17 params,
  Location-header capture, external-redirect follow, allowlist-substring bypass)
- auth-bypass.md: when to run default/weak creds (after user-enum finds admin;
  hand-testable set is not brute force)
- xss.md: URL-valued fields (avatar/link) as stored/blind XSS vectors
- business-logic.md: referral self-referral registration recipe (register A,
  refer B, check both sides for credit)
- exhaustive-coverage.md: mandatory auth/registration-flow coverage step so
  the routing triggers no matter which playbook the agent reads first

No benchmark names or session inventory; generic OWASP technique only.
2026-08-13 15:57:05 +01:00
Violin df475ea4a8 docs(coverage): document state/coverage-matrix.yaml schema in exhaustive-coverage.md
Runs 1-2 of the rebuilt-image set both forced guard-code reads on the
VULN_RESEARCH coverage gate: the flat-key schema and per-status proof
rules existed only in ptt_handlers.py. The reference now documents the
exact schema (flat top-level keys, tested/not_applicable/blocked with
evidence-path requirements, obligation matching), per the agent's own
prevention suggestion in framework_feedback.md.
2026-08-13 13:39:01 +01:00
Violin 4fc6e0c22b fix(guard): coverage-gate error teaches remediation per cell status
Run 20260813_101504 burned ~15 min and 19 close attempts on the
undispositioned-coverage gate: the error listed failures without naming
the fix, so the agent flailed (even reading guard source) and wrote
invalid reasons ('evidence: none else'). The error now spells out the
exact remediation per cell status (tested/not_applicable/blocked/missing).
2026-08-13 12:31:41 +01:00
Violin 704c1fd594 chore(playbooks): remove trailing blank lines 2026-08-13 12:17:57 +01:00
Violin 625ca927c0 chore(guard): rename receipt key env var to drop benchmark reference
VIOLIN_BENCHMARK_RECEIPT_KEY -> VIOLIN_RECEIPT_KEY. The all-caps
'BENCHMARK' slipped past the original case-sensitive de-cheat grep in
plugins/violin_guard. No consumers hardcode the literal; all use the
RECEIPT_KEY_ENV constant.
2026-08-13 10:40:39 +01:00
Violin ec37bea859 chore(playbooks): de-reference benchmark challenge names in nosql notes 2026-08-13 10:36:37 +01:00
Violin bbf69fca6f chore(playbooks): drop stale unread last_updated metadata blocks (ssti/xss/sqli) 2026-08-13 10:36:12 +01:00
Violin e319facc9a chore(playbooks): strip benchmark challenge-inventory footnotes (9 files) 2026-08-13 10:34:38 +01:00
Violin c38a5ea323 fix(guard): heartbeat message nudges context compaction
Run 20260812_204014 died at 27m with HTTP 402 prompt-token limit
(141557 > 99922): the agent executed 328 tool calls without ever
compacting, cutting exploitation short (12/20, 8 challenges never
probed). The heartbeat now reminds the agent to compact when the run
has executed many commands.
2026-08-12 22:11:12 +01:00
Violin e30a5b8973 fix(run): closeout goal links Validated hypotheses to FIND files
Run 184313's agent canonized findings but never wrote the forward
'Linked findings' board field, so the scorer lost the confirmations.
The closeout goal now permits bookkeeping-only updates: link each
Validated hypothesis to its FIND-*.md via violin_record_hypothesis.
No new testing, findings, or evidence re-verification allowed.
2026-08-12 21:34:17 +01:00
Violin a82c1dfd86 fix(score): confirm findings via reverse hypothesis links
Run 20260812_184313 scored 0/20 formalized despite 7 FIND files and 8
Validated hypotheses: the agent canonized findings carrying 'Linked
Hypothesis: H-00N' but never wrote the forward 'Linked findings' board
field (it closed PT-102 by editing state/ptt.md directly, bypassing the
record_ptt handler gates). The scorer now:

- parse_findings extracts reverse 'Linked Hypothesis' references
- validated_challenge_ids falls back to reverse links / shared evidence
  when a Validated hypothesis has no forward links
- paper trail is unchanged: Validated hypothesis + substantive finding
  over real evidence, in either direction

Re-scoring 184313: formalized 0% -> 30% (6 confirmed). Regression test
test_validated_hypothesis_confirms_via_find_reverse_link added.
2026-08-12 21:32:56 +01:00
Violin 723e349291 fix(guard): scope online-research gate to the exploited hypothesis
- check_command now accepts hypothesis_id (schema + handler + args)
- Exploit-phase research gate checks only the named hypothesis when
  provided; otherwise all candidates (previous behavior)
- Error message names the remediation tool: violin_record_hypothesis
  id=H-00N cve_research=... exploit_research=...
- Fixes silent bypass: normalized id comparison (002 vs 2) so an
  unresearched hypothesis is actually blocked
- New test: named-hypothesis passes, unresearched H-002 blocked,
  all-candidates mode still enforces full rows
2026-08-12 18:52:42 +01:00
Violin 46bad5c1a8 refactor(guard): de-benchmark production code; route-level coverage obligations
- Remove challenge_ids seeding (vulnerability-name leak) from scope;
  seed engagement.coverage_obligations (client-style in-scope endpoints)
  + generic engagement.audit_mode flag instead
- plugins/violin_guard now contains zero benchmark/run-id references;
  gates are framework-owned and audit-mode-gated
- Cross-engagement guard blocks ANY foreign engagement dir, not just
  benchmark-run-*
- Anti-cheat regression test asserts no vuln names in generated scope
2026-08-12 07:09:51 +01:00
Violin 61e3ed8b61 fix(guard): coverage completeness — every scored challenge needs an evidence-backed matrix cell 2026-08-11 20:20:07 +01:00
Violin b84cd852f2 fix(guard): accept business-logic vuln classes; surface review_batch sync-credit recovery in denial 2026-08-11 20:16:08 +01:00
Violin 5355ff1b68 fix(guard): review-block curl -s without status capture so receipts are decisive 2026-08-11 19:43:26 +01:00
Violin f593b359ae fix(score): count FIND-confirmed findings in technical proof union; cap formalization <=100% 2026-08-11 19:36:35 +01:00
Violin 132e6f7c9a fix(guard): require Validated hypotheses to link canonical FIND files at VULN_RESEARCH close 2026-08-11 18:24:32 +01:00
Violin 9a40ec645c fix(guard): block rejections that never ran their cheapest discriminating test 2026-08-11 17:57:02 +01:00
Violin f04116377e docs(changelog): condense 3.1.0 entry to tight bullet summary 2026-08-11 17:11:04 +01:00
Violin 6b2bc26af3 fix(benchmark): seed engage brief, close phase-skip loophole, evidence-backed coverage 2026-08-11 17:09:35 +01:00
Violin b8262d585d feat(guard): record-as-you-go recency gate — hard block on deferred bookkeeping
The advisory contract rule was not enough: flash-class agents defer
hypothesis/coverage/PTT writes to closeout, then reconstruct results from
conversation memory after compression — the false-positive factory.

check_hypothesis_freshness now hard-blocks further target commands when the
newest execution evidence is newer than the hypothesis board's last update
(15 min grace for burst timing). The agent MUST record the batch result via
violin_record_hypothesis before proceeding. Bursts preflight all commands
before any executes, so no mid-burst false blocks.

Also fixes a silent test-suite gap: tests/__init__.py and the four
subpackage __init__.py files were missing, so 171 integration tests
(incl. test_plugin_guard.py which pins freshness behavior) NEVER ran.
Suite went from 248 passed / 7 collection errors to 419 passed, 0 errors.
2026-08-11 13:46:53 +01:00
Violin 119e0c1600 feat(guard): friction auto-logs at block time + record-as-you-go contract
Agent was deferring framework feedback and state writes to closeout, then
reconstructing what happened from conversation memory after compression —
the exact mechanism that fabricates false positives.

- Guard now self-logs: _check_command_internal appends a Guard Block/Review
  row to state/framework_feedback.md at the moment check_command rejects a
  command (only when the file exists, i.e. benchmark engagements; no-op
  otherwise). Friction is captured with zero agent bookkeeping.
- SKILL.md Operational Contract: 'Record as you go' — after EVERY
  violin_review_batch, immediately update hypothesis board + coverage matrix
  + PTT in the same turn; never batch state writes to closeout, never
  reconstruct tests from memory. State files are the only source of truth.
- 5 new tests: block-row append, no-op without file/errors, dedupe, pipe
  escaping.

243 tests pass, ruff clean.
2026-08-11 13:41:51 +01:00
Violin e0b3cea379 fix(benchmark): curl-form endpoint matching + decisive discriminators
- _method_route_in_text now accepts '-X POST <url>' reproduction commands
  (quoted URLs no longer break the match) — recovers referral-abuse
- coupon-100-discount: decisive patterns (INTERNAL100 / 'discounted to $0')
  kill the false positive from a neg-qty finding whose checkout sent
  coupon_code:null
- weak-admin-creds: decisive patterns (DefaultCredentials / admin:password)
  stop mass-assign role-granted text from confirming it
- vuln-research playbook + hypothesis template: mandate 1:N Linked findings
  (an unlinked FIND file scores 0 even with perfect evidence)

Calibration still 20/20 + 0/0. Latest run re-scored: 6/20, now all true
positives (false coupon + false creds removed, referral recovered).
2026-08-11 13:03:47 +01:00
Violin 5c83ee3fdc fix(benchmark): closeout must finalize, not re-run; friction log benchmark-scoped
- _engagement_needs_closeout no longer fires on leftover unchecked PTT rows:
  a single '[ ]' task marker triggered a continuation pass that re-ran the
  entire assessment (255 msgs / 20m50s) instead of closing out. Closeout is
  now gated on the artifacts the scorer consumes (FIND files + report.md +
  retrospective.md) only.
- Closeout goal rewritten to be surgical: assessment is COMPLETE, evidence is
  final, no new tests/scans/verification, no evidence modification; only
  generate missing report/retrospective (prefer generate-closeout) and update
  PTT statuses.
- Friction-log instruction moved out of the general pentest SKILL.md (it is a
  benchmark-only artifact) into the benchmark goal prompt so the agent
  actually sees it.
- New pinned tests: leftover-PTT-row closeout detection, closeout-goal
  wording.
2026-08-10 21:23:54 +01:00
Violin ddffe9cccc fix(benchmark): engagement start stamp in local time, not UTC
datetime.now(UTC) made benchmark-run-<ts> dirs and started_at an hour
early on UTC+1 hosts. Use local wall-clock time for the run stamp.
2026-08-10 21:05:28 +01:00
Violin bbc2d93a63 feat(guard): generated closeout artifacts + framework-owned methodology
- generate-closeout CLI derives findings.yaml and report.md from canonical
  FIND-NNN.md files; agent closeout reduced to executive-summary narrative
- Per-finding recording cut from 4 surfaces to 2 (hypothesis + FIND)
- New skills/pentest/references/exhaustive-coverage.md mandated from SKILL.md;
  Operational Contract (SKILL.md S7) and Citation Discipline (evidence ref S8)
- Benchmark goal/closeout prompts reduced to task + integrity constraint

Tests: 233 passed (7 new); live-verified against real Aug 10 run (10/10
findings, ids+severities match hand-written original).
2026-08-10 20:52:10 +01:00
Violin 3807d22eaa fix(benchmark): evidence-gated scorer contract, false-positive discriminators, runner validity
- Confirm Validated hypotheses via canonical FIND-NNN.md matched in live-app
  terms (METHOD + endpoint route) alongside execution bundles
- require/require_any discriminators for shared-endpoint challenges;
  absence-type scoring for no-rate-limiting
- Runner: closeout timeout is a soft warning, not run invalidation
- ai_judge: whitelist legitimate closeout artifacts in schema-drift audit
- Align version surfaces to 3.1.0; move pyyaml to runtime deps

Calibration: known-good 20/20, known-bad 0/0. Latest run re-scored 4 -> 9.
2026-08-10 20:52:02 +01:00
Violin a3326c2ed4 merge: topic branches for eval score verification 2026-08-10 08:57:12 +01:00
Violin 48a4f214d6 feat(guard): add receipt integrity verifier, fail-closed state parsers, and guard runtime tests 2026-08-10 08:54:56 +01:00
Violin 48119a64cf feat(benchmark): implement proof verifier, AI judge refinements, and duck-store calibration evidence 2026-08-10 08:54:35 +01:00
Violin 1e1971aa6a feat(skills): update pentest playbooks, recon methodologies, and scope templates 2026-08-10 08:54:23 +01:00
Violin 7ca3c0b6c5 chore: remove whitespace from benchmark config 2026-08-08 13:30:33 +01:00
Violin d41aec7457 fix(guard): stabilize engagement path resolution 2026-08-08 13:29:11 +01:00
Violin d7e139c486 feat: implement violin_guard plugin with secure execution adapters, terminal policies, and pentest skill frameworks 2026-08-08 13:29:11 +01:00
Violin 5e21f2257f fix(benchmark,guard): enhance benchmark profiling, guard UX, and findings integration 2026-08-08 13:29:11 +01:00
Violin 9ed494d439 feat: introduce benchmark runner with Docker support and automated vulnerability calibration evidence 2026-08-08 13:29:11 +01:00
Violin 4b21dce94a feat: harden benchmark evaluation and guard runtime 2026-08-08 13:29:11 +01:00
3b21e0a92a feat: Automated Benchmark Runner and Evaluation Framework (#68)
* fix: bump distribution version to 3.0.1

* feat(benchmark): introduce benchmark runner engine, Docker containerization, and calibration datasets

* Fix URL/path scope exclusions and update duck-store template

- Modified targets.py to ensure that excluding a specific URL or path does not result in the entire host being blocked. Implemented a strict command payload check for excluded endpoints.

- Updated duck-store benchmark scope template to explicitly block the /vulnerabilities endpoint (which leaks intentional challenges) while allowing access to endpoint documentation.

* fix: correct scope.yaml indentation and refine guard blocking messages

* fix: resolve ModuleNotFoundError when score.py is executed directly

---------

Co-authored-by: Dan <dan@strategicautomation.local>
2026-08-08 13:29:11 +01:00
DanandGitHub 2709b6a69f Merge pull request #66 from Strategic-Automation/fix/distribution-version-3.0.1
fix: bump distribution version to 3.0.1
v3.0.1
2026-08-04 18:56:23 +01:00
Dan 08684d65b1 fix: bump distribution version to 3.0.1 2026-08-04 18:55:42 +01:00
DanandGitHub d89fc64d4e chore(release): bump version to 3.0.1 (#65)
Merge dev into master for 3.0.1 release
2026-08-04 17:24:29 +01:00
DanandGitHub 5071b9689f docs(release): align workflow instructions, hypothesis discipline, and release v3.0.1 (#64)
Merge dev into master
2026-08-04 17:18:44 +01:00
DanandGitHub 1ef97dee9e Release v3.0.0: workflow-stable engagement lifecycle
Promote the verified v3.0.0 workflow release from dev to master.
v3.0.0
2026-08-01 22:40:25 +01:00
Violin 1ce445ae59 Use project runtime in Windows smoke test 2026-08-01 22:37:57 +01:00