> 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/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.md).

# Implementation Notes

**Session ID**: `phase18-session04-idle-lifecycle-engine-parity` **Package**: apps/server **Started**: 2026-06-10 00:36 **Last Updated**: 2026-06-10 00:52

***

## Session Progress

| Metric              | Value   |
| ------------------- | ------- |
| Tasks Completed     | 25 / 25 |
| Estimated Remaining | 0 hours |
| Blockers            | 0       |

***

### Task T025 - Run Verification

**Started**: 2026-06-10 00:50 **Completed**: 2026-06-10 00:52 **Duration**: 2 minutes

**Notes**:

* Ran Biome formatting on touched TypeScript files.
* Ran server typecheck after formatting.
* Ran focused Vitest coverage for context, lifecycle, LLM, and route integration files.
* Ran ASCII/LF validation across touched session artifacts and server files.

**Files Changed**:

* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/tasks.md` - marked final verification task and completion checklist complete.
* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.md` - logged final verification results.

**BQC Fixes**:

* N/A - verification task.

***

## Verification Summary

* `npm --workspace apps/server run typecheck` - passed.
* `npx vitest run apps/server/tests/idleSuggestionContext.test.ts apps/server/tests/idleSuggestionLifecycle.test.ts apps/server/tests/llm.test.ts apps/server/tests/routes.test.ts` - passed, 54 tests.
* ASCII/LF validation for 14 touched files - passed.

***

### Task T021 - Write Context Builder Tests

**Started**: 2026-06-10 00:49 **Completed**: 2026-06-10 00:50 **Duration**: 1 minute

**Notes**:

* Added unit tests for mission context, modified-file extraction, safe path filtering, session-ID fallback, scoped recent messages, and redaction of unsafe recent-message content.

**Files Changed**:

* `apps/server/tests/idleSuggestionContext.test.ts` - new context-builder test file.

**BQC Fixes**:

* Trust boundary enforcement: tests assert unsafe absolute paths and secrets do not survive in context.

***

### Task T022 - Write Lifecycle Coordinator Tests

**Started**: 2026-06-10 00:49 **Completed**: 2026-06-10 00:50 **Duration**: 1 minute

**Notes**:

* Added unit tests for trigger, priority selection, manager writes, broadcasts, in-flight guard, cooldown, timeout fallback, destroy cleanup, and compact warning behavior.

**Files Changed**:

* `apps/server/tests/idleSuggestionLifecycle.test.ts` - new lifecycle coordinator test file.

**BQC Fixes**:

* Resource cleanup and duplicate prevention: fake-timer tests assert timer cleanup, abort signal behavior, in-flight suppression, and cooldown suppression.

***

### Task T023 - Write Idle Route and Engine Tests

**Started**: 2026-06-10 00:49 **Completed**: 2026-06-10 00:50 **Duration**: 1 minute

**Notes**:

* Extended LLM route tests for typed idle route output.
* Added parser/fallback coverage for fallback object shape, fenced arrays, extracted arrays, malformed output, generic filtering, and max-three cap.

**Files Changed**:

* `apps/server/tests/llm.test.ts` - extended idle route and engine coverage.

**BQC Fixes**:

* Contract alignment: tests assert typed engine fields are present and valid.

***

### Task T024 - Write Route Integration Coverage

**Started**: 2026-06-10 00:49 **Completed**: 2026-06-10 00:50 **Duration**: 1 minute

**Notes**:

* Added full route lifecycle coverage that posts SessionStart, UserPromptSubmit, PreToolUse, and Stop events, then polls the injected manager for a typed Quest Board suggestion.
* Updated the route harness to use a temporary suggestion state directory.

**Files Changed**:

* `apps/server/tests/routes.test.ts` - added idle lifecycle integration test and suggestion manager harness wiring.

**BQC Fixes**:

* Failure path completeness: integration coverage proves non-blocking idle generation still reaches manager state.

***

### Task T020 - Update Server README

**Started**: 2026-06-10 00:48 **Completed**: 2026-06-10 00:49 **Duration**: 1 minute

**Notes**:

* Documented automatic idle lifecycle generation, manager-owned storage, shared broadcasts, local fallback behavior, provider opt-in requirements, and server-only scope.

**Files Changed**:

* `apps/server/README_server.md` - added idle lifecycle generation documentation.

**BQC Fixes**:

* N/A - documentation-only task.

***

### Task T010 - Implement Lifecycle Idle Trigger

**Started**: 2026-06-10 00:42 **Completed**: 2026-06-10 00:45 **Duration**: 3 minutes

**Notes**:

* Added `handleHeroIdleTransition` keyed by stable session ID with hero-ID fallback handled by the context builder.
* Added duplicate-trigger suppression through an in-flight map before async generation begins.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added idle trigger entry point and in-flight guard.

**BQC Fixes**:

* Duplicate action prevention: repeated idle transitions for the same session are rejected while generation is running.

***

### Task T011 - Implement Cooldown Checks

**Started**: 2026-06-10 00:42 **Completed**: 2026-06-10 00:45 **Duration**: 3 minutes

**Notes**:

* Added a 60-second default cooldown keyed by session ID.
* Clock injection keeps cooldown behavior deterministic in tests.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added cooldown state and injectable clock.

**BQC Fixes**:

* Duplicate action prevention: cooldown checks suppress duplicate generation after a successful trigger.

***

### Task T012 - Implement Timeout and Late Suppression

**Started**: 2026-06-10 00:42 **Completed**: 2026-06-10 00:45 **Duration**: 3 minutes

**Notes**:

* Added an 18-second default timeout with abort signal propagation.
* Late results are ignored when the generation token no longer matches the active in-flight record.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added timeout race, abort controller, and late-result guard.

**BQC Fixes**:

* Resource cleanup: timeout timers are cleared in `finally`; destroy aborts pending generation and clears timers.
* Concurrency safety: generation tokens prevent stale async results from writing manager state.

***

### Task T013 - Implement Manager Write Path

**Started**: 2026-06-10 00:43 **Completed**: 2026-06-10 00:45 **Duration**: 2 minutes

**Notes**:

* Stored selected typed suggestions through `SuggestionManager.createIdleSuggestion`.
* Added exact-match idempotency protection before writing the same active session suggestion again.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added manager persistence path.

**BQC Fixes**:

* Failure path completeness: manager validation/write failures return `manager_error` and emit compact warnings without raw context.

***

### Task T014 - Wire Suggestion Broadcast Path

**Started**: 2026-06-10 00:43 **Completed**: 2026-06-10 00:45 **Duration**: 2 minutes

**Notes**:

* Used `emitSuggestionMutationUpdate` after manager writes so automatic generation shares the existing canonical snapshot and compatibility frame path.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added shared broadcast helper call.

**BQC Fixes**:

* Contract alignment: automatic lifecycle updates now use the same event contract as REST mutations.

***

### Task T015 - Wire Server Runtime

**Started**: 2026-06-10 00:45 **Completed**: 2026-06-10 00:47 **Duration**: 2 minutes

**Notes**:

* Instantiated `IdleSuggestionLifecycleCoordinator` in `createFactionOsServer`.
* Injected it into `eventRouter` and destroyed it before `SuggestionManager.destroy()` during shutdown.

**Files Changed**:

* `apps/server/src/server.ts` - wired coordinator construction, route injection, and shutdown ordering.

**BQC Fixes**:

* Resource cleanup: server shutdown now clears lifecycle async resources before manager teardown.

***

### Task T016 - Wire Event Route Activity Recording

**Started**: 2026-06-10 00:45 **Completed**: 2026-06-10 00:47 **Duration**: 2 minutes

**Notes**:

* Recorded compact lifecycle activity for session start, mission start, file access, bash command, permission request, tool result, input received, opaque event labels, and hero idle.
* Avoided raw prompt, command, patch, transcript, provider payload, and broad preview storage in route-level activity messages.

**Files Changed**:

* `apps/server/src/routes/event.ts` - added lifecycle activity recording.

**BQC Fixes**:

* Trust boundary enforcement: activity passed to lifecycle storage is limited to labels, safe paths, and compact status strings.

***

### Task T017 - Trigger Idle Generation After Idle State

**Started**: 2026-06-10 00:45 **Completed**: 2026-06-10 00:47 **Duration**: 2 minutes

**Notes**:

* Triggered generation only after `roster.update(... state: "idle")` and `hero_state` emission.
* Fire-and-forget route call prevents `/event` from awaiting LLM generation.

**Files Changed**:

* `apps/server/src/routes/event.ts` - added non-blocking idle lifecycle trigger.

**BQC Fixes**:

* Failure path completeness: unexpected trigger rejection emits a compact warning toast instead of causing an unhandled rejection.

***

### Task T018 - Update Idle Suggestion Route

**Started**: 2026-06-10 00:47 **Completed**: 2026-06-10 00:48 **Duration**: 1 minute

**Notes**:

* Kept `POST /llm/idle-suggestion` on the upgraded typed engine output.
* Compatibility `idle_suggestion` frames now emit candidate `text` while the JSON response preserves the typed suggestion objects.

**Files Changed**:

* `apps/server/src/routes/llm.ts` - adjusted compatibility frame payload.

**BQC Fixes**:

* Contract alignment: route output stays `{ suggestions: [...] }` while typed fields are retained.

***

### Task T019 - Add Compact Warning Behavior

**Started**: 2026-06-10 00:43 **Completed**: 2026-06-10 00:48 **Duration**: 5 minutes

**Notes**:

* Added lifecycle logger warnings for generation timeouts/errors and manager write failures.
* Warning context includes only stable reason codes, session ID, and hero ID.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added compact warning paths.
* `apps/server/src/routes/event.ts` - added compact trigger rejection toast.

**BQC Fixes**:

* Error information boundaries: warnings do not include raw paths, prompts, transcripts, provider payloads, or secrets.

***

### Task T004 - Create Idle Suggestion Context Builder

**Started**: 2026-06-10 00:37 **Completed**: 2026-06-10 00:42 **Duration**: 5 minutes

**Notes**:

* Added a pure context builder for hero, mission, recent-message, and modified-file inputs.
* Implemented conservative path handling: relative paths survive, absolute paths survive only when they can be made relative to a known base directory.
* Bounded recent activity and sanitized prompt, summary, and message text through the existing LLM privacy helpers.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionContext.ts` - new pure context builder and safe path helpers.

**BQC Fixes**:

* Trust boundary enforcement: safe IDs, path normalization, absolute-path rejection, and text redaction are applied before context leaves the builder.

***

### Task T005 - Create Lifecycle Coordinator Shell

**Started**: 2026-06-10 00:38 **Completed**: 2026-06-10 00:42 **Duration**: 4 minutes

**Notes**:

* Added lifecycle coordinator options for `SuggestionManager`, `Broadcaster`, generation injection, clock injection, cooldown, timeout, project root, and compact logger.
* Added a `destroy()` contract that aborts pending generation and clears timers, in-flight state, cooldowns, and bounded recent messages.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - new injectable lifecycle coordinator.

**BQC Fixes**:

* Resource cleanup: acquired timeout timers and abort controllers are owned centrally and released on generation completion or destroy.

***

### Task T006 - Add Recent Session Activity Recording

**Started**: 2026-06-10 00:39 **Completed**: 2026-06-10 00:42 **Duration**: 3 minutes

**Notes**:

* Added bounded per-session recent activity storage keyed by stable session ID with hero-ID fallback.
* Added reset behavior on destroy so old lifecycle context cannot leak into a later runtime scope.

**Files Changed**:

* `apps/server/src/lib/idleSuggestionLifecycle.ts` - added `recordSessionActivity` and bounded storage.

**BQC Fixes**:

* State freshness on re-entry: destroy clears in-memory activity and generation state before manager teardown.

***

### Task T007 - Extend Idle Engine Types

**Started**: 2026-06-10 00:39 **Completed**: 2026-06-10 00:42 **Duration**: 3 minutes

**Notes**:

* Replaced the string-only internal suggestion shape with typed candidate output containing title, text, prompt, category, and priority.
* Preserved route compatibility by keeping `generateIdleSuggestions` as the route-facing function that returns an array.

**Files Changed**:

* `apps/server/src/llm/engines/idleSuggestionEngine.ts` - added typed engine input and output contracts.

**BQC Fixes**:

* Contract alignment: engine output now matches the fields required by `SuggestionManager.createIdleSuggestion`.

***

### Task T008 - Implement Idle Engine Parser Support

**Started**: 2026-06-10 00:40 **Completed**: 2026-06-10 00:42 **Duration**: 2 minutes

**Notes**:

* Added parser support for direct arrays, fenced JSON, extracted arrays, extracted objects, and object payloads with `suggestions` arrays.
* Added normalization for string and object suggestions with explicit filtering before capping at three suggestions.

**Files Changed**:

* `apps/server/src/llm/engines/idleSuggestionEngine.ts` - added parser and normalization helpers.

**BQC Fixes**:

* Failure path completeness: malformed or unusable LLM output now falls through to deterministic fallback generation instead of silently returning an empty route response.

***

### Task T009 - Implement Deterministic Fallback Builder

**Started**: 2026-06-10 00:40 **Completed**: 2026-06-10 00:42 **Duration**: 2 minutes

**Notes**:

* Added local fallback candidates derived from safe modified-file hints, completed task text, completion summary, or bounded recent activity.
* Kept generic suggestion filtering active for both LLM and fallback candidates.

**Files Changed**:

* `apps/server/src/llm/engines/idleSuggestionEngine.ts` - added deterministic fallback builder.

**BQC Fixes**:

* Failure path completeness: missing provider transfer, malformed responses, generic output, and empty responses have a local typed fallback path when safe context exists.

***

### Task T003 - Verify Idle Engine and Privacy Boundary

**Started**: 2026-06-10 00:35 **Completed**: 2026-06-10 00:37 **Duration**: 2 minutes

**Notes**:

* Verified `generateIdleSuggestions` currently calls `complete` through the shared `llmClient` and sanitizes prompt text with `sanitizeLlmText`.
* Verified provider transfer remains behind the two-level `ANTHROPIC_API_KEY` plus `FACTIONOS_ALLOW_LLM_PROVIDER_TRANSFER` gate in `llmClient` and `llmPrivacy`.
* Verified `safeParseArray` only accepts top-level or fenced arrays, while the local `llmClient` fallback returns an object containing `suggestions`, causing fallback suggestions to be dropped.

**Files Changed**:

* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/tasks.md` - marked verification task complete.
* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.md` - logged engine verification.

**BQC Fixes**:

* N/A - verification-only task.

***

### Task T002 - Verify Event Ingest Idle Flow

**Started**: 2026-06-10 00:35 **Completed**: 2026-06-10 00:37 **Duration**: 2 minutes

**Notes**:

* Verified `hero_idle` handling resolves the ingest hero, completes the active mission, emits `mission_complete`, posts lifecycle notices, updates the hero to `idle`, and then emits `hero_state`.
* Verified existing route tests cover SessionStart, UserPromptSubmit, tool-use, PostToolUse, and Stop state transitions through session aliases.

**Files Changed**:

* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/tasks.md` - marked verification task complete.
* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.md` - logged event-flow verification.

**BQC Fixes**:

* N/A - verification-only task.

***

### Task T001 - Verify Session 01-03 Artifacts

**Started**: 2026-06-10 00:34 **Completed**: 2026-06-10 00:36 **Duration**: 2 minutes

**Notes**:

* Confirmed `analyze-project.sh` reports Session 01, 02, and 03 complete for Phase 18.
* Confirmed current session targets `apps/server` and package prerequisites pass.
* Confirmed `SuggestionManager`, `emitSuggestionMutationUpdate`, event ingest, and current idle route artifacts exist.

**Files Changed**:

* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/tasks.md` - marked verification task complete.
* `.spec_system/specs/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.md` - logged setup verification.

**BQC Fixes**:

* N/A - verification-only task.

***

## Task Log

### 2026-06-10 - Session Start

**Environment verified**:

* [x] Prerequisites confirmed
* [x] Tools available
* [x] Directory structure ready

***


---

# 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/phase18-session04-idle-lifecycle-engine-parity/implementation-notes.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.
