Files
violin/tests/pentest_docs/test_pentest_docs_task7_attack_chain.py
Violin ea7e094528 Remediate audit P0/P1 findings; migrate tests to green
- state.py: fcntl/msvcrt file locking, reservation+finalization, history
  verification, remove dead subprocess bridges (p1-lock)
- hypotheses.py: enforce canonical status, phase/host/service/port match,
  reject unrelated hypotheses (p1-hyp)
- tools.py/__init__.py: retain kwargs (task_id), lifecycle hooks wired
  (REGISTERED_TOOLS + no-op-then-active hooks) (p1-life)
- Migrate tests from tests/*.py to tests/guard + tests/pentest_docs; align
  to actual API (handle_target returns ips[0], handle_exec_burst fail-closed,
  PTT self-certify uses real batch_id, post-exploitation requires hypothesis)
- scoping.md: add checkpoint.json continuity-artifact drift note
- pyproject.toml: v1.2.0, per-file-ignores for tests/scripts (E402/S101)
- Add .pytest-tmp-plugin/ to .gitignore

64 passed; ruff clean.
2026-07-12 20:57:55 +01:00

64 lines
1.7 KiB
Python

from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
PENTEST = ROOT / "skills/pentest"
EXPLOITATION = PENTEST / "playbooks/exploitation.md"
REPORTING = PENTEST / "playbooks/reporting.md"
TEMPLATE = PENTEST / "templates/report-template.md"
STANDARDS = PENTEST / "references/standards.md"
def test_standards_define_attack_chain_record_contract():
text = STANDARDS.read_text(encoding="utf-8").lower()
required = [
"attack-chain correlation",
"chain_id",
"step_id",
"prerequisite_findings",
"resulting_access",
"chain impact",
]
for phrase in required:
assert phrase in text
def test_exploitation_keeps_chain_steps_individually_approved():
text = EXPLOITATION.read_text(encoding="utf-8").lower()
required = [
"attack-chain correlation",
"do not automatically chain",
"each step",
"new approval",
"chain_id",
"prerequisite_findings",
]
for phrase in required:
assert phrase in text
def test_reporting_requires_chain_rollup_without_replacing_atomic_findings():
text = REPORTING.read_text(encoding="utf-8").lower()
required = [
"attack chain roll-up",
"atomic findings",
"prerequisite findings",
"chain impact",
"must not replace",
]
for phrase in required:
assert phrase in text
def test_template_has_attack_chain_correlation_section():
text = TEMPLATE.read_text(encoding="utf-8").lower()
required = [
"## attack chain correlation",
"chain id",
"step id",
"prerequisite findings",
"resulting access",
"chain impact",
]
for phrase in required:
assert phrase in text