Overview
CocoAudit reads the append-only audit trail at lifecycle/audit.md. Every plan approval, spec gate passage, $ship confirmation, SecondEye acknowledgment, and CocoSentinel approval is recorded verbatim with an ISO 8601 UTC timestamp. The record is never summarized, never overwritten, and never deleted within a project's lifetime.
Enabling CocoAudit: Enabled at $pod init when the developer selects "Enable session audit trail? (recommended for regulated environments)". This creates modes/cocoaudit.on and initializes lifecycle/audit.md with a project header.
CocoContract Lifecycle Events (Feature 44 Enhancement)
CocoAudit records four categories of CocoContract event, written by contract-prove and the archive step of .cortex/skills/cococontract/contract/SKILL.md via the same lifecycle/audit.md append logic the PostToolUse hook already uses:
- Contract declaration — full text of a new outcome contract (persona, observable result, falsifiability condition) plus the session ID and timestamp of declaration.
- Evidence submission — evidence tier (e2e / reference / spec / differential / unit), the function version hash at submission time, the result (pass/fail), and the verbatim evidence description.
- Stale-evidence detection — recorded when a previously passing evidence check is found stale due to a function version change: the prior passing version hash, the current version hash, and the detection timestamp.
- Contract archive — recorded when a contract is committed to
outcomes/, with the contract content hash.
$audit ci
Extends $audit with a contract regression phase that runs before standard audit log verification. Invoke audit-ci. The regression phase reads all archived contracts in outcomes/, re-executes each contract's falsifiability condition where machine-executable (e2e checks against a real Cortex endpoint), and records pass/fail. A contract whose re-execution fails is a behavioral regression — reported with the same severity as a failing safety gate. Intended for use as a CI/CD pre-deployment gate.
Commands
$audit add "<message>"
Routes to .cortex/skills/cocoaudit/audit-add/SKILL.md. Appends a clearly marked manual event using:
invoke audit-events add "<message>"
Manual entries are useful for migration, test, and documentation scenarios. They must remain labeled as manual and must not be treated as hook-generated HITL evidence.
$audit timeline
Routes to .cortex/skills/cocoaudit/audit-timeline/SKILL.md. Displays a compact chronological view using:
invoke audit-events timeline
$audit view [--from <date>]
Steps:
- Check
modes/cocoaudit.onexists — if not, output: "CocoAudit is not enabled. Enable at$pod initor createmodes/cocoaudit.onmanually." - Check
lifecycle/audit.mdexists — if not, output: "Audit trail not yet initialized. Run$pod initwith audit enabled." - Read
lifecycle/audit.mdand parse## [Event Type]header blocks - Apply
--fromfilter if provided: parse each block's**Timestamp**field as an ISO 8601 UTC timestamp and include events whose timestamp is greater than or equal to the filter value. A date-only filter such as2026-06-01means2026-06-01T00:00:00Z. - Without filter: show last 20 blocks; with filter: show all matching blocks
- Render in terminal format:
────────────────────────────────────────
[plan-approved] 2026-06-14T10:30:00Z
Artifact: lifecycle/plan.md
Input: "looks good, proceed"
Result: Build phase unlocked
────────────────────────────────────────
- Show total count: "Showing N of M total audit events"
$audit export
Steps:
- Check
modes/cocoaudit.onexists - Check
lifecycle/audit.mdexists - Count total
## [event blocks in the file - Generate timestamped filename:
audit-export-YYYY-MM-DDTHH-MM-SSZ.md(colons replaced with hyphens for filesystem safety) - Write to
.cocoplus/audit-export-[timestamp].md:
# CocoAudit — Compliance Export
**Project**: [project name from lifecycle/meta.json]
**Exported**: [ISO 8601 UTC timestamp]
**Total Events**: [N]
> This document is an append-only audit trail. Records are verbatim developer inputs.
> This file must not be edited after export.
---
[Full verbatim content of lifecycle/audit.md]
- Output: "Audit export written to
.cocoplus/audit-export-[timestamp].md([N] events)" - Idempotent: Each invocation produces a new timestamped file. Never overwrites prior exports.
Integrity Checks
When viewing, exporting, or running $audit ci, validate audit structure before rendering:
- Every event block begins with
## [and includes**Timestamp**and**Event** - Timestamps parse as ISO 8601 UTC
- Event blocks remain in non-decreasing timestamp order
- Malformed blocks are reported with their block number and first heading line
Do not modify audit.md while checking integrity. Reporting malformed audit structure is allowed; repairing the append-only file requires explicit developer direction.
Exit Criteria
-
$audit viewrenders last 20 events correctly when no--fromfilter -
$audit view --from 2026-06-01shows only events from that date forward -
$audit viewreports malformed or out-of-order event blocks before rendering -
$audit exportproduces unique timestamped files on each invocation - Both commands fail gracefully with clear error when
modes/cocoaudit.onabsent - Both commands fail gracefully when
lifecycle/audit.mdabsent - All four CocoContract event categories (declaration, evidence submission, stale-evidence detection, archive) are documented and recognized by
$audit view -
$audit ciruns the contract regression phase before standard audit log verification and exits non-zero on any regression
Anti-Rationalization
| Temptation | Why Wrong |
|---|---|
| Summarize developer input | Verbatim is the requirement — paraphrasing destroys audit validity |
| Overwrite prior exports | Idempotent means new file each time, not same file |
| Use local timezone in timestamps | ISO 8601 UTC only — local timezone timestamps are not audit-grade |
| Delete or truncate audit.md | Append-only means never delete; it is a compliance artifact |
| Auto-repair malformed audit blocks | Audit repair changes compliance evidence and requires explicit developer direction |