Skip to content

Event 78 · CP-AUDIT-ACK-01 · episteme profile audit ack CLI + hash-chained ack-store#35

Merged
junjslee merged 1 commit intomasterfrom
event-78-audit-ack-cli
Apr 29, 2026
Merged

Event 78 · CP-AUDIT-ACK-01 · episteme profile audit ack CLI + hash-chained ack-store#35
junjslee merged 1 commit intomasterfrom
event-78-audit-ack-cli

Conversation

@junjslee
Copy link
Copy Markdown
Owner

Summary

Fourth (and last main) v1.0.1 polish CP. The SessionStart audit-drift banner has pointed at episteme profile audit ack <audit-id> since v0.11.0, but the subcommand did not exist. Operator (Event 68, 2026-04-27) had to close the asymmetry_posture audit loop via direct profile re-elicit because there was no structured ack pathway. This PR ships the missing CLI + the hash-chained ack-store the banner has been promising all along.

What ships

1. New CLI subcommand episteme profile audit ack

# Ack a drift alert with a substantive rationale
episteme profile audit ack audit-20260427-063251-9131 --rationale "Re-elicited asymmetry_posture in Event 68; 3 consecutive stop+rollbacks closed the gap."

# Optional supporting refs
episteme profile audit ack <id> --rationale "..." --evidence-refs "Event 65" "Event 66" "Event 67"

# List outstanding (un-acked) drift records
episteme profile audit ack --list

# Revoke a prior ack (audit trail preserved; revoke appends, never deletes)
episteme profile audit ack --revoke <audit-id> --rationale "Reverting on new evidence of continued drift."

2. New module src/episteme/_profile_audit_ack.py

Function Purpose
validate_rationale(text) Lazy-token + min-15-char rejection (mirrors Reasoning Surface validator discipline)
write_ack(audit_id, rationale, ...) Append cp7-chained-v1 envelope to ~/.episteme/state/profile_audit_acks.jsonl
write_revoke(audit_id, rationale, ...) Append revoke entry (NOT a delete)
is_acked(audit_id) Latest-state-per-id walk; True iff latest entry is an ack
acked_ids() Batch lookup for SessionStart suppression
list_outstanding_audits() Filter profile_audit.jsonl records by ack-store state
verify_chain() Integration with episteme chain verify

3. Audit-loop integration (suppression)

  • core/hooks/session_context.py: inline _is_acked_in_store(run_id) check suppresses SessionStart banner for acked run_ids. Inlined per the hooks-stay-self-contained convention (no sys.path setup of src/episteme/ in standalone hook invocation).
  • src/episteme/_profile_audit.py:surface_drift_line(): imports _profile_audit_ack and runs is_acked check. Library-tier; degrades gracefully if module unavailable (test isolation).

4. Chain integration

episteme chain verify now enumerates profile_audit_acks alongside protocols / deferred_discoveries / pending_contracts. Stream uses the same SHA-256 cp7-chained-v1 envelope schema — no new chain primitives needed.

Audit-trail discipline

Revoke is NEVER a delete. A revoke appends a new chain entry whose type is profile_audit_ack_revoke; the latest-state-per-id walk treats the latest entry as authoritative. The full ack/revoke trajectory is preserved in the chain (Pillar 2 ethos: nothing changes silently; nothing is silently undone).

Validation discipline

Rationale must be ≥ 15 chars AND must NOT match the lazy-token list:

  • English: n/a, na, tbd, todo, none, nothing, nil, null, ack, acked, acknowledged, ok, okay, fine, later, fix later, do later, address later, wip, in progress
  • Korean: 해당 없음, 없음, 없다, 추후, 나중에

Lazy-token check fires BEFORE min-char check so 'n/a' returns the lazy-token error message (more diagnostic) rather than the min-char message.

Tests

tests/test_profile_audit_ack.py20/20 pass:

Class Cases
ValidateRationaleTests min-char, English lazy tokens, Korean lazy tokens (해당 없음), ack / ok / tbd, substantive accepted, non-string rejected
AckStoreWriteTests ack envelope shape, revoke entry, invalid audit-id rejected
IsAckedReadPathTests no-store, ack-then-acked, revoke-after-ack, re-ack-after-revoke (latest wins), acked_ids set correctness
ChainIntegrityTests 4-entry chain stays intact across ack + ack + revoke + ack
ListOutstandingAuditsTests excludes-acked, excludes-no-drift, empty-when-no-records

Full test suite green: 144/144 (124 baseline + 20 new).

Smoke test (live, post-merge — operator should run)

# 1. Confirm the CLI is wired (--help renders all flags)
episteme profile audit ack --help

# 2. List currently outstanding drift records
episteme profile audit ack --list

# 3. (If outstanding records exist) ack one with a substantive rationale
episteme profile audit ack <id-from-step-2> --rationale "Re-elicited in Event 68; lived-behavior closed the gap."

# 4. Verify the new chain stream
episteme chain verify
# Expect: profile_audit_acks listed alongside other streams; INTACT entries=1

# 5. Verify suppression — start a new Claude Code session
# The SessionStart banner should NOT show the acked drift alert

Soak-invariant

Surface Status
core/hooks/session_context.py Modified (post-soak; allowed)
src/episteme/_profile_audit.py Modified (library)
src/episteme/_profile_audit_ack.py NEW
src/episteme/cli.py Modified
tests/test_profile_audit_ack.py NEW
kernel/* / core/blueprints/* / templates/* / labs/* UNTOUCHED

v1.0.1 polish queue post-Event-78

  • ✅ CP-RELEASE-PLEASE-CHKPT-FILTER-01 (Event 75)
  • ✅ CP-SYMLINK-RESTORE-01 Part A (Event 76)
  • ✅ CP-EXAMPLES-SCHEMA-PARITY-01 Components 1-4 (Event 77)
  • CP-AUDIT-ACK-01 (this PR) — last main piece
  • ⏳ CP-SYMLINK-RESTORE-01 Part B (SessionStart hook integration; ~1h, deferred-by-design)
  • ⏳ CP-EXAMPLES-SCHEMA-PARITY-01 Component 5 (optional episteme verify-examples CLI; deferred-by-design)

4 of 4 main v1.0.1 polish CPs shipped. Both remaining items are explicitly deferred-by-design optional enhancements (Part B integrates the symlink-restore script into a hook for auto-run; Component 5 adds a machine-checkable schema-parity validator). v1.0.1 polish track is effectively complete.

Cross-references

  • Spec source: ~/episteme-private/docs/cp-v1.0.1-polish.md § CP-AUDIT-ACK-01
  • Original gap surfaced: Event 68 (docs/PROGRESS.md Event 68 entry — operator closed asymmetry_posture audit loop via direct re-elicit because no CLI existed)
  • Chain envelope schema: core/hooks/_chain.py § cp7-chained-v1
  • Phase 12 audit module: src/episteme/_profile_audit.py
  • Audit trail: ~/episteme-private/docs/PROGRESS.md Event 78 entry (private)

…vent 78)

CP-AUDIT-ACK-01 (v1.0.1 polish mini-batch CP #4 — last main piece).

The SessionStart audit-drift banner has pointed at
`episteme profile audit ack <audit-id>` since v0.11.0, but the
subcommand did not exist. Operator (Event 68, 2026-04-27) closed
the asymmetry_posture audit loop via direct profile re-elicit
because no structured ack pathway existed. This Event ships the
missing CLI + the hash-chained ack-store the banner has been
promising all along.

What ships:

1. New CLI subcommand `episteme profile audit ack`:
   - `<audit-id> --rationale "..."` writes an ack
   - `--list` enumerates outstanding (un-acked) drift records
   - `--revoke <audit-id> --rationale "..."` revokes a prior ack
   - `--evidence-refs Event65 Event66 ...` optional supporting refs

2. New module src/episteme/_profile_audit_ack.py:
   - validate_rationale: lazy-token + min-15-char rejection
     (mirrors Reasoning Surface validator discipline)
   - write_ack / write_revoke: append cp7-chained-v1 envelopes
     to ~/.episteme/state/profile_audit_acks.jsonl
   - is_acked / acked_ids: latest-state-per-id walk
   - list_outstanding_audits: filter profile_audit.jsonl by ack-store
   - verify_chain: integration with episteme chain verify

3. Audit-loop integration (suppression):
   - core/hooks/session_context.py: inline _is_acked_in_store check
     suppresses the SessionStart banner for acked run_ids. Inlined
     per the hooks-stay-self-contained convention (no sys.path setup
     of src/episteme/ in standalone hook invocation).
   - src/episteme/_profile_audit.py:surface_drift_line: imports
     _profile_audit_ack and runs is_acked check; degrades gracefully
     if the module is unavailable (test isolation).

4. Chain integration:
   - episteme chain verify now enumerates profile_audit_acks
     alongside protocols / deferred_discoveries / pending_contracts.
   - Stream uses the same SHA-256 cp7-chained-v1 envelope schema —
     no new chain primitives needed.

Audit-trail discipline:
- Revoke is NEVER a delete. Revoke appends a new chain entry whose
  type is profile_audit_ack_revoke; the latest-state-per-id walk
  treats the latest entry as authoritative. The full ack/revoke
  trajectory is preserved in the chain (Pillar 2 ethos: nothing
  changes silently; nothing is silently undone).

Validation discipline:
- Rationale must be >= 15 chars, NOT match the lazy-token list
  ('n/a', 'tbd', 'ack', 'ok', 'okay', 'later', 'wip', ' 해당 없음',
  '없음', etc. — English + Korean; mirrors agent_feedback.md
  no-AI-co-author-trailer style of explicit-list discipline).
- Lazy-token check fires BEFORE min-char check so 'n/a' returns
  the lazy-token error message (more diagnostic) rather than the
  min-char message.

Tests at tests/test_profile_audit_ack.py — 20/20 pass:
- ValidateRationaleTests (8 cases): min-char, lazy-token English,
  lazy-token Korean, ack/ok/tbd, substantive accepted, non-string
  rejected
- AckStoreWriteTests (3 cases): ack envelope shape, revoke entry,
  invalid audit-id rejected
- IsAckedReadPathTests (5 cases): no-store, ack-then-acked,
  revoke-after-ack, re-ack-after-revoke (latest wins),
  acked_ids-set-correctness
- ChainIntegrityTests (1 case): 4-entry chain stays intact across
  ack+ack+revoke+ack
- ListOutstandingAuditsTests (3 cases): excludes-acked,
  excludes-no-drift, empty-when-no-records

Full test suite green: 144/144 (124 baseline + 20 new).

Soak-protected surfaces touched:
- core/hooks/session_context.py (post-soak; allowed)
- src/episteme/_profile_audit.py (library; not soak-protected)
- src/episteme/_profile_audit_ack.py (NEW)
- src/episteme/cli.py (CLI; not soak-protected)
- tests/test_profile_audit_ack.py (NEW; not soak-protected)
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
episteme Ready Ready Preview, Comment Apr 29, 2026 2:53am

@junjslee junjslee merged commit bb8e96e into master Apr 29, 2026
5 checks passed
@junjslee junjslee deleted the event-78-audit-ack-cli branch April 29, 2026 02:57
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