fix(opencode): preserve audit chain verification across rollover eviction#3250
fix(opencode): preserve audit chain verification across rollover eviction#3250Peldan wants to merge 2 commits into
Conversation
…tion The OpenCode adapter's audit log truncates to MAX_ENTRIES via .slice(-MAX_ENTRIES) on every append. That drops the GENESIS-anchored head, but verifyAuditEntries requires entries[0].previousHash === GENESIS_HASH, so once the log rolls over verification fails permanently. Because appends verify first and governance fails closed (denyOnPolicyError), every subsequent tool and prompt decision is then denied — the plugin bricks after MAX_ENTRIES entries. Port the seam-hash re-anchoring already applied to the Go/Rust/TypeScript implementations in microsoft#1838 (which did not touch the OpenCode adapter): on eviction, retain the last evicted entry's hash as a seam and re-anchor the surviving chain to it in verifyAuditEntries. The seam is persisted in a backward-compatible way — logs that never roll over stay bare arrays; rolled -over logs use { seamHash, entries }; and an already-truncated legacy bare array is recovered by adopting its head's previousHash as the seam. Adds tests covering rollover, legacy recovery, format stability, and that content tampering is still detected. Related: microsoft#1838 Signed-off-by: arvidpeldan <peldans@gmail.com>
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
|
Welcome to the Agent Governance Toolkit! Thanks for your first pull request. |
🤖 AI Agent: contributor-guide — View details
Welcome, and thank you for your contribution! Your detailed explanation and thorough test coverage are impressive. Great job addressing backward compatibility and ensuring robust verification logic. Before merging, please:
For guidance, refer to CONTRIBUTING.md. |
|
@Peldan please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
Description
The OpenCode adapter's audit log truncates to MAX_ENTRIES via .slice(-MAX_ENTRIES) on every append. That drops the GENESIS-anchored head, but verifyAuditEntries requires entries[0].previousHash === GENESIS_HASH, so once the log rolls over verification fails permanently. Because appends verify first and governance fails closed (denyOnPolicyError), every subsequent tool and prompt decision is then denied — the plugin bricks after MAX_ENTRIES entries.
Port the seam-hash re-anchoring already applied to the Go/Rust/TypeScript implementations in #1838 (which did not touch the OpenCode adapter): on eviction, retain the last evicted entry's hash as a seam and re-anchor the surviving chain to it in verifyAuditEntries. The seam is persisted in a backward-compatible way — logs that never roll over stay bare arrays; rolled-over logs use { seamHash, entries }; and an already-truncated legacy bare array is recovered by adopting its head's previousHash as the seam. Adds tests covering rollover, legacy recovery, format stability, and that content tampering is still detected.
Affected package: agent-governance-opencode (@microsoft/agent-governance-opencode).
Type of Change
Package(s) Affected
Checklist
AI Assistance
If AI tools materially shaped this change, briefly note what was used:
AI assistance was used to confirm the bug with a standalone reproduction (a post-truncation appendAuditEntry throws failed hash-chain verification), draft the fix, and clarify the PR description. All changes reviewed and owned by me.
IP, Patents, and Licensing
Related Issues
Related: #1838