> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase01-session05-websocket-hydration-and-archive-export-privacy/spec.md).

# Session Specification

**Session ID**: `phase01-session05-websocket-hydration-and-archive-export-privacy` **Phase**: 01 - Core Runtime Hardening **Status**: Completed **Created**: 2026-05-29 **Package**: Cross-package (`apps/server`, `apps/web`, `packages/protocol`) **Package Stack**: TypeScript, Express, ws, React, Zustand, Vitest

***

## 1. Session Overview

This session hardens the local WebSocket and session data surfaces that sit between the hook/runtime work from Sessions 01-04 and the later LLM and documentation sessions. The current server sends deterministic hydration frames and accepts a small client-message vocabulary, but the message boundary still needs direct tests and schema-validated failure paths.

The session also addresses privacy gaps around local session archives, replay buffers, and CSV/JSON exports. FactionOS is local-first, but prompts, paths, command previews, summaries, and tool metadata can still be sensitive when they are persisted, downloaded, shared through replay links, or later forwarded to remote surfaces.

The scope is intentionally runtime-focused. It does not redesign the replay UI, wire War Room sharing, or implement hosted analytics. It creates the tested local contracts and documentation that Session 06 can build on for LLM privacy and Session 07 can summarize as the final Phase 01 runtime contract.

***

## 2. Objectives

1. Validate deterministic WebSocket hydration order and payload shape on new connections.
2. Schema-validate WebSocket client messages without crashing or mutating state on malformed input.
3. Add local archive and export privacy controls that preserve deterministic CSV and JSON schemas.
4. Align web replay/export handling and stable docs with the hardened local-only privacy boundary.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase01-session01-event-ingest-contract-reconciliation` - provides the event and ingest baseline.
* [x] `phase01-session02-hook-runtime-safety` - provides hook payload and listener reliability assumptions.
* [x] `phase01-session03-cli-lifecycle-parity` - provides CLI local auth and lifecycle context.
* [x] `phase01-session04-server-routes-and-authorization-boundaries` - provides route validation, auth boundary, and unsupported-route decisions.

### Required Tools/Knowledge

* Node.js 20 or newer with npm workspaces.
* Vitest project layout for server, web, and protocol tests.
* Existing `RequestValidator` route-boundary pattern in `apps/server/src/lib/requestValidation.ts`.
* Existing adapter privacy redaction posture in `apps/adapters/src/shared/privacy.ts`.
* Direct `EXAMPLES` sources listed in the session stub for WebSocket, export, and archive traceability.

### Environment Requirements

* `EXAMPLES/` remains available locally as ignored source-intake evidence.
* No hosted service, Cloudflare Worker, Anthropic key, Supabase, PostHog, or Umami instance is required.
* Tests must run with mock event generation disabled where deterministic frame order matters.

***

## 4. Scope

### In Scope (MVP)

* Local operator can rely on deterministic WebSocket hydration frames - add direct tests for `connected`, `roster_update`, `notice_board_hydrate`, `scroll_state`, and `achievement_state`.
* Local operator can send supported WebSocket client messages safely - validate `hello`, `ping`, `permission_response`, `plan_approval`, `post_notice`, `collect_scroll`, and `hero_state_override`.
* Local operator can download session exports with stable schemas and safer defaults - redact or omit avoidable prompt/path/command-sensitive fields while preserving schema version and deterministic headers.
* Local archive remains an explicit local audit trail - document retention, redaction boundary, and failure behavior, and add focused tests or retained-risk notes.
* Web client can ignore malformed WebSocket frames and preserve replay/export behavior - validate incoming frame shape before store application and keep replay share decoding defensive.
* Stable docs describe current WebSocket, archive, replay, and export privacy behavior without claiming share-safe or hosted-safe exports.

### Out of Scope (Deferred)

* War Room remote relay payload sharing - Reason: Phase 05 owns Worker-backed collaboration and remote sharing.
* Hosted analytics or hosted replay collection - Reason: Phase 07 owns analytics provider guardrails.
* Full replay UI redesign - Reason: this session hardens data boundaries, not the product surface.
* LLM provider-transfer controls for scan and analysis - Reason: Session 06 owns LLM privacy.
* Unified erasure UI or CLI command - Reason: retention deletion is release hardening beyond the 2-4 hour session limit.

***

## 5. Technical Approach

### Architecture

`packages/protocol` remains the shared contract for event and client-message types. Runtime validation stays at the server WebSocket boundary, matching the route validation pattern introduced in Session 04. The server should parse raw socket input as `unknown`, validate a narrow action shape, and emit compact error or no-op responses without throwing, mutating manager state, or echoing raw payloads.

Export and archive privacy should be handled through small pure helpers in `apps/server/src/lib`, then wired into route/archive code. Redaction must be deterministic and testable. CSV headers and JSON `schemaVersion` must remain stable even when sensitive values are replaced or omitted.

The web client should continue to degrade cleanly when the local WebSocket is offline or sends malformed data. Incoming frames should be dropped unless they are objects with a string `type`, and replay-link decoding should continue to filter malformed entries before dispatch.

### Design Patterns

* Boundary validation: parse and validate WebSocket client messages before calling managers.
* Pure privacy helpers: keep redaction and snapshot shaping unit-testable outside Express and ws.
* Stable schema compatibility: keep export headers, top-level JSON fields, and schema header deterministic.
* Local-first graceful degradation: all changes must work without optional services or remote relays.
* Documentation as contract: update concise and detailed docs in the same session as behavior changes.

### Technology Stack

* TypeScript with strict mode in `apps/server`, `apps/web`, and `packages/protocol`.
* Express 4 and `ws` for the local server.
* React 18, Zustand, and browser WebSocket API for the web client.
* Vitest Node and happy-dom projects for focused tests.
* Biome for format and lint checks.

***

## 6. Deliverables

### Files to Create

| File                                            | Purpose                                                                                   | Est. Lines |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------- | ---------- |
| `apps/server/src/ws/clientMessageValidation.ts` | Validate WebSocket client messages and build compact invalid-message responses.           | \~180      |
| `apps/server/src/lib/sessionPrivacy.ts`         | Redact prompt, path, command, token, and export/archive-sensitive text.                   | \~220      |
| `apps/server/tests/websocket.test.ts`           | Cover hydration order, malformed messages, valid client messages, and disconnect cleanup. | \~320      |
| `apps/web/tests/wsClientPrivacy.test.ts`        | Cover incoming-frame filtering and replay/export privacy helper behavior.                 | \~180      |

### Files to Modify

| File                                      | Changes                                                                                   | Est. Lines |
| ----------------------------------------- | ----------------------------------------------------------------------------------------- | ---------- |
| `apps/server/src/ws/handlers.ts`          | Validate client messages and keep state mutation behind parsed values.                    | \~120      |
| `apps/server/src/ws/broadcaster.ts`       | Ensure archived events pass through the local archive privacy boundary.                   | \~30       |
| `apps/server/src/lib/sessionArchive.ts`   | Apply archive redaction or document retained local-only archive risk in code and tests.   | \~80       |
| `apps/server/src/lib/exportSession.ts`    | Apply export privacy mode while preserving CSV and JSON schema stability.                 | \~160      |
| `apps/server/src/routes/export.ts`        | Validate export options through shared request validation and set privacy/schema headers. | \~60       |
| `apps/server/tests/exportSession.test.ts` | Add redaction and schema-stability coverage.                                              | \~120      |
| `apps/server/tests/exportRoute.test.ts`   | Add export option validation and redacted route-response coverage.                        | \~100      |
| `apps/web/src/store/useWsClient.ts`       | Drop malformed incoming WebSocket frames before store application.                        | \~40       |
| `apps/web/src/lib/exportSession.ts`       | Preserve export download behavior while surfacing privacy/schema headers where useful.    | \~50       |
| `apps/web/src/lib/replayLink.ts`          | Keep shared replay decoding bounded and safe for malformed or sensitive event payloads.   | \~80       |
| `apps/web/tests/exportSession.test.ts`    | Add privacy/header and error-path tests.                                                  | \~70       |
| `apps/web/tests/replayLink.test.ts`       | Add malformed and sensitive-field replay boundary coverage.                               | \~80       |
| `packages/protocol/tests/events.test.ts`  | Lock the client-message union and hydration event contract expectations.                  | \~60       |
| `packages/protocol/README_protocol.md`    | Document protocol ownership for WebSocket client-message shapes.                          | \~30       |
| `docs/api/README_api.md`                  | Update concise WebSocket, archive, replay, and export privacy behavior.                   | \~80       |
| `docs/api/event-api-hook-contracts.md`    | Update detailed WebSocket/client-message/export/archive contract and hardening status.    | \~180      |
| `docs/privacy-and-security.md`            | Update local archive, replay, export, and retention privacy notes.                        | \~100      |
| `apps/server/README_server.md`            | Update server WebSocket/export/archive behavior and local privacy notes.                  | \~70       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] New WebSocket connections receive hydration frames in deterministic order with expected payload families.
* [ ] Malformed WebSocket payloads do not crash the server, close healthy sockets unnecessarily, or mutate manager state.
* [ ] Supported client messages are schema-validated and continue to emit the expected server events.
* [ ] Session exports preserve schema version, deterministic CSV headers, and deterministic JSON top-level fields.
* [ ] Session exports avoid leaking avoidable prompt, path, command, token, and sensitive local-field values beyond documented local-only boundaries.
* [ ] Archive and replay behavior has tests or explicit retained-risk documentation.

### Testing Requirements

* [ ] Server WebSocket tests cover hydration order, malformed input, valid messages, duplicate approvals, and socket cleanup.
* [ ] Export helper and route tests cover CSV, JSON, schema headers, invalid formats, redaction, and no raw input echo.
* [ ] Web tests cover malformed incoming WebSocket frames, replay decoding, and export download/header behavior.
* [ ] Protocol tests cover the client-message union and hydration event expectations.
* [ ] Focused Vitest commands pass for touched server, web, and protocol tests.

### Non-Functional Requirements

* [ ] No hosted service, remote relay, analytics provider, or LLM provider becomes required.
* [ ] Error and invalid-message responses do not echo prompts, command previews, tokens, raw request bodies, or private path fragments.
* [ ] Replay/export/archive payloads remain bounded and version-aware where formats already have version fields.
* [ ] Documentation describes exports and archives as local-first audit artifacts, not share-safe artifacts.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Biome format/lint succeeds for touched files.
* [ ] TypeScript typecheck succeeds for touched packages.

***

## 8. Implementation Notes

### Key Considerations

* Route-level auth from Session 04 already protects WebSocket upgrades and HTTP export routes when `FACTIONOS_AUTH_TOKEN` is set; this session should not weaken those defaults.
* Redaction should be deterministic and narrowly scoped. Do not remove analytics or mission metrics that are useful and not sensitive.
* Preserve export schema version `1` unless the field contract changes incompatibly. Redacted values can keep headers stable without forcing a schema bump.
* Archive behavior may remain local-only rather than fully redacted if redaction would damage audit value; any retained risk must be explicit in docs and tests.

### Potential Challenges

* WebSocket tests can become timing-sensitive: use mock generation disabled, ephemeral ports, and helpers that read a bounded number of frames.
* Redaction can over-strip useful operational context: keep IDs, lifecycle state, counts, timestamps, and non-sensitive metrics intact.
* CSV schema stability can conflict with privacy: prefer deterministic placeholders over column removal.
* Replay shares may already encode historical events: decode must stay backward-compatible while filtering malformed entries.

### Relevant Considerations

* \[P00] **Prompt and path privacy**: This session directly tests redaction before broader export, replay, adapter, or hosted flows.
* \[P00] **Bounded local buffers**: Replay and archive work must keep explicit caps and retention boundaries visible.
* \[P00-packages/protocol] **Protocol leads cross-package work**: Client-message and hydration contracts must stay aligned with protocol tests before server/web wiring.
* \[P00-apps/server+packages/protocol] **Typed surface exceeds implementation**: Do not describe unproduced historical WebSocket events as shipped.
* \[P00] **Local-first boundary**: Harden local exports and archives without adding hosted service dependencies.
* \[P00-apps/web] **Responsive and accessibility debt**: No UI redesign is in scope, but export/replay changes must not regress existing keyboard or toast behavior.

### Behavioral Quality Focus

Checklist active: Yes

Top behavioral risks for this session:

* Malformed socket input mutates manager state or crashes the process.
* Export or archive output leaks sensitive prompts, local paths, commands, or tokens after a user expects safer local-only handling.
* Redaction breaks schema-stable CSV/JSON consumers or replay-link backward compatibility.
* Client-side malformed frames poison replay localStorage or cause store reducers to throw.

***

## 9. Testing Strategy

### Unit Tests

* `apps/server/tests/exportSession.test.ts` for redaction, placeholders, CSV headers, JSON shape, and schema version.
* `packages/protocol/tests/events.test.ts` for client-message union and hydration event expectations.
* `apps/web/tests/replayLink.test.ts` and `apps/web/tests/exportSession.test.ts` for replay and export helper boundaries.

### Integration Tests

* `apps/server/tests/websocket.test.ts` for a real HTTP/ws server with mock generation disabled.
* `apps/server/tests/exportRoute.test.ts` for route validation, response headers, auth-aware behavior, and redacted route output.
* Existing route/security tests as regression coverage for Session 04 boundaries.

### Manual Testing

* Start the local server and web client with mocks disabled, connect the browser, verify hydration, post a notice, collect a scroll, export CSV/JSON, and confirm download toasts still work.
* Send malformed WebSocket frames with a local script or test client and verify the server stays up and existing clients remain usable.

### Edge Cases

* Invalid JSON frame, valid JSON primitive, missing `type`, unknown `type`, wrong field type, overly long strings, and oversized arrays.
* Duplicate `permission_response` and `plan_approval` messages.
* Empty roster/mission export and populated export with prompt, cwd, tty, path, command, bearer token, webhook URL, and secret-like assignment values.
* Malformed replay hash, decoded entries with no string `type`, and replay tokens at the entry cap.

***

## 10. Dependencies

### External Libraries

* None new.

### Other Sessions

* **Depends on**: `phase01-session04-server-routes-and-authorization-boundaries`
* **Depended by**: `phase01-session06-llm-fallback-and-scan-privacy`, `phase01-session07-runtime-contract-documentation`

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase01-session05-websocket-hydration-and-archive-export-privacy/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
