> 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/specs/phase24-session02-camp-mission-linkage/tasks.md).

# Task Checklist

**Session ID**: `phase24-session02-camp-mission-linkage` **Total Tasks**: 16 **Estimated Duration**: 2.5-3.5 hours **Created**: 2026-07-08

***

## Legend

* `[x]` = Completed
* `[ ]` = Pending
* `[P]` = Parallelizable (can run with other \[P] tasks)
* `[S2402]` = Session reference (phase 24, session 02)
* `TNNN` = Task ID

***

## Progress Summary

| Category       | Total  | Done   | Remaining |
| -------------- | ------ | ------ | --------- |
| Setup          | 2      | 2      | 0         |
| Foundation     | 6      | 6      | 0         |
| Implementation | 5      | 5      | 0         |
| Testing        | 6      | 6      | 0         |
| **Total**      | **19** | **19** | **0**     |

***

## Setup (2 tasks)

* [x] T001 \[S2402] Verify prerequisites: baseline web typecheck clean; re-read `recordProjectionPendingLink`, `reduceMissionStart`, `normalizePendingLinkPrompt`, and `MAX_PENDING_LINKS` in `apps/web/src/lib/gameProjection.ts` and the accept/assign flows plus `foldGameProjection` guard shape in `apps/web/src/store/useGameStore.ts`.
* [x] T002 \[S2402] Locate the existing store quest tests that cover `acceptQuestSuggestion`/`assignQuestSuggestion` (expected `apps/web/tests/questBoardStore.test.ts`) and note their mock-fetch fixture pattern for reuse.

***

## Foundation (6 tasks)

### apps/server

* [x] T003a \[S2402] Extend `acceptSuggestion` in `apps/server/src/managers/suggestionManager.ts` to fall through to current (non-dismissed) codebase issues when no idle suggestion matches: return a prompt-bearing accepted value using the issue's `suggestedPrompt` and `suggestedAgentType`-neutral hero resolution, without dismissing or mutating the issue (accept is dispatch, not resolution), preserving idempotent in-flight guards.
* [x] T003b \[S2402] Verify the accept route in `apps/server/src/routes/suggestions.ts` serves issue accepts through the unchanged `SuggestionAcceptResponse` shapes (send\_prompt with resolved hero, prompt\_sent fallback) with no new route or response variant.

### apps/web

* [x] T003 \[S2402] \[P] Add `legionCampIdForIssueId(camps, issueId)` to `apps/web/src/lib/legionCamps.ts`: pure lookup over camp `issueIds` returning `CampId | null`; trims input, returns null for empty/unknown ids, deterministic on duplicate membership (first by sorted camp id).
* [x] T004 \[S2402] \[P] Add `campMissionsFromLinks(campLinks)` to `apps/web/src/lib/gameProjection.ts`: pure inverse derivation returning a sorted `Record<CampId, MissionId[]>` for joint-assault rendering.
* [x] T005 \[S2402] Add `selectGameCampMissions` selector to `apps/web/src/store/useGameStore.ts` delegating to `campMissionsFromLinks` over the current projection.
* [x] T006 \[S2402] Add a store-internal helper `recordQuestCampPendingLink({campId, heroId, prompt})` in `apps/web/src/store/useGameStore.ts` that applies `recordProjectionPendingLink` inside `set`, skips state churn on reference-equal no-ops, and persists via `shouldPersistGameProjection`/`scheduleGameProjectionPersist` with the same replay/mock persist-context capture as `foldGameProjection`.

***

## Implementation (5 tasks)

* [x] T006b \[S2402] Add accept/assign capabilities to codebase-issue cards in `apps/web/src/lib/questBoardModel.ts` (`accept: { suggestionId: issue.id }`, `assign: { suggestionId: issue.id }`) so camp quests are actionable through the existing accept flow.
* [x] T007 \[S2402] Capture the card's issue id (from `actions.dismissIssue?.issueId`) and resolve its camp id via `legionCampIdForIssueId` before optimistic removal in `acceptQuestSuggestion` (`apps/web/src/store/useGameStore.ts`).
* [x] T008 \[S2402] On accept success, record the pending link only when the response is `send_prompt` (hero id known) and a camp id resolved, using the verbatim response `prompt`; exhaustive handling of both response `action` variants with no recording on `prompt_sent` (`apps/web/src/store/useGameStore.ts`).
* [x] T009 \[S2402] Mirror the wiring in `assignQuestSuggestion`: record with the response hero id for `send_prompt` and the explicitly assigned `heroId` parameter for `prompt_sent`, camp-gated the same way (`apps/web/src/store/useGameStore.ts`).
* [x] T010 \[S2402] Ensure failure and rollback paths record nothing: the recording call sits strictly after the `result.ok` success branch, with duplicate-trigger protection left to `recordProjectionPendingLink` (`apps/web/src/store/useGameStore.ts`).
* [x] T011 \[S2402] Review pass: no new storage keys or authorities, prompt stays bounded by `normalizePendingLinkPrompt`, no raw fields added to persisted state, Biome clean.

***

## Testing (6 tasks)

### apps/server

* [x] T011b \[S2402] \[P] Add issue-accept tests to `apps/server/tests/suggestionManager.test.ts` and `apps/server/tests/suggestionRoutes.test.ts`: accept by issue id returns the suggested prompt, dismissed issues 404, issue remains in snapshots after accept, idle suggestions keep precedence on id collision.

### apps/web

* [x] T012 \[S2402] \[P] Add `legionCampIdForIssueId` tests (hit, miss, empty, duplicate membership determinism) to `apps/web/tests/legionCamps.test.ts`.
* [x] T013 \[S2402] \[P] Add `campMissionsFromLinks` tests (empty, single, multi-mission per camp, sorted output) to `apps/web/tests/gameProjection.test.ts`.
* [x] T014 \[S2402] Add store recording tests: accept success with `send_prompt` records; accept `prompt_sent` records nothing; assign `prompt_sent` records with assigned hero; no-camp card records nothing; failed action records nothing (extend the existing quest store test file).
* [x] T015 \[S2402] Add guard and end-to-end tests: with `replayingSinceMs` set or `mockEnabled` true recording folds in memory but schedules no persist; accept then `mission_start` with matching hero/prompt binds `campLinks` and consumes the pending link; `selectGameCampMissions` reflects the binding.
* [x] T016 \[S2402] Run gates: full web project tests from repo root (`npx vitest run --project web`), web typecheck, Biome check on changed files, ASCII/LF validation; update implementation-notes.md.

***

## Completion Checklist

Before marking session complete:

* [ ] All tasks marked `[x]`
* [ ] All tests passing
* [ ] All files ASCII-encoded
* [ ] implementation-notes.md updated
* [ ] Ready for `/validate`

***

## Next Steps

Run `/implement` 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/specs/phase24-session02-camp-mission-linkage/tasks.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.
