Skip to content

represent ECVC and SCVS state with persistency (#255) - #274

Open
viktorbeck98 wants to merge 1 commit into
developmentfrom
feat/persist-sequence-detectors
Open

represent ECVC and SCVS state with persistency (#255)#274
viktorbeck98 wants to merge 1 commit into
developmentfrom
feat/persist-sequence-detectors

Conversation

@viktorbeck98

@viktorbeck98 viktorbeck98 commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Task

Closes #255.

Description

  • ECVC re-derives its model. post_train's body moved to _derive(), called
    after training and after a load. It sorts the vectors first: restored keys are
    strings whose set iteration order is hash-randomized per process, and the seeded
    shuffle splits train from validation by that order. The sort is what makes a
    restored model equal a freshly trained one.
  • Keys carry the window size. A count vector's length is max(EventID) + 1
    and says nothing about the window it was counted over, so restoring state at a
    different window_size used to mean every vector missed and every window
    alerted. It now logs a warning.
  • ECVC holds its vectors permanently. post_train used to free train_seqs;
    it can't now — those vectors are the persisted model. Memory grows with the
    number of distinct training windows.
  • Shared helpers moved to utils/sequence_encoding.py so no detector imports
    from another. Consequence: build_count_vec is no longer importable from
    scvs_detector. ECVCOp.build_count_vec is unchanged.

How Has This Been Tested?

pytest --run-ignored — 700 passed, including the ECVC and SCVS audit.log
end-to-end regressions, which detect the same log IDs as before. New coverage in
test_persist_integration.py: save/reload per detector, codec round-trip, the
window-size warning, and an assertion that a reloaded ECVC matrix and threshold
match a trained one

Checklist

  • This Pull-Request goes to the development branch.
  • I have successfully run prek locally.
  • I have added tests to cover my changes.
  • I have linked the issue-id to the task-description.
  • I have performed a self-review of my own code.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Both detectors kept their learned count vectors in a plain in-memory set,
so a trained model was lost on restart. They now store them as keys in
EventPersistency.events_seen, the pattern EventSequenceDetector already
uses, which gives them save, load and auto-load for free.

ECVC derives its matrix and threshold from those vectors in _derive(),
called after training and after a load. The vectors are sorted first:
restored keys are strings whose set iteration order is hash-randomized
per process, and the seeded shuffle splits train from validation by that
order, so sorting is what makes a restored model equal a trained one.

Keys carry the window size, since a count vector's length is
max(EventID) + 1 and says nothing about the window it was counted over.
Restoring state at a different window_size now logs a warning instead of
silently alerting on every window.

The count vector and sequence codec helpers move to
utils/sequence_encoding.py so no detector imports from another. As a
result build_count_vec is no longer importable from scvs_detector.

Co-Authored-By: Claude Opus 5 <[email protected]>
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