> 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-session01-pure-strike-and-combo-model/tasks.md).

# Task Checklist

**Session ID**: `phase24-session01-pure-strike-and-combo-model` **Total Tasks**: 18 **Estimated Duration**: 2.5-3.5 hours **Created**: 2026-07-08

***

## Legend

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

***

## Progress Summary

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

***

## Setup (2 tasks)

* [x] T001 \[S2401] Verify prerequisites: web workspace typecheck and existing focused tests run clean (`cd apps/web && npx tsc -b --noEmit`); confirm `ToolUse`/`ToolResultEvent` shapes in `packages/protocol/src/missions.ts` and `packages/protocol/src/events.ts` and `toolCategoryFor` in `apps/web/src/lib/toolUsage.ts`.
* [x] T002 \[S2401] Create `apps/web/src/lib/combatPlayback.ts` with module doc comment stating the purity contract (no store/React/DOM/audio imports, type-only protocol imports, explicit timestamps, no Date.now()).

***

## Foundation (5 tasks)

* [x] T003 \[S2401] Define strike vocabulary types in `apps/web/src/lib/combatPlayback.ts`: `StrikeKind` ("hammer" | "fire" | "scout" | "peon" | "strike" | "counterattack"), `StrikeCategory`, combo state, rate-limit history, and stage-prop tier types with exhaustive enum handling.
* [x] T004 \[S2401] Define named exported tuning constants (`STRIKE_MAX_DURATION_MS` = 400, `COMBO_WINDOW_MS`, `COMBO_MAX_STAGE`, `STAGE_PROP_MILESTONES_MS`, `SFX_RATE_LIMIT_PER_MINUTE`, `STRIKE_LABEL_MAX_LENGTH`, history bounds) in `apps/web/src/lib/combatPlayback.ts`.
* [x] T005 \[S2401] Implement `classifyStrike(toolName)` mapping every known `ToolName` to a strike kind with a generic `strike` fallback for unknown, custom MCP, empty, or whitespace tool names (never throws).
* [x] T006 \[S2401] Implement `classifyToolResult(ok)` / counterattack derivation: failed results produce `counterattack`, successful results produce no strike.
* [x] T007 \[S2401] Implement `comboKeyFor(targetId, category)` shared key helper so later sessions key accumulators identically.

***

## Implementation (6 tasks)

* [x] T008 \[S2401] Implement combo accumulator `advanceComboState(state, category, timestampMs)`: escalate stages within `COMBO_WINDOW_MS`, cap at `COMBO_MAX_STAGE`, reset after quiet, return same reference on no-op, prune entries older than the window (bounded memory over long missions).
* [x] T009 \[S2401] Implement visual emission derivation `strikeEmissionsFor(state, strike)`: whether a new strike renders as a fresh strike or merges into the existing combo stage, with tolerance for out-of-order timestamps (clamp to last-seen time; document the contract).
* [x] T010 \[S2401] Implement `stagePropsForElapsed(elapsedMs)`: monotonic non-decreasing prop tier from `STAGE_PROP_MILESTONES_MS`; negative or zero elapsed returns tier 0.
* [x] T011 \[S2401] Implement `shouldPlayCue(category, historyMs, nowMs)` pure rate-limit decision: allow while under `SFX_RATE_LIMIT_PER_MINUTE` in the trailing minute, deny after, independent per category; return pruned history so callers keep bounded state.
* [x] T012 \[S2401] Implement safe strike label derivation `safeStrikeLabel(toolName, path?)`: bounded length, relative-path style reusing the sector-label approach from `apps/web/src/lib/legionCamps.ts`, never passing through `inputPreview`, absolute paths, or raw command text.
* [x] T013 \[S2401] Final module review pass: exports complete for Sessions 03/04/06 consumption, no scope creep into camp/HP/link logic, Biome format/lint clean.

***

## Testing (5 tasks)

* [x] T014 \[S2401] \[P] Write classification and label tests in `apps/web/tests/combatPlayback.test.ts`: full `ToolName` table, custom MCP names, empty/whitespace names, counterattack mapping, and privacy checks (no absolute paths, no `inputPreview` content, length bound enforced).
* [x] T015 \[S2401] \[P] Write combo, stage-prop, and rate-limit tests in `apps/web/tests/combatPlayback.test.ts`: stage progression/cap/reset, per-key independence, milestone boundaries, window-edge allow/deny, category independence, bounded history after long streams.
* [x] T016 \[S2401] Write the simulated 45-minute stream test in `apps/web/tests/combatPlayback.test.ts`: 1200+ mixed events with bursts and quiet gaps, asserting bounded visual emissions, bounded cue allowances per category, and bounded accumulator sizes.
* [x] T017 \[S2401] Run focused suite and gates: `npx vitest run tests/combatPlayback.test.ts` from `apps/web`, web typecheck, root `npm run format:check` on changed files.
* [x] T018 \[S2401] Validate ASCII encoding and LF line endings on both new files; update implementation-notes.md with decisions and constant values.

***

## 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-session01-pure-strike-and-combo-model/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.
