Skip to content

Add independent audit logging and reviewer fallback - #76

Merged
areshand merged 6 commits into
mainfrom
codex/phase2-audit-reviewer
Sep 2, 2026
Merged

Add independent audit logging and reviewer fallback#76
areshand merged 6 commits into
mainfrom
codex/phase2-audit-reviewer

Conversation

@areshand

@areshand areshand commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • give operations reviewers an independent read-only identity, full session trace access, and a supervisor-mediated same-scope production evidence path
  • add a supervisor-owned human-review fallback that issues no next permit and returns one bounded question when independent verification cannot accept
  • implement the independently deployed Audit Logger with authenticated append-only SQLite history, replay protection, hash chains, periodic signed checkpoints, integrity verification, projections, metrics, and a separate container boundary
  • keep the Audit Logger outside workflow authority: event submission returns empty HTTP 204 transport acknowledgement, creates no append receipt, and is never consumed by supervisor or prod-mcp authorization

Verification

  • cargo fmt --all --check
  • cargo test --locked (76 passed)
  • npm test --prefix control-server (47 passed)
  • npm test --prefix audit-log (14 passed)
  • python3 -m unittest discover -s tests -p test_*.py -v (97 passed)
  • tests/run.sh
  • git diff --check

Comment thread audit-log/bin/hash-token.mjs Outdated
@@ -0,0 +1,9 @@
#!/usr/bin/env node
import { createHash } from "node:crypto";

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use rust for the audit-log. moreover, let's rename it to logger

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and fixed in bf81275. The component is now the Rust multiagent-logger workspace crate and is renamed holistically to logger across its binary, Docker image, schema, environment variables, tests, and architecture/deployment docs. The port retains the SQLite WAL/FULL ledger, exact idempotency, hash chains, Ed25519 checkpoints, startup verification, scoped clients, and optional projections. The Rust tests and final Docker build pass.

Comment thread runtime/src/authority.rs Outdated
ValidationLeaseList,
GateCheck,
OpsDescribe,
OpsEvidenceRead,

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need a seperate evidence read. it should be hte same as other ops read

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and fixed in bf81275. OpsEvidenceRead and the ops evidence-read CLI were removed; reviewer observations now use the normal ops execute / prod-mcp operations_execute path. The supervisor still preserves the caller UID and fail-closes the reviewer branch to a live reviewer, a reviewed-request binding, identical task/goal/target/runbook scope, access=read, mutation=false, no mutation approvals, and the observer role/subject. A dedicated test proves reviewer and operator execution modes remain disjoint.

Comment thread logger/src/store.rs Outdated
}
let connection =
Connection::open(database).map_err(|error| format!("open logger database: {error}"))?;
connection.execute_batch("PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA locking_mode=EXCLUSIVE; PRAGMA foreign_keys=ON; PRAGMA trusted_schema=OFF;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this used for ?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was the authoritative store for idempotency, per-session ordering and heads, checkpoints, restart recovery, and verification. Since we decided not to use a database, fixed in e5bd042: rusqlite/SQLite is removed and replaced with one canonical append-only JSONL ledger. Each record is fsynced before acknowledgement; the service holds an exclusive writer lock, rebuilds its indexes on startup, and fails closed on truncated, non-canonical, duplicate, out-of-sequence, hash-invalid, or signature-invalid records. No database remains in the logger.

@areshand
areshand merged commit 4736623 into main Sep 2, 2026
4 checks passed
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