Repository navigation
Conversation
mlieberman85
left a comment
There was a problem hiding this comment.
Nice start. A few gaps before this fully closes #542:
- Remediation reads without
expected_level, but on a miss it re-audits at level 3, so a level-1 cache is still a hit. Please passexpected_level=3. --include/--excludeandprofile=also produce filtered audits that currently look unfiltered. Please record the full scope (afilteredflag or the control-ID set).- A filtered audit still replaces an unfiltered cache, and the remediation read ignores
[stores.cache]. Fix both here, or change "Fixes #542" to "Refs". - Bump
CACHE_VERSION, or treat a missingtagskey as a miss, so old cache files aren't read as unfiltered. - Spec-first: describe the envelope change in
framework-design.md10.4. - Add the model version to
Assisted-byand name the tool in the PR body.
Drafted with Claude Code; reviewed and posted by me.
16fa6e3 to
56b39cc
Compare
|
Addressed.
Tests: 38 in Three failures in the long I also left |
mlieberman85
left a comment
There was a problem hiding this comment.
Thanks, this covers everything I asked. Two things before it can merge:
- Rebase onto main. It conflicts in
orchestrator.py,cli.pyandaudit.py, so CI hasn't run. #552 changed_load_merged_storesto(framework_name, operator). After the rebase,_load_merged_stores(local_path, "openssf-baseline")would raise inside thetry, and every remediation would quietly re-run the audit. Please resolve the operator configuration the way_run_baseline_checksdoes. Ideally, also move the cache-key derivation into one helper that bothtools/audit.pyand the orchestrator call, so the two can't drift apart again. - Profile-filtered audits.
audit_openssf_baseline(profile=...)narrowscontrolsitself and passestags=None, so its cache entry still saysfiltered=False, and remediation reads it as a full audit. Please fail closed: when a caller passescontrolswithout sayingcache_filtered, treat the audit as filtered. Callers that pass the full set (the MCP tool without a profile, the CLI without filters) then passcache_filtered=Falseexplicitly. Please add a test for the profile case.
On the three tests that fail in a full-suite run: main now passes the full suite (5210 passed after #548 made the gh calls offline). If they still fail after the rebase, please open an issue with the output.
Drafted with Claude Code; reviewed and posted by me.
A filtered audit left a cache that remediation read as a full audit. On main, `darnit audit --tags level=1` writes 26 results and remediate_audit_findings then acts on those as if all 66 controls had run. The cache envelope now records the audit's scope: framework, level, tag filter, and whether any filter narrowed the control set. CACHE_VERSION is 2 and must match exactly, so older envelopes, which cannot describe their own scope, are ignored and rebuilt. A filtered audit is written under its own key, so it never replaces the full-audit entry. run_sieve_audit records an audit as filtered when it has tags, when the caller says so, or when the caller passed its own `controls` without saying. That last case fails closed: the function cannot tell a narrowed list from the full set. Callers with the full set say cache_filtered=False (the generic MCP audit tool); the CLI and the Baseline tool compute it from --tags/--include/--exclude and from the profile. Remediation reads through read_full_audit_cache, which resolves the operator configuration and the store the way run_sieve_audit does, derives the key with the same helper (audit_cache_key), and accepts only an unfiltered level 3 audit of its framework. Rebuilt on current main rather than rebased: main had rewritten the three conflicting files since the original commit. Drafted with Claude, edited by me. Signed-off-by: Marc-cn <130138935+Marc-cn@users.noreply.github.com> Assisted-by: Claude:claude-fable-5-1
56b39cc to
913771a
Compare
|
Rebuilt on current main and force-pushed (one commit). Main had rewritten the three conflicting files, so I re-applied the change instead of resolving the conflicts in place.
Checked through the CLI on a committed one-file repository:
One existing test changed: Full suite: 5167 passed, 19 skipped. The three tests that failed for me before did not fail. Note for #576: it wires Drafted with Claude; reviewed and posted by me. |
Fixes #542 (partially, two bullets deferred, see below)
Problem
Remediation read the audit cache without checking that the cached audit covered what it was about to remediate.
read_audit_cachevalidated TTL, HEAD commit and dirty state, but never compared theframeworkorlevelthe envelope records and the tag filter wasn't recorded at all.So a level-filtered run, a
--tags domain=VMrun or an audit of a different framework in the same checkout left a cache that a later Baseline remediation treated as a full Baseline audit, and remediated only the subset it found.What changed
read_audit_cachetakesexpected_framework,expected_levelandexpected_tags. A mismatch is a miss, checked alongside the existing staleness rules. All three default toNone, so existing callers are unaffected.cli.py:238,apply_user_config=False), sorun_sieve_auditnever saw the filter and a filtered run wrotetags: "". It now passescache_tagsexplicitly for the envelope.remediate_audit_findingsasks for an unfilteredopenssf-baselinecache and re-audits on a mismatch.expected_levelis deliberately not passed from remediation: that function has no level of its own, so there'd be nothing truthful to compare against.Verification
Before — a tag-filtered audit writes a cache indistinguishable from a full one:
After:
4 new tests in
tests/darnit/core/test_audit_cache.py::TestScopeMismatch.tests/darnit(minus parity) 2047 passed;tests/darnit_baseline900 passed.Type of Change
Testing
AI assistance
Not included
Two bullets from the issue, both need their decision:
[stores.cache]. Fixing it means pulling_load_merged_stores+resolve_storesintoremediation/orchestrator.py, mirroringtools/audit.py:567. This is the follow-up flagged in feat(stores): route audit-cache through AuditCacheStore protocol (feature 035) #413 and seemed better separate.