Skip to content

since view: list gate rows under the session they name (limit 74's open half) - #100

Open
githubscum wants to merge 2 commits into
mainfrom
lotor-lane/since-attribute
Open

githubscum wants to merge 2 commits into
mainfrom
lotor-lane/since-attribute

Conversation

@githubscum

Copy link
Copy Markdown
Owner

WO: WO-SINCE-ATTRIBUTE. Addresses: KNOWN-LIMITS 74's open half, and limit 35's closing note. Eval: none named. This is R1 legibility, not a v3 rung.

What changed

Since 2026-09-07 every gated-action row has carried the session id the hook passed. sessions_since ignored it and printed "Gate decisions carry no session id", which is false for new rows. A reader asking "what did that session get denied" was told the record could not say, when the record said.

  • A gated-action or policy-warn row whose own sessionId is a non-empty string goes on that session's record as denials, approvals or warns.
  • Key absent, null, empty or non-string stays in unattributed. egress-event always does. Nothing is attributed by timestamp.
  • The render prints one gate line per session with attributed rows, and no zero counts.

Four adjacent bugs, each probed:

  • A session whose only record is a denial would have been counted "opened idle, not listed". It is now listed.
  • A session with no open or close row would have sorted as 0. It now sorts on its first gate row.
  • An approvals-only window printed nothing. It prints now.
  • The action tally was built on a plain object: action constructor printed constructor xfunction Object() { [native code] }1 and __proto__ vanished from the tally. It counts on a Map now. The first of those was already in the unattributed block on main.

No file under the non-delegable core changed.

Tested

  • npm test on the committed tree: 1405 tests, 1399 pass, 0 fail, 6 skipped.
  • Fail-first: with the old view and the first pass's new test file, 9 of 19 tests fail. The ones that pass include the no-owner states, egress and zero-count tests, which hold on old code and are tripwires, not new behaviour.
  • A scratch probe, not committed, ran window edges, excludeSessionId beside other sessions' rows, odd ids and odd action names. The two tally failures came from it, and the re-run came back clean.
  • git merge-tree against KNOWN-LIMITS 76: three readers stop reporting a refused write as touched #98 and receipt-coverage re-derived from every append site; KNOWN-LIMITS 87: sent targets are plaintext #99: both conflict in KNOWN-LIMITS.md, in the managed pin block only. Whichever lands later re-stamps. src/views/since.js, src/mcp/server.js and test/since-view.test.js auto-merge with KNOWN-LIMITS 76: three readers stop reporting a refused write as touched #98, and test/since-view.test.js passes on that merged tree, 20 of 20. The full suite was not run on it.
  • Executor: glm-5.3-flash, two passes. 45 and 15 model stamps read from its transcripts, no other model on them. Its shell was refused both times, so it claimed no test result and every result above is mine. Verifier: my read of the diff and the probe, no second model.

What a reviewer should doubt

  • Not run on the live chain. Synthetic rows only. The row shape comes from reading the gate's four receipt sites and limit 74's measurements. I did not script over the chain while the question of what binds this lane's stops is open.
  • The attribution is a self-report. The id is what the hook passed (limit 1). The view now states it per session, which reads stronger than the old gap did. The caveat says so; decide whether that is loud enough.
  • More sessions will be listed. A live session with only a warn or denial used to fall under "opened idle". It now appears with "no close receipt, so no counts". That is the intent, but the idle count on a real day will drop by an amount I did not measure.
  • "approved" means "not denied". A row with no decision key would count as approved, the same split the unattributed list already uses. The gate only writes denied and approved today.
  • Report size. Both-layers-permissive warns carry an id and fire per tool call, so a busy session's warns array can be long in the MCP response. Those rows were already in the response, under unattributed.warns, and nothing here truncates them.
  • sessions_since's tool description changed, so a client that fingerprints tool definitions will read it as changed (limit 41). A running MCP server keeps the old code until restart.
  • docs/receipt-coverage.md goes stale. Its "unattributed" line on main, and receipt-coverage re-derived from every append site; KNOWN-LIMITS 87: sent targets are plaintext #99's "still prints the caveat" sentence, go false when this lands. Left alone on purpose, because receipt-coverage re-derived from every append site; KNOWN-LIMITS 87: sent targets are plaintext #99 rewrites that file. Whichever lands second should fix the sentence.

🤖 Generated with Claude Code

githubscum and others added 2 commits November 5, 2026 12:39
A gated-action or policy-warn row whose own sessionId is a non-empty string now
lands on that session's record. Absent, null, empty or non-string stays
unattributed; egress rows always do; nothing is attributed by timestamp.

didWork counts gate rows, so a session whose only record is a denial is listed.
The sort falls back to the first gate row. An approvals-only window now prints.
No zero count prints. The tally counts on a Map: 'constructor' printed garbage
and '__proto__' vanished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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