> 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/phase17-session09-automatic-mission-lifecycle-posts/spec.md).

# Session Specification

**Session ID**: `phase17-session09-automatic-mission-lifecycle-posts` **Phase**: 17 - Notice Board Coordination Parity **Status**: Completed **Created**: 2026-06-05 **Package**: apps/server **Package Stack**: TypeScript local server, Express 5, WebSocket broadcaster, Vitest

***

## 1. Session Overview

This session restores automatic Notice Board posts for real mission lifecycle events in the local server. Earlier Phase 17 sessions established the canonical Notice Board model, persistence, routes, WebSocket events, CLI and hook context access, War Room relay, and room convergence. The remaining runtime gap is that real mission start and mission completion events should create concise coordination notices without turning every hook event into a Notice Board feed.

The work is server-only and should wire into the existing `/event` mission lifecycle path. `apps/server/src/routes/event.ts` already materializes heroes, starts missions, records tool use, and completes missions from hook payloads. This session should add a narrow automatic-post helper around that lifecycle path, using `NoticeBoard.autoPost` for recovered 30 second dedupe and using the Session 08 bridge to broadcast and optionally relay accepted notices.

Privacy remains the controlling constraint. Automatic notices are explicit coordination summaries only: `Started: <name>` and `Done: <summary>`. They must not contain raw prompts, transcripts, terminal output, command bodies, file contents, secrets, absolute paths, raw hook payloads, logs, diagnostics, replay buffers, exports, scans, media drafts, backups, or quarantined historical content. Raw hook events remain mission telemetry and must not become Notice Board spam.

***

## 2. Objectives

1. Add mission-start `status` auto-posts for real mission lifecycle starts with 30 minute expiration, recovered dedupe, local broadcast, and optional relay.
2. Add mission-completion `completion` auto-posts for real mission lifecycle summaries with one hour expiration, recovered dedupe, local broadcast, and optional relay.
3. Map active room id, author session id, author name, machine id, avatar, and safe related files when available without leaking sensitive payloads.
4. Add focused tests proving dedupe, expiration, privacy filtering, relay forwarding, raw-event separation, and real-mode population without mock data.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase17-session02-server-notice-manager-persistence-and-context` - provides `NoticeBoard.autoPost`, persistence, room filtering, expiration, and recovered 30 second automatic-post dedupe.
* [x] `phase17-session03-server-routes-and-websocket-parity` - provides local `notice_board_message` broadcasts and canonical Notice Board route behavior.
* [x] `phase17-session08-local-war-room-bridge-and-room-notice-convergence` - provides optional local-to-War Room notice relay forwarding and standalone local no-op behavior.

### Required Tools/Knowledge

* Node 26.2.0 or newer with npm workspaces.
* Existing `apps/server` event ingest route and Vitest harnesses.
* Existing Notice Board manager, route broadcast helpers, and War Room bridge.
* Existing hook payload normalization and sensitive-field redaction rules.

### Environment Requirements

* Work from the repository root.
* Use package-relative monorepo paths from the repo root.
* Keep all generated and edited files ASCII-only with Unix LF line endings.
* Tests must use fake clocks, temporary Notice Board state directories, fake broadcasters, and fake relay senders; no Cloudflare credentials or live Worker are required.

***

## 4. Scope

### In Scope (MVP)

* Real mission start handling posts a deduped `status` notice with content `Started: <name>` and expiration around 30 minutes.
* Real mission completion handling posts a deduped `completion` notice with content `Done: <summary>` and expiration around one hour.
* Automatic posts use active room id from the server's War Room notice relay runtime resolver when present, otherwise the local standalone room id.
* Automatic posts use hero/session metadata for `authorSessionId`, `authorName`, `authorMachineId`, `authorAvatarUrl`, and `authorType: "agent"` when available.
* Related files are derived only from safe mission tool-use paths that normalize to project-relative Notice Board paths.
* Accepted automatic posts emit local `notice_board_message` frames and forward through the existing War Room notice bridge when connected.
* Duplicate automatic posts for the same room, author session, and type inside 30 seconds are suppressed by `NoticeBoard.autoPost`.
* Mission labels and summaries are concise, bounded, and filtered for secrets, absolute paths, raw commands, terminal output, patch bodies, transcripts, and file contents.
* Raw hook events, opaque events, tool events, and mock generator activity stay separate from automatic Notice Board messages unless they are real mission lifecycle start or completion events.
* Focused tests prove mission name generation creates deduped `status` notices, mission summary generation creates deduped `completion` notices, and real `FACTIONOS_MOCK=false` style sessions populate the board.

### Out of Scope (Deferred)

* Manual CLI posts - Reason: completed in Session 05.
* Hook context lookup - Reason: completed in Session 06.
* Web UI rendering - Reason: completed in Session 04.
* Worker relay implementation - Reason: completed in Session 07.
* New Notice Board message types or UI affordances - Reason: this session only restores recovered automatic lifecycle posts.
* Hosted identity, hosted storage, analytics capture, public replay hosting, remote execution, Docker execution, or trusted unified erasure claims - Reason: these remain explicit no-claims.

***

## 5. Technical Approach

### Architecture

Create a narrow server helper for mission lifecycle Notice Board posts. The helper should accept a `NoticeBoard`, `Broadcaster`, optional `WarRoomNoticeBridge`, active-room resolver, clock, and project root. It should expose explicit `postMissionStarted` and `postMissionCompleted` operations that take normalized mission, hero, and ingest metadata rather than raw request bodies. Each operation calls `NoticeBoard.autoPost`, emits `notice_board_message` only when a notice was accepted, then asks the bridge to forward the notice.

Wire the helper into `eventRouter` through injected dependencies from `createFactionOsServer`. The route should continue to handle raw lifecycle and tool telemetry exactly as it does today. Automatic Notice Board behavior should run only after a mission is actually started or completed, and only for the accepted mission lifecycle path.

Use existing protocol helpers where possible for Notice Board validation and safe relative file normalization. The helper should prefer explicit mission name fields when available, fall back to a bounded safe label, and degrade to a generic local label rather than leaking sensitive prompt text. Summary handling should similarly prefer the bounded mission completion summary and drop or redact unsafe content.

### Design Patterns

* Canonical manager write: use `NoticeBoard.autoPost` so recovered dedupe, expiration, room filtering, persistence, and normalization remain manager owned.
* Injected runtime dependencies: event routes receive notices, bridge, active room resolver, and clock through server construction for deterministic tests.
* Fail-closed privacy filtering: unsafe labels, summaries, related files, and metadata are omitted or redacted before calling the manager.
* Additive event behavior: mission telemetry remains unchanged; automatic notices are an extra coordination side effect only on mission lifecycle starts and completions.
* Optional relay: bridge forwarding remains no-op when disconnected and emits compact failure toasts only through existing bridge failure behavior.

### Technology Stack

* TypeScript in `apps/server`.
* Express local REST route for `/event`.
* Existing `Broadcaster` WebSocket event fanout.
* Existing `NoticeBoard` manager and `WarRoomNoticeBridge`.
* Vitest with temporary filesystem state and fake clocks.
* No new runtime dependencies.

***

## 6. Deliverables

### Files to Create

| File                                                | Purpose                                                                                                                                                                 | Est. Lines |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/server/src/lib/missionLifecycleNotices.ts`    | Automatic mission-start and mission-completion Notice Board publisher, metadata mapping, privacy filtering, related-file normalization, broadcast, and relay forwarding | \~260      |
| `apps/server/tests/missionLifecycleNotices.test.ts` | Focused helper tests for start/completion content, expiration, dedupe, safe metadata, related files, privacy blocking, broadcast, and bridge forwarding                 | \~340      |

### Files to Modify

| File                                          | Changes                                                                                                                                              | Est. Lines |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/server/src/routes/event.ts`             | Inject lifecycle notice publisher and call it only after accepted mission start and mission completion paths                                         | \~120      |
| `apps/server/src/server.ts`                   | Instantiate shared active-room resolver and pass notices, broadcaster, bridge, and lifecycle publisher dependencies into the event router            | \~60       |
| `apps/server/tests/eventIngest.test.ts`       | Extend route harness with Notice Board dependencies and assert real hook lifecycle produces deduped status/completion notices without raw-event spam | \~180      |
| `apps/server/tests/routes.test.ts`            | Add server-level real-mode route coverage proving `/event` populates `/notice-board` when `mock: false`                                              | \~120      |
| `apps/server/tests/noticeBoardRoutes.test.ts` | Add or adjust assertions only if automatic posts require shared route helper behavior for relay failure toasts or active-room resolution             | \~60       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Mission start generation creates one deduped `status` notice per room, author session, and type inside the 30 second window.
* [ ] Mission completion generation creates one deduped `completion` notice per room, author session, and type inside the 30 second window.
* [ ] Status notices expire around 30 minutes after creation.
* [ ] Completion notices expire around one hour after creation.
* [ ] Automatic posts include active room id, author session id, author name, machine id, optional avatar, and safe related files when available.
* [ ] Automatic posts emit local `notice_board_message` events.
* [ ] Automatic posts forward through the War Room notice bridge when connected and degrade cleanly when disconnected.
* [ ] Raw hook, tool, opaque, prompt, transcript, terminal, command, and file content payloads do not become Notice Board messages.
* [ ] Real `mock: false` server sessions populate the board without static demo or mock generator behavior.

### Testing Requirements

* [ ] Unit tests written and passing for lifecycle notice helper behavior.
* [ ] Route-level event ingest tests written and passing for real mission lifecycle start and completion.
* [ ] Server-level route test written and passing for `/event` to `/notice-board` population with `mock: false`.
* [ ] Focused package test command run for touched server tests.

### Non-Functional Requirements

* [ ] Automatic notice content is bounded, concise, and coordination-only.
* [ ] No raw prompts, transcripts, terminal output, command bodies, file contents, secrets, absolute paths, logs, exports, replay buffers, scans, media drafts, diagnostics, backups, or quarantined historical content are shared, persisted, relayed, or logged.
* [ ] Local server `/warroom` remains a compatibility/status stub, not a Worker proxy.
* [ ] Hosted identity, hosted storage, analytics, public replay, production auditability, public collaboration safety, remote execution, Docker execution, and trusted unified erasure remain no-claims.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] No new runtime dependencies.

***

## 8. Implementation Notes

### Key Considerations

* `NoticeBoard.autoPost` already owns recovered 30 second dedupe by room, author session, and type. The lifecycle helper should not reimplement that behavior.
* `eventRouter` currently has no Notice Board dependency. This session should extend its dependency interface without disturbing current mission, tool, lineage, and opaque-event behavior.
* Session 08 bridge forwarding is already optional and no-op when disconnected. Reuse that behavior instead of adding any local Worker proxy route.
* Mission prompts in `Mission.prompt` are documented as verbatim user prompts. Do not blindly put them into notice content. Prefer explicit safe name fields and use bounded fallback labels when needed.
* Related file paths must be normalized to safe project-relative paths before they become Notice Board related files.

### Potential Challenges

* Mission name source ambiguity: Prefer hook-provided `name` when available and fall back to a generic or redacted mission label if the only candidate is raw prompt text.
* Duplicate lifecycle inputs: Let `NoticeBoard.autoPost` suppress duplicates and add route tests for repeated start/stop payloads inside the window.
* Related-file safety: Tool-use paths can be absolute or redacted. Use project-root normalization and drop unsafe entries instead of failing the lifecycle notice.
* Relay failure handling: Keep accepted local posts even when optional relay forwarding fails, and surface only compact failure toasts.

### Relevant Considerations

* \[P01-apps/server] **Anthropic transfer is two-level opt-in**: This session must not add provider transfer or use provider credentials to generate notice text.
* \[P06-apps/warroom+apps/web] **War Room federation is optional and redacted**: Automatic notices may relay only concise coordination messages and must not imply hosted identity, public collaboration safety, production auditability, certification, or full erasure.
* \[P07] **Redaction is boundary-specific**: Lifecycle notices cross local broadcast, persistence, and optional relay boundaries, so minimization is required before manager writes.
* \[P03-apps/server] **Local server boundary must stay conservative**: Preserve loopback-first, auth, CORS, rate-limit, request validation, and unsupported route boundaries.
* \[P03] **Stable docs are the current contract**: Do not copy code from `EXAMPLES/`; port behavior into current source patterns only.

### Behavioral Quality Focus

Checklist active: Yes

Top behavioral risks for this session:

* Automatic posts could leak raw prompt, command, transcript, path, or file content data if labels and summaries are copied directly.
* Duplicate lifecycle hook events could spam the Notice Board without recovered dedupe and in-flight guards.
* Optional relay failures could incorrectly block local Notice Board state or expose raw error payloads.

***

## 9. Testing Strategy

### Unit Tests

* Test lifecycle helper `postMissionStarted` creates `status` notices with content prefix, expiration, author metadata, active room, local broadcast, relay forwarding, and dedupe behavior.
* Test lifecycle helper `postMissionCompleted` creates `completion` notices with content prefix, one hour expiration, related files, local broadcast, relay forwarding, and dedupe behavior.
* Test privacy filtering drops or redacts raw prompt-like text, absolute paths, command strings, patch bodies, transcript fields, token-like values, and unsafe related files.

### Integration Tests

* Extend `/event` route harness to include `NoticeBoard`, fake bridge, and fake active-room resolver, then replay real hook lifecycle payloads and assert Notice Board outputs.
* Add server-level `mock: false` route coverage proving POST `/event` creates notices visible through GET `/notice-board`.
* Assert tool, opaque, permission, file access, bash, and input events do not create additional automatic notices.

### Manual Testing

* Start the local server with `FACTIONOS_MOCK=false`, send a small SessionStart -> UserPromptSubmit -> Stop payload sequence, and inspect `/notice-board` for one status and one completion notice.
* Repeat the same lifecycle inside 30 seconds and verify duplicates are suppressed.

### Edge Cases

* Missing session id: use safe local fallback or skip auto-post when an author session cannot be normalized.
* Missing mission summary: skip completion auto-post or use a generic bounded completion label only if it does not leak raw content.
* Absolute or unsafe related paths: omit them instead of storing or relaying them.
* Disconnected War Room bridge: local broadcast and persistence still succeed.

***

## 10. Dependencies

### External Libraries

* None.

### Other Sessions

* **Depends on**: `phase17-session02-server-notice-manager-persistence-and-context`, `phase17-session03-server-routes-and-websocket-parity`, `phase17-session08-local-war-room-bridge-and-room-notice-convergence`
* **Depended by**: `phase17-session10-validation-documentation-and-handoff`

***

## 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/phase17-session09-automatic-mission-lifecycle-posts/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.
