Repository navigation
Incidents opened by fixed code stayed open for a week, because nothing asked the current code again - #69
Merged
opencdlee-dotcom merged 1 commit intoSep 24, 2026
Conversation
…g asked the current code again Every machine exit waits for the sensor to say something new: re-grade reads the newest evidence, re-verify re-asks one signature, cleared-state and removed-file need the sensor to look again. An incident opened by code that has since been fixed hears none of that unless the same subject is re-observed, so it waits out the 7-day age-out. Live: #527, a Spotify risk case built from listener findings recorded `unsigned` while codesign was not answering (Spotify is Developer ID), and #537, a staging plugin-container the current code grades MEDIUM on its build-output rung. _rejudge_open_incidents(db, now) runs in record_security_state after the removed-file exit. For each OPEN/ACK signal, risk or chain incident created before this scan, every observation finding it holds is re-derived through _reobserve, the path `backtest replay --reobserve` scores with, with the live suppression memory and dismissal weights, the learning period off and the seen-ledger empty. It stands if any evidence is CRITICAL, attack-defined or never-tolerate, or if any finding is replayed as recorded (gone from disk, unmodelled sensor, missing field). Then, by kind: - signal: every finding dropped, or routed below the interrupt tier by route_findings; - risk: re-scored by _risk_buckets / _risk_score over the findings inside one RISK_WINDOW at each moment one was observed, as _accumulate_risk scores it, and no window may still cross. Summed whole, a program that picks a new port per launch is 68 distinct signals (#527); per window it peaks at 0.9; - correlation: a chain the current join rules would not form (_unjoinable_chain_resolution); lineage chains are left alone. A closed incident goes to FALSE_POSITIVE with `re-judged by current code (logic <version>:<code sha12>): <one reason per distinct change> — reopens on new evidence`. It writes no dismissals row and no custody ledger row (the ladder is asked with _custody_remember off). It runs at most hourly, at once when _REJUDGE_LOGIC_VERSION or the running aegis.py changes, and is capped by _REJUDGE_MAX_INCIDENTS (25) and _REJUDGE_BUDGET (30 s) per run. A capped run logs how many it left, and the next resumes after the last incident it examined. Also touched: _accumulate_risk. Its per-entity summing and scoring are extracted as _risk_buckets / _risk_score, with no behaviour change, so a pile is re-scored by the code that opened it. _backtest_replay's counter setup is now _reobserve_stats(), shared with the healer. Sandboxed real scan of this code against a copy of the live state: #527 and #537 closed as re-judged. #526 (subject gone), #539 and #540 (rustup, still HIGH with no rung) stay. No incident was opened, no outward effect was taken, and the real custody ledger read 151 lines before and after. Tests: tests/test_rejudge_open_incidents.py (16). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
opencdlee-dotcom
merged commit Sep 24, 2026
4c36153
into
agent/fable-precision/assembly
9 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Precision plan, step S9: current code re-judges what it already opened. Base:
agent/fable-precision/assembly.Why
Every machine exit waits for the sensor to say something new:
An incident opened by code that has since been fixed hears none of that unless the same subject is observed again, so it waits out the 7-day age-out. Two live examples:
unsignedwhile codesign was not answering. Spotify is Developer ID._rejudge_open_incidents(db, now)It is registered in
record_security_state, after the removed-file exit and before age-out.What it looks at: each OPEN or ACK incident of kind signal, risk or correlation that is not CRITICAL and was created before this scan.
How it re-judges: every observation finding the incident holds is re-derived through
_reobserve, the same pathbacktest replay --reobserveuses. It uses the live suppression memory and dismissal weights, with the learning period off and the seen-ledger empty. The custody ledger is not written while the ladder is asked.The incident stays open if:
Otherwise, by kind:
route_findingsroutes it below the interrupt tier_risk_buckets/_risk_scoreover the findings inside oneRISK_WINDOW, anchored at each moment one was observed (as_accumulate_riskscores it), and no window still crosses the threshold_unjoinable_chain_resolutionsays the current join rules would not form the chain; lineage chains are left aloneThe risk case needs windowing. Summed whole, #527's evidence is 68 distinct listener signals (one new port per Spotify launch) scoring 11.9. Scored per window, as the accumulator scores it, it peaks at 0.9.
How it closes: the status becomes FALSE_POSITIVE with the resolution
re-judged by current code (logic <version>:<code sha12>): <one reason per distinct change> — reopens on new evidence. No dismissals row is written and nothing is added to actions.jsonl, following the other machine exits.When it runs: at most once an hour, and immediately when
_REJUDGE_LOGIC_VERSIONor the running aegis.py changes. Each run is capped at 25 incidents or 30 seconds. A capped run logs how many it left, and the next run resumes after the last incident it examined.Also touched:
_accumulate_risk. Its per-entity summing and scoring are extracted into_risk_bucketsand_risk_scorewith no behaviour change, so a pile is re-scored by the same code that opened it._reobserve_stats()is now shared with_backtest_replay.Sandboxed real scan of 3ff8ea2 against a copy of the live state
Why the others stay open:
This run also opened #543, a CRITICAL "tamper-evidence chain does not verify". It is a race in the sandbox copy, not caused by S9:
notary.jsonlat 21:14:57, ending at seq 2569.The two earlier runs of the driver did not hit this race.
Tests
tests/test_rejudge_open_incidents.pyhas 16 tests:record_security_stateruns it.Full suite on this commit's tree (tree sha checked before and after, live custody ledger unchanged): 2 failed, the rest passed. Both failures are
TestHostileArgsSeverity::test_benign_interpreter_agent_stays_lowandTestExpandedHostileArgs::test_benign_args_stay_low('INFO' != 'LOW'), an interaction between S5 and S7 that is fixed on the assembly branch by ccc01b0 (demotion never goes below LOW); not caused by this change.🤖 Generated with Claude Code