Repository navigation
FEAT: file write surface scorer (scorer phase 10) - #3042
Richard Lundeen (richlundeen) merged 9 commits into
Conversation
Adds SurfaceScorable and ScoringScope, the ContentWritten condition, a surface observation payload, LocalFileSurfaceSource and FileWriteScorer, with a runnable attack example.
Preserve both surface and conversation scoring additions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…handle, resolve the message - Directory listings that fail are coverage gaps (listing_failed), so a denied directory leaves the verdict undetermined instead of a complete negative. - Acquisition work is bounded: max_listed_entries caps entries examined, max_files stops enumeration at the first candidate over the limit, and max_read_bytes caps bytes read and hashed per acquisition. A file cut short has no digest (SurfaceEntry.sha256 is now optional) and leaves coverage incomplete (read_limit_exceeded). Cancelling the awaiting coroutine sets a flag the worker checks at every entry and chunk. - Each file is opened first, the open handle's final path is checked against the resolved root (/proc/self/fd, F_GETPATH, GetFinalPathNameByHandleW), and size, timestamp and content all come from that handle. Opens are non-blocking so a FIFO cannot hang the worker. Directory links are not descended into and are reported as gaps. - FileWriteScorer resolves the message reference with MessageScorableResolver before deriving the run's scope, rejecting missing ids and pieces that do not form one stored message.
|
Thanks Roman Lutz (@romanlutz), all four were real, and the reproductions made them quick to pin down. Pushed in one commit on top of your merge of main. Unreadable directories: listings now go through an explicit walk, and a directory that cannot be listed is recorded as Bounded work: Confinement: each file is now opened first, the open handle's final path is checked against the resolved root ( Message reference: the scope now comes from |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Cover persisted verdicts, offline replay, confinement failures and platform handle adapters. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep POSIX root resolution available while testing denied or invalid file parents. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
This is in a good state IMO but leaving it to Richard Lundeen (@richlundeen) to sign off / merge or provide more feedback since this is part of his roadmap for scoring. |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f8fce61b-b61c-4139-a65e-13159ceb2b3f
Remove speculative scope and surface selectors, preserve uncertainty for incomplete text, and avoid repeated glob listings. Keep source tests separate and document workspace ownership. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f8fce61b-b61c-4139-a65e-13159ceb2b3f
|
Thanks Richard Lundeen (@richlundeen). The merge queue run that removed this failed on |
Description
Adds the phase 10 file-surface prototype from the scorer design proposal.
FileWriteScorerchecks whether a location holds the expected content when read, rather than interpreting the response's claims.SurfaceScorablenames an exact file or a glob through the string enumSurfaceMatch.ContentWritten.matcheruses the sharedContains,Equals, andRegexcriteria; without a matcher, any nonempty content counts.LocalFileSurfaceSourceacquires bounded, condition-independent evidence under one root. It checks confinement through the opened handle, retains size/hash/time and bounded text, and records coverage gaps. Glob traversal lists each directory once and skips repeated traversal states.Containsmatch, but cannot establish anEqualsorRegexverdict. Missing or incomplete evidence remains undetermined.The prototype does not infer write attribution from modification time. The earlier draft's
ScoringScopeand unused surface selector are removed. Callers own workspace isolation: attempts sharing a root must run one at a time and start from a clean root for write attribution. A message with a later turn returns an undetermined score without reading the mutable location.Merged
origin/mainthroughf916d8ee5. The source/scorer responsibility split remains unchanged.Tests and Documentation
Source tests are grouped in
test_local_file_surface_source.py. Scorer tests cover shared matcher options, truncated text, persistence, replay, the later-turn guard, and a real attack with a local mock agent. Model tests cover enum and matcher serialization. The paired notebook uses a separate workspace for each attempt, andframework.mdrecords only the responsibility split.Validation on the merged branch:
uv run --no-sync pre-commit run --all-files— passed all hooks, including type checks.uv run --no-sync pytest tests\unit\score\test_file_write_scorer.py tests\unit\score\test_local_file_surface_source.py tests\unit\models\test_surface.py tests\unit\models\test_scorable.py -q— 161 passed, 3 skipped (symbolic-link privileges unavailable on Windows).uv run --no-sync jupytext --to ipynb --execute --set-kernel python3 doc\code\scoring\6_file_write_scorer.py— passed; retained outputs and verified the notebook/Python cells match.