diff --git a/openspec/changes/implement-platform-audit-events/.openspec.yaml b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/.openspec.yaml similarity index 100% rename from openspec/changes/implement-platform-audit-events/.openspec.yaml rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/.openspec.yaml diff --git a/openspec/changes/implement-platform-audit-events/design.md b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/design.md similarity index 100% rename from openspec/changes/implement-platform-audit-events/design.md rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/design.md diff --git a/openspec/changes/implement-platform-audit-events/proposal.md b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/proposal.md similarity index 100% rename from openspec/changes/implement-platform-audit-events/proposal.md rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/proposal.md diff --git a/openspec/changes/implement-platform-audit-events/specs/platform-audit-events/spec.md b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/specs/platform-audit-events/spec.md similarity index 100% rename from openspec/changes/implement-platform-audit-events/specs/platform-audit-events/spec.md rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/specs/platform-audit-events/spec.md diff --git a/openspec/changes/implement-platform-audit-events/specs/platform-operational-readiness/spec.md b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/specs/platform-operational-readiness/spec.md similarity index 100% rename from openspec/changes/implement-platform-audit-events/specs/platform-operational-readiness/spec.md rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/specs/platform-operational-readiness/spec.md diff --git a/openspec/changes/implement-platform-audit-events/tasks.md b/openspec/changes/archive/2026-08-13-implement-platform-audit-events/tasks.md similarity index 100% rename from openspec/changes/implement-platform-audit-events/tasks.md rename to openspec/changes/archive/2026-08-13-implement-platform-audit-events/tasks.md diff --git a/openspec/specs/platform-audit-events/spec.md b/openspec/specs/platform-audit-events/spec.md new file mode 100644 index 0000000..a0e46a6 --- /dev/null +++ b/openspec/specs/platform-audit-events/spec.md @@ -0,0 +1,117 @@ +# Platform Audit Events Specification + +## Purpose + +Define EchoEd's durable, privacy-minimized, transaction-bound audit-event contract for approved high-impact actions, scoped administrative review, integrity verification, retention, export, and operational recovery. + +## Requirements + +### Requirement: Durable audit-event schema +The system MUST persist approved high-impact events using an explicit versioned schema containing event ID, timestamp, actor identity and role snapshot, action, category, outcome, target type and identifier, optional organization scope, request and correlation identifiers, minimized before/after state, safe reason code, and integrity metadata. The schema MUST NOT store credentials, tokens, authorization headers, cookies, private content, assessment answers, uploaded bytes, filenames, or unnecessary personal data. + +#### Scenario: High-impact action captured +- **WHEN** an approved administrative mutation succeeds +- **THEN** exactly one durable event records the allowlisted attribution and state-transition fields without protected content + +#### Scenario: Unsafe audit payload rejected +- **WHEN** code attempts to persist a sensitive key or unsupported nested value +- **THEN** audit persistence fails closed without writing the unsafe event or committing the associated mutation + +### Requirement: Atomic mutation and event persistence +The system MUST write successful high-impact mutation events in the same database transaction as their business-state changes. A mutation MUST roll back when its required audit event cannot be persisted, and a rolled-back mutation MUST NOT leave a success event. + +#### Scenario: Audit persistence failure +- **WHEN** required audit-event persistence fails during a role change +- **THEN** neither the role change nor a success audit event is committed + +#### Scenario: Business mutation rollback +- **WHEN** a high-impact mutation is rolled back after an audit row is staged +- **THEN** the audit row is rolled back in the same transaction + +### Requirement: Approved action coverage +The system SHALL maintain an explicit action catalog and MUST capture currently supported platform-role changes, account deletion, organization invitation and membership changes, forum moderation, and Course Studio publish/review/restore transitions. Unsupported actions MUST NOT be fabricated as successful audit events. + +#### Scenario: Covered mutation catalog +- **WHEN** a supported covered mutation succeeds +- **THEN** its stable catalog action is present in the durable audit store + +#### Scenario: Denied mutation +- **WHEN** authorization or safety controls deny a requested mutation +- **THEN** no successful durable mutation event is recorded and existing operational security diagnostics remain available + +### Requirement: Append-only and integrity verification +Application APIs MUST NOT update or delete audit events. Each event MUST include canonical integrity-chain metadata scoped to platform or organization, and repository tooling MUST verify ordering and content integrity. The documentation MUST state that this is tamper-evident application data rather than protection from a fully privileged database operator. + +#### Scenario: API mutation attempt +- **WHEN** a client attempts to update or delete an audit event +- **THEN** no supported route permits the operation + +#### Scenario: Integrity verification +- **WHEN** an operator verifies an unchanged audit chain +- **THEN** verification succeeds, while modified or reordered canonical event data causes verification to fail + +### Requirement: Scoped audit review +The backend MUST enforce explicit audit-read allowlists. Platform administrators SHALL read the minimized platform feed, and active organization administrators SHALL read only events scoped to their organization. Cross-organization IDs MUST NOT bypass scope checks or disclose event contents. + +#### Scenario: Platform audit review +- **WHEN** an authorized platform administrator requests the platform audit feed +- **THEN** a bounded minimized result is returned + +#### Scenario: Organization audit review +- **WHEN** an active organization administrator requests their organization audit feed +- **THEN** only events whose organization scope matches the active membership are returned + +#### Scenario: Cross-organization audit request +- **WHEN** an organization administrator supplies another organization's identifier +- **THEN** access is denied or concealed according to the security error policy without returning event metadata + +### Requirement: Bounded filtering and pagination +Audit reads MUST use stable bounded pagination and allowlisted low-cardinality filters for time, action, category, outcome, actor ID, and target type/ID. Invalid filters and limits MUST fail validation, and responses MUST NOT serialize ORM models directly. + +#### Scenario: Filtered page +- **WHEN** an authorized reviewer supplies valid filters and a bounded page cursor +- **THEN** the API returns only matching explicit response records plus a continuation cursor + +#### Scenario: Excessive page size +- **WHEN** a client requests more than the configured maximum page size +- **THEN** request validation rejects or caps the request according to the documented API contract + +### Requirement: Safe audit export +Authorized reviewers SHALL export only the same scoped, filtered, minimized fields available through review APIs. Export size MUST be capped, spreadsheet-formula injection MUST be neutralized, and each successful export MUST itself create a durable audit event. + +#### Scenario: Authorized CSV export +- **WHEN** an authorized platform administrator exports a bounded filtered audit set +- **THEN** the response is a safe CSV attachment and an `audit.exported` event records the operation without embedding exported contents + +#### Scenario: Unauthorized export +- **WHEN** an actor without audit-read permission requests an export +- **THEN** the request fails without disclosing whether matching events exist + +### Requirement: Retention and preservation controls +The system SHALL document retention ownership and provide dry-run-first operator tooling for bounded expiration. Production deletion MUST require explicit environment acknowledgement, a verified backup reference, and confirmation that no preservation hold applies. Retention MUST NOT be exposed as a public API. + +#### Scenario: Retention dry run +- **WHEN** an operator supplies a cutoff without destructive confirmation +- **THEN** tooling reports only aggregate eligible counts and changes no data + +#### Scenario: Preservation hold +- **WHEN** a preservation hold is active for the requested scope or period +- **THEN** retention deletion fails closed + +### Requirement: Accessible administrative review +The Angular application SHALL provide authorized platform administrators an accessible audit review experience with loading, empty, error, filtered, detail, pagination, and export states. Frontend controls MUST mirror but MUST NOT replace backend authorization. + +#### Scenario: Administrator reviews an event +- **WHEN** an authorized administrator opens the audit review route and selects an event +- **THEN** minimized attribution, action, outcome, scope, timestamp, and safe state changes are presented with accessible labels + +#### Scenario: Audit API failure +- **WHEN** audit loading or export fails +- **THEN** the page presents an accessible safe error with request-reference context where available and does not retain stale protected results + +### Requirement: Audit-store observability and privacy +Audit capture, read, export, verification, and retention operations MUST emit privacy-safe operational metrics/logs without duplicating before/after contents or using actor, target, organization, or event IDs as metric labels. Durable audit events and operational diagnostics MUST remain conceptually distinct. + +#### Scenario: Audit persistence failure signal +- **WHEN** required audit persistence fails +- **THEN** a bounded operational failure signal includes request correlation and category but excludes the attempted state payload diff --git a/openspec/specs/platform-operational-readiness/spec.md b/openspec/specs/platform-operational-readiness/spec.md index 639299d..9e8c281 100644 --- a/openspec/specs/platform-operational-readiness/spec.md +++ b/openspec/specs/platform-operational-readiness/spec.md @@ -2,7 +2,7 @@ ## Purpose -Define EchoEd's evidence-backed contract for safe production configuration, deployment, migration, health checking, shutdown, monitoring, backup, restore, rollback, and operational recovery without expanding into hosting infrastructure or durable audit events. +Define EchoEd's evidence-backed contract for safe production configuration, deployment, migration, health checking, shutdown, monitoring, backup, restore, rollback, and operational recovery, including durable audit-event recovery, without expanding into hosting infrastructure. ## Requirements @@ -73,16 +73,20 @@ The system documentation SHALL define measurable initial availability, successfu - **THEN** the indicator formula, target, window, data limitations, owner, and related response are unambiguous ### Requirement: Persistent-state backup and verified restore -The operational contract MUST identify all persistent state and define backup scope, cadence, retention, encryption, separation, integrity verification, and restore testing. A backup SHALL NOT be considered valid until an isolated restore proves database and supported uploaded-asset usability. +The operational contract MUST identify all persistent state, including durable audit events and their integrity metadata, and define backup scope, cadence, retention, encryption, separation, integrity verification, and restore testing. A backup SHALL NOT be considered valid until an isolated restore proves database, audit-chain, and supported uploaded-asset usability. Audit retention MUST NOT remove the only recoverable copy required by incident or preservation policy. #### Scenario: Safe recovery drill -- **WHEN** an operator backs up disposable database and upload data, verifies the manifest, restores to isolated targets, and runs usability checks -- **THEN** the restored records and asset bytes match the originals without exposing sensitive data +- **WHEN** an operator backs up disposable database and upload data, verifies the manifest, restores to isolated targets, verifies the restored audit chain, and runs usability checks +- **THEN** the restored records, audit integrity metadata, and asset bytes match the originals without exposing sensitive data #### Scenario: Corrupted backup - **WHEN** a backup file no longer matches its integrity manifest - **THEN** restore fails closed before replacing the target state +#### Scenario: Audit-event recovery +- **WHEN** an operator restores a database containing durable audit events +- **THEN** audit-chain verification succeeds before the restored service is accepted for operational use + ### Requirement: Storage ownership and recovery targets Documentation MUST identify the source of truth, persistence boundary, backup owner, restore owner, deployment behavior, and loss consequences for database, uploaded assets, generated static assets, configuration, and secrets. It SHALL define defensible initial RPO and RTO targets and their prerequisites and limitations.