Skip to content

Feat/issue 33 s2 campaign state#79

Closed
hyperpolymath wants to merge 2 commits into
mainfrom
feat/issue-33-s2-campaign-state
Closed

Feat/issue 33 s2 campaign state#79
hyperpolymath wants to merge 2 commits into
mainfrom
feat/issue-33-s2-campaign-state

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

No description provided.

hyperpolymath and others added 2 commits May 26, 2026 12:30
Adds a per-WeakPoint hexad path to persist_assemblyline_report so a
batch scan can persist one hexad per finding in addition to the existing
aggregate hexad. Subject identity is `finding:<repo>:<file>:<line>:<category>`,
chosen for cross-run stability so the upcoming S2 (campaign register-pr)
and S3 (query) slices can join on it without diffing JSON.

New public surface:
- HexadSemantic gains an optional `finding: Option<FindingSemantic>`
  (additive, skip_serializing_if = none → existing consumers unaffected).
- FindingSemantic carries finding_id / repo / file / line / category /
  rule_id / rule_name / severity / description / first_seen_run /
  last_seen_run / framework. rule_id and rule_name reuse the canonical
  SARIF mapping (sarif.rs::rule_id / rule_name now pub(crate)).
- build_finding_hexads(report) -> Vec<PanicAttackHexad>.
- STORE_FINDING_HEXADS_ENV = "PANIC_ATTACK_STORE_FINDING_HEXADS" — when
  set non-empty AND StorageMode::VerisimDb is configured,
  persist_assemblyline_report writes one file per finding under
  `<dir>/hexads/findings/`.

Behaviour preserved:
- Default path unchanged (env var off → no per-finding writes).
- Aggregate hexad still emitted in every VerisimDb run.
- Suppressed WeakPoints are skipped, keeping the store aligned with
  fleet/CI counts.

S1 sets first_seen_run == last_seen_run; back-stamping from a prior
hexad is S2's job (per the issue), not S1's.

Tests: 7 new (id stability, category discrimination, count per WP,
suppression skip, canonical rule_id/name, file write + round-trip,
env-var default-off). Full suite: 215 lib + 13 + 16 + 6 + 12 + 3 + 7
+ 12 + 14 + 20 + 10 + 8 + 22 + 22 + 12 + 2 doc — all green. Clippy
clean with -D warnings.

Refs #33.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the second slice of issue #33: a panic-attack campaign subcommand
that tracks the lifecycle of individual findings produced by the
assemblyline per-finding hexad path (S1). State is persisted as
campaign-facet hexads written under <dir>/hexads/campaign/, indexed by
finding_id, append-only — the current state per finding is the newest
campaign hexad with that finding_id as subject.

New surface:

- HexadSemantic gains `campaign: Option<CampaignSemantic>` (additive,
  skip_serializing_if = none).
- CampaignSemantic { finding_id, state, pr_url?, reason?, last_polled? }
  — state is a free-form String so future labels can be added without
  a schema bump.
- storage: build_campaign_hexad / write_campaign_hexad /
  load_{finding,campaign,aggregate}_hexads helpers.
- src/campaign/ module — register_pr, dismiss, current_state,
  status_markdown.
- panic-attack campaign register-pr|dismiss|status — CLI surface.

`status` renders a Markdown tracker matching the shape of the issue #32
manual checklist: summary line, table with finding-id, repo, rule_id,
location, state, PR link (or dismissal reason), last-event timestamp,
checkbox column.

Out of scope (S2b): poll subcommand that queries GitHub for PR-state
transitions. The data path is in place — the polling logic lands once
the rate-limit / pagination shape is settled.

Tests: 5 new in src/campaign/ (register, dismiss-overrides-open,
empty-arg rejection, empty-store status, two-row render). Full lib
suite: 220 green. Clippy clean with -D warnings. End-to-end CLI smoke
test green: register-pr + dismiss + status round-trip prints the
expected markdown.

Refs #33. Stacked on #55 (S1) — diff against main includes the S1
changes until S1 lands; this PR will rebase clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath hyperpolymath enabled auto-merge (squash) May 30, 2026 13:03
@hyperpolymath
Copy link
Copy Markdown
Owner Author

Closing — superseded. Issue #33's storage work landed via #61 (feat(storage): persist kanren CrossLangInteraction as hexads (issue #33 follow-up)) and #63 (feat(query): facts-backed (crosslang :from :to) evaluator). The S1+S2 staging this PR implemented has been replaced by the merged follow-up architecture.

auto-merge was automatically disabled May 30, 2026 16:57

Pull request was closed

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.

1 participant