> 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/phase05-session02-worker-api-hardening-and-client-contract/spec.md).

# Session Specification

**Session ID**: `phase05-session02-worker-api-hardening-and-client-contract` **Phase**: 05 - War Room Worker Integration **Status**: Not Started **Created**: 2026-05-29 **Package**: Cross-cutting (`apps/warroom`, `packages/protocol`) **Package Stack**: TypeScript, Cloudflare Workers, Vitest

***

## 1. Session Overview

This session hardens the optional War Room Worker API before the web cockpit depends on it. The current Worker already creates rooms, handles joins and approvals, accepts participant sockets, keeps bounded recent events, and excludes sender echoes, but several payloads remain schema-loose and error responses are not yet stable enough for typed web consumption.

The work starts in `packages/protocol` so room, participant, pending join, catch-up, error, rate-limit, and socket frame contracts become the shared source of truth. `apps/warroom` then consumes those contracts at its Worker and Durable Object boundaries, rejects malformed input deterministically, preserves room isolation and caps, and exposes typed behavior for later web integration.

This session does not build the web panel, wire local cockpit federation, add hosted identity, or turn the local Express server into a room proxy. Its job is to make the Worker/client contract reliable, bounded, and testable so Sessions 03 through 05 can consume it safely.

***

## 2. Objectives

1. Define shared War Room REST, WebSocket, participant, catch-up, and error contracts in `packages/protocol`.
2. Enforce Worker request, participant, authority, room code, and socket frame validation with deterministic error envelopes.
3. Preserve current Worker behavior for room isolation, participant caps, recent-event caps, sender-excluded broadcasts, and socket cleanup.
4. Expand protocol and Worker tests for success paths, malformed payloads, authorization failures, stale decisions, rate limits, and bounded catch-up.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase05-session01-war-room-requirements-and-trust-baseline` - Provides the War Room lifecycle vocabulary, participant trust model, redaction baseline, and requirement routing matrix for this session.
* [x] `phase04-session08-media-validation-and-documentation-closeout` - Confirms media, local-first, and privacy gates before external-transfer work resumes.

### Required Tools/Knowledge

* Node 20+ npm workspace tooling.
* TypeScript contract patterns in `packages/protocol`.
* Cloudflare Worker and Durable Object request, storage, and WebSocket semantics.
* Vitest in-process Worker fakes under `apps/warroom/tests`.

### Environment Requirements

* Run focused protocol and Worker tests before changing behavior to capture the current baseline.
* No Cloudflare credentials are required for this session; the opt-in `wrangler dev` test remains optional.
* Core local FactionOS behavior must remain independent of Worker configuration.

***

## 4. Scope

### In Scope (MVP)

* Maintainers can import typed War Room room, participant, pending join, decision, catch-up, rate-limit, and error contracts from `packages/protocol` - implemented as exported types, constants, and runtime helpers.
* Worker callers can create, read, join, approve, reject, and connect to rooms through schema-validated inputs - invalid bodies, malformed room codes, unknown participants, pending sockets, stale approvals, stale rejections, and room-full conditions return deterministic envelopes.
* Worker storage remains bounded and minimal - participant metadata and recent safe frames stay capped, sorted, serializable, and free of blocked local developer payload categories.
* Web consumers can depend on a typed client-facing contract without importing Worker internals - request/response types and error codes are protocol-owned.
* Tests prove CORS, rate-limit envelopes, room isolation, caps, sender-excluded broadcast, catch-up bounds, malformed payload handling, and authorization behavior.

### Out of Scope (Deferred)

* Building the web War Room panel or lifecycle state store - *Reason: Session 03 owns web create, join, connect, disconnect, local-only, and unavailable states.*
* Implementing approval, presence, reconnect, catch-up, and leave UX - *Reason: Session 04 owns accessible user flows and duplicate-action UI guards.*
* Federating local mission, hero, replay, export, media, scan, or tool payloads through the Worker - *Reason: Session 05 owns the redacted cockpit event allowlist and blocked-category tests.*
* Adding hosted identity, external auth providers, production database storage, analytics, or public replay hosting - *Reason: later phases own hosted service guardrails and erasure.*
* Turning the local Express server into a Worker proxy - *Reason: Phase 05 keeps `/warroom` as local compatibility/status metadata unless a future PRD adds a proxy threat model.*

***

## 5. Technical Approach

### Architecture

`packages/protocol/src/warroom.ts` becomes the shared contract layer for War Room Worker requests, responses, errors, constants, and runtime validators. `packages/protocol/src/events.ts` remains the shared event union, but its War Room event shapes should reference protocol-owned room and catch-up types instead of duplicating loose payloads.

`apps/warroom/src/index.ts` consumes the protocol contracts at every external boundary: top-level Worker routing, Durable Object init/info/join/approve/ reject handlers, socket handshakes, socket client frames, recent-event storage, and JSON responses. Unknown room paths, malformed room codes, invalid bodies, authorization failures, and rate limits should all map to stable protocol error codes without echoing raw request bodies.

### Design Patterns

* Protocol-first contracts: Define shared types and validators before Worker code consumes them.
* Boundary validation: Validate request bodies, query parameters, socket frames, and room codes before mutation or persistence.
* Fail-closed federation: Drop or reject unknown socket frames before recent event storage, catch-up, diagnostics, or browser consumption.
* Bounded storage: Preserve participant and recent-event caps, deterministic snapshots, and minimal persisted fields.
* Deterministic errors: Return stable error codes, status codes, and optional details or retry metadata, not raw exceptions or request payloads.

### Technology Stack

* TypeScript 5.9.3 in `packages/protocol` and `apps/warroom`.
* Cloudflare Workers and Durable Objects through `@cloudflare/workers-types`.
* Vitest 4.1.7 for protocol and Worker unit tests.
* Biome for formatting and linting.
* npm workspaces for package linking.

***

## 6. Deliverables

### Files to Create

| File                                      | Purpose                                                                                          | Est. Lines |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------ | ---------- |
| `packages/protocol/tests/warroom.test.ts` | Protocol contract and validator tests for War Room requests, responses, errors, and safe frames. | \~220      |

### Files to Modify

| File                                   | Changes                                                                                                              | Est. Lines |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------- |
| `packages/protocol/src/warroom.ts`     | Add shared constants, request/response types, error envelopes, validators, and safe frame helpers.                   | \~280      |
| `packages/protocol/src/events.ts`      | Align War Room event and catch-up shapes with shared protocol contracts.                                             | \~40       |
| `packages/protocol/README_protocol.md` | Document protocol ownership for Worker client contracts and safe frame scope.                                        | \~20       |
| `apps/warroom/package.json`            | Add the workspace dependency on `@factionos/protocol` if imports are introduced.                                     | \~5        |
| `package-lock.json`                    | Sync workspace dependency metadata.                                                                                  | \~20       |
| `apps/warroom/src/index.ts`            | Enforce shared validation, deterministic errors, rejection handling, and safe socket frame persistence.              | \~260      |
| `apps/warroom/tests/warroom.test.ts`   | Expand Durable Object tests for validation, authority, stale decisions, rejection, safe frames, and catch-up bounds. | \~260      |
| `apps/warroom/tests/worker.test.ts`    | Expand top-level Worker tests for malformed codes, CORS, rate-limit envelopes, and delegated error behavior.         | \~120      |
| `apps/warroom/README_warroom.md`       | Record hardened endpoint, error, and safe-frame contract notes for later web sessions.                               | \~40       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Worker APIs reject malformed room codes, non-object JSON, bad payloads, unauthorized participants, pending socket attempts, stale approvals, stale rejections, and invalid socket frames without leaking raw request details.
* [ ] Shared contracts cover room snapshots, participant metadata, pending joins, join decisions, socket handshake frames, bounded catch-up frames, rate-limit responses, and federation errors.
* [ ] The Worker preserves room isolation, a 16-participant cap, a 100-event recent-event cap, sender-excluded broadcast, and socket close/error cleanup.
* [ ] The local Express `/warroom` boundary remains a compatibility/status stub and no local server proxy behavior is added.

### Testing Requirements

* [ ] Protocol tests cover valid and invalid contracts, enum values, bounds, unknown fields, and blocked sensitive payload categories.
* [ ] Worker Durable Object tests cover create/read/join/approve/reject/socket success and failure paths.
* [ ] Worker router tests cover malformed room codes, CORS, rate-limit headers, and delegated error envelopes.
* [ ] Focused typecheck and Vitest commands pass for `packages/protocol` and `apps/warroom`.

### Non-Functional Requirements

* [ ] War Room federation remains optional external transfer; local workflows work without Cloudflare credentials or Worker URL configuration.
* [ ] Worker diagnostics and errors use compact codes and metadata only.
* [ ] No hosted auth, hosted storage, analytics, public replay hosting, or production database dependency is introduced.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] No raw prompts, command bodies, terminal output, file contents, secrets, broad paths, exports, replay buffers, media drafts, or scan payloads are accepted into Worker persistence.

***

## 8. Implementation Notes

### Key Considerations

* Treat participant ids, display names, approver ids, colors, role fields, and socket `from` data as untrusted browser hints until the Worker validates them.
* Keep the broad cockpit collaboration event allowlist narrow or deferred. This session can define safe management frames and rejection/drop behavior, but Session 05 owns real cockpit event federation.
* Use shared protocol validators instead of duplicating ad hoc checks in the Worker wherever possible.
* Preserve existing test evidence for sender exclusion, ring caps, room persistence, and socket cleanup while hardening validation.

### Potential Challenges

* Worker package imports from `@factionos/protocol`: Add an explicit workspace dependency and confirm Wrangler/Vitest resolution still works.
* Existing tests assert loose error shapes: Update them to assert the new stable envelopes while preserving HTTP status intent.
* Rejection and leave semantics can expand quickly: Implement or document only the contract needed for later approval UX, keeping broad leave UX for Session 04.
* Socket frame validation can drift into Session 05 scope: Keep this session to safe management frames, ping, and fail-closed behavior for unknown payloads.

### Relevant Considerations

* \[P03-apps/warroom+apps/web] **War Room federation is still separate**: Worker/Durable Object sharing is not wired into the local cockpit; this session must produce contracts for later web work without claiming web federation is shipped.
* \[P03] **Redaction is boundary-specific**: Worker-safe payloads must be explicitly validated and minimized; local export, replay, log, and analytics redaction do not automatically make payloads safe for Worker transfer.
* \[P03-packages/protocol] **Protocol leads cross-package work**: Add shared contracts in `packages/protocol` before Worker and later web consumers use them.
* \[P00] **Hosted services are optional**: Cloudflare Worker use must remain optional and must not introduce hosted auth, hosted storage, analytics, or public replay dependencies.

### Behavioral Quality Focus

Checklist active: Yes

Top behavioral risks for this session:

* Schema-loose socket frames entering persistence and later catch-up before Session 05 adds broad cockpit federation.
* Stale or duplicate approval/rejection actions mutating participant state inconsistently.
* Rate-limit, room-not-found, pending, forbidden, and invalid-payload failures returning inconsistent shapes that future web UI cannot exhaustively handle.
* Sensitive local payload categories crossing the Worker boundary through unknown fields or raw exception/error copies.

***

## 9. Testing Strategy

### Unit Tests

* Add protocol tests for War Room constants, room code parsing, participant bounds, request validators, error envelope builders, safe frame validation, and blocked payload categories.
* Expand Durable Object tests for `/init`, `/info`, `/join`, `/approve`, `/reject`, `/socket`, socket messages, catch-up, sender exclusion, caps, and persistence.

### Integration Tests

* Expand top-level Worker router tests for CORS, malformed room codes, delegated Durable Object errors, and rate-limit headers/envelopes.
* Keep `wranglerDev.test.ts` opt-in and skip-aware; do not require Cloudflare credentials for normal validation.

### Manual Testing

* Run focused typecheck and Vitest commands for protocol and Worker packages.
* Optionally run `FACTIONOS_RUN_WRANGLER_DEV=1 npm test` locally when Wrangler is available to detect fake/runtime drift.

### Edge Cases

* Empty, non-object, oversized, and wrong-type JSON bodies.
* Room code casing, banned alphabet characters, missing participant ids, and unknown room paths.
* Duplicate join with existing participant id, full rooms, non-leader decisions, stale approvals, stale rejections, and pending socket attempts.
* Unknown socket event type, unknown fields, malformed JSON, ping frames, and catch-up after dropped invalid frames.
* Rate-limit responses with retry metadata and CORS headers.

***

## 10. Dependencies

### External Libraries

* `@factionos/protocol`: workspace dependency consumed by `apps/warroom` for shared contracts.
* `@cloudflare/workers-types`: existing Worker type definitions.
* `vitest`: existing root test runner.

### Other Sessions

* **Depends on**: `phase05-session01-war-room-requirements-and-trust-baseline`
* **Depended by**: `phase05-session03-web-room-lifecycle-and-state-store`, `phase05-session04-join-approval-presence-and-reconnect-ux`, `phase05-session05-federation-event-redaction-and-cockpit-integration`, `phase05-session06-deployment-environment-and-diagnostics`, `phase05-session07-war-room-validation-and-documentation-closeout`

***

## 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/phase05-session02-worker-api-hardening-and-client-contract/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.
