> 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-session04-combat-playback-effects-layer/spec.md).

# Session Specification

**Session ID**: `phase24-session04-combat-playback-effects-layer` **Phase**: 24 - Legion II - Live Tier And Combat Playback **Status**: Not Started **Created**: 2026-07-08 **Base Commit**: 6e5af583288dbe9dfd9ca58c55ac0f5d8865831c **Package**: apps/web **Package Stack**: TypeScript

***

## 1. Session Overview

This session ships the combat playback effects layer for linked Legion camps. Phase 24 sessions 01-03 already provide the pure strike/combo model, camp-to-mission linkage, and live enemy presentation. The next executable step is to turn a camp-bound mission's real event stream into transient battlefield effects without creating another game-state authority.

The implementation should mount a pointer-events-none layer above hero tokens and drive it from existing store evidence: `eventLog`, `missions`, `gameProjection.campLinks`, ranked camp placement, and hero coordinates. The layer renders strikes, counterattacks, combo stages, stage props, display-only HP drain, verified-kill burn-down, and reduced-motion static twins.

The core honesty rule is unchanged: effects are product presentation for real linked mission events only. Unlinked missions, replayed traffic, unknown verification events, mock-only progress, and failed missions must not show camp kills or durable rewards.

***

## 2. Objectives

1. Create a pure `apps/web` combat playback effects model that selects linked mission events and derives bounded presentation state.
2. Render a battlefield effects layer with strike, counterattack, combo, stage-prop, HP-drain, and verified-kill visuals.
3. Preserve honesty boundaries: linked-only playback, verification-only kill visuals, no new protocol events, no new storage keys, and no rewards.
4. Prove caps, timer cleanup, reduced-motion parity, privacy, and integration through focused tests and web typecheck.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase24-session01-pure-strike-and-combo-model` - Provides `combatPlayback.ts` classification, combo, stage-prop, rate-limit, and safe-label helpers.
* [x] `phase24-session02-camp-mission-linkage` - Provides `gameProjection.campLinks`, pending-link recording, and `selectGameCampMissions`.
* [x] `phase24-session03-live-enemy-presentation` - Provides battlefield layer conventions, live enemy anchors, safe-label posture, and reduced-motion patterns.

### Required Tools Or Knowledge

* React 19, Vitest, Testing Library, Zustand store patterns, and Tailwind/CSS layer conventions in `apps/web`.
* Existing store event buffer shape: `ReplayEntry { at, event }` in `apps/web/src/store/useGameStore.ts`.
* Existing battlefield layer order in `apps/web/src/components/battlefield/Battlefield.tsx`.

### Environment Requirements

* Node 26.2.0+ and npm 11.16.0.
* `npm --workspace @factionos/web run typecheck` available.
* Focused Vitest runs available through root `npm test -- <test files>`.

***

## 4. Scope

### In Scope (MVP)

* Users watching a camp-linked mission can see real `tool_use` events strike the linked camp - using Session 01 classification and safe labels.
* Users can see failed `tool_result` events as counterattack flashes near the linked hero - with bounded labels and no raw output.
* Users can see concurrent linked missions attacking one camp as a joint assault - with deterministic per-hero trims and capped visuals.
* Users can see display-only HP drain on plausibly-fixing events - without mutating scanner-derived camp HP or projection camp state.
* Users can see verified camp kill burn-down only when an evidence-backed `task_verification` success can be related to a linked camp - with reduced-motion razed-state parity.
* Users with reduced motion enabled receive HP chip ticks, last-strike micro-badges, stage-prop labels, and razed-state badges instead of motion-only effects.

### Out Of Scope (Deferred)

* Audio cues and bark reuse - Reason: Session 06 owns SFX and bark wiring.
* Replay/mock persistence regressions beyond component honesty - Reason: Session 07 owns persistence and storage boundary proof.
* XP, loot, banners, titles, levels, Battle Report changes, War Council, Dawn Report, War Tide, essence, buildings, territory, bosses, or seasons - Reason: Phase 24 explicitly excludes reward/progression systems.
* New protocol events, server routes, or storage keys - Reason: Phase 24 guardrails require playback to derive from existing events and projection state.

***

## 5. Technical Approach

### Architecture

Create a pure helper module, `apps/web/src/lib/combatPlaybackEffects.ts`, that derives a bounded presentation model from `ReplayEntry[]`, `missions`, `campLinks`, ranked camps, and hero coordinates. The helper should consume existing `combatPlayback.ts` helpers for classification, combo stages, stage props, and labels. It must handle `ServerEvent` discriminants exhaustively for the events it understands and ignore unsupported events safely.

Create `apps/web/src/components/battlefield/CombatPlaybackLayer.tsx` as a board-internal, pointer-events-none layer. `Battlefield.tsx` should pass only selector-fed data: `eventLog`, `missions`, `gameProjection.campLinks`, `rankedCamps`, hero coordinates, hero names, `gameProjection.lastEventAt`, and `reduceMotion`. The layer may hold transient animation state, timers, and capped effects, but it must not write to the store, mutate `gameProjection`, unlock achievements, or persist anything.

### Design Patterns

* Pure model first: Keeps event selection, combo, HP display, verification matching, caps, and privacy tests independent of React.
* Presentation-only layer: Mirrors `CampLayer.tsx`, `LiveLegionLayer.tsx`, and `ScannerStateLayer.tsx` by reading projection state instead of owning game rules.
* Timer cleanup pattern: Reuse the `achievementCelebration.ts` approach for bounded lifetimes and cleanup on unmount.
* Reduced-motion twins: Add static equivalents at the same time as motion effects, following existing battlefield CSS patterns.

***

## 6. Deliverables

### Files To Create

| File                                                          | Purpose                                                                                                   | Est. Lines |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/web/src/lib/combatPlaybackEffects.ts`                   | Pure linked-combat playback selector, caps, HP display, verification mapping, and safe presentation model | \~280      |
| `apps/web/src/components/battlefield/CombatPlaybackLayer.tsx` | Battlefield effects layer for strikes, counterattacks, combo stages, stage props, HP drain, and burn-down | \~240      |
| `apps/web/tests/combatPlaybackEffects.test.ts`                | Pure model tests for linked-only playback, combos, stage props, HP drain, verification, and privacy       | \~300      |
| `apps/web/tests/CombatPlaybackLayer.test.tsx`                 | Component tests for caps, cleanup, reduced motion, joint assault, and product-facing DOM                  | \~260      |

### Files To Modify

| File                                                  | Changes                                                                                                                                 | Est. Lines |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/web/src/components/battlefield/Battlefield.tsx` | Wire combat playback layer with event log, missions, linked camps, camp placement, hero coordinates, and cleanup-safe celebration reuse | \~70       |
| `apps/web/src/components/battlefield/CampLayer.tsx`   | Export or adapt camp placement helpers needed by the effects layer without changing camp authority                                      | \~20       |
| `apps/web/src/index.css`                              | Add combat playback motion classes, stage props, HP chip treatment, and reduced-motion overrides                                        | \~90       |
| `apps/web/tests/Battlefield.test.tsx`                 | Add integration coverage for linked mission strike, counterattack, verification-only kill, and layer order                              | \~120      |

***

## 7. Success Criteria

### Functional Requirements

* [ ] A linked `tool_use` event renders the correct strike kind on the linked camp within the bounded effect lifetime.
* [ ] A linked failed `tool_result` renders a counterattack near the linked hero.
* [ ] Unlinked missions produce no strike, HP drain, counterattack, or kill visuals.
* [ ] Multiple linked missions against one camp render as a joint assault without unbounded visual growth.
* [ ] Camps show kill burn-down only from evidence-backed successful `task_verification`; failed or unmatched verification leaves the camp alive.

### Testing Requirements

* [ ] Unit tests written and passing for pure playback derivation.
* [ ] Component tests written and passing for caps, timer cleanup, reduced motion, and privacy.
* [ ] Battlefield integration tests cover the store event path.

### Non-Functional Requirements

* [ ] No new storage keys, protocol events, server routes, rewards, or persisted progress.
* [ ] No raw prompts, raw output, command bodies, absolute paths, provider payloads, or secrets render in layer labels or DOM attributes.
* [ ] Long event streams stay bounded by explicit visual caps and combo merging.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] UI surfaces contain product-facing copy only.

***

## 8. Implementation Notes

### Working Assumptions

* Package scope is `apps/web`: The analysis script marks Session 04 as `apps/web`, and all relevant code anchors are battlefield components, web store selectors, and web tests.
* Combat playback is transient presentation state: Phase 24 guardrails forbid a second authority and new storage keys, while existing `eventLog`, `missions`, and `gameProjection.campLinks` provide enough evidence for live effects.
* Verified kill matching must be evidence-backed: `TaskVerificationEvent` carries `taskId` and `ok` but no `missionId`; the implementation should trigger burn-down only when current store evidence can relate that verification to a linked mission/camp, and otherwise render no kill.

### Conflict Resolutions

* Phase stub says the effects layer sits above hero tokens, while earlier live enemy presentation sits below them. Chosen interpretation: Session 04 effects use a higher visual layer with `pointer-events: none`, so strikes can pass over heroes without blocking hero controls.
* Phase stub says to reuse the existing celebration burst, but rewards are explicitly out of scope. Chosen interpretation: reuse the visual constants/patterns from `achievementCelebration.ts` for burn-down feedback, without adding achievements or durable reward records.

### Key Considerations

* Keep `gameProjection.legion.camps` scanner-derived; HP drain is display-only.
* Keep safe labels bounded through `combatPlayback.ts` and camp label sanitizers.
* Keep the normal battlefield, Quest Board, and hero controls reachable because the effects layer is non-interactive.

### Potential Challenges

* Verification-to-mission relation may be absent: Treat unmatched `task_verification` as no kill rather than guessing.
* Event storms can overload the board: Use combo merging, visible caps, and timer cleanup as hard requirements.
* Reduced-motion parity can lag motion implementation: Implement the static twins in the same component pass.

### Relevant Considerations

* \[P23-apps/web] **Presentation-only battlefield layers**: Keep the layer thin, selector-fed, reduced-motion-aware, and separate from game rules.
* \[P22-apps/web] **Single projection authority**: Read projection selectors and do not copy or persist progress elsewhere.
* \[P23-apps/web] **Scanner camp projection stays aggregate-only**: Keep raw issue text, prompts, paths, file contents, provider payloads, scan roots, and secrets out of projection and battlefield UI.
* \[P20] **Broad privacy gates are release-critical**: Keep raw commands, output, diffs, file contents, provider payloads, tokens, secrets, broad absolute paths, and scanner details out of normal UI rows and DOM.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Timer leaks or stale effects after unmount.
* False camp kills from unmatched verification or unlinked mission events.
* Sensitive raw event data leaking into labels, titles, test ids, or DOM attributes.

***

## 9. Testing Strategy

### Unit Tests

* Pure `combatPlaybackEffects.ts` tests for linked-only event selection, strike classification, combo stages, stage props, display HP, verification matching, unmatched no-kill behavior, visible caps, and hostile string privacy.

### Integration Tests

* `CombatPlaybackLayer.test.tsx` for visual caps, timer cleanup, reduced-motion static twins, joint assault rendering, counterattack flashes, and product-facing DOM labels.
* `Battlefield.test.tsx` for `useGameStore.applyEvent` flows: linked mission start, tool use strike, failed tool result counterattack, task verification kill, and unlinked no-op.

### Runtime Verification

* Run focused Vitest files, then `npm --workspace @factionos/web run typecheck`.

### Edge Cases

* Unknown/custom tool names fall back to generic strikes.
* Missing camp placement, off-board heroes, absent mission rows, and unmatched task verification produce no effect instead of throwing.
* Replayed events should not create new persisted progress or permanent effect records.
* Reduced-motion mode conveys the same information statically.

***

## 10. Dependencies

### Other Sessions

* Depends on: `phase24-session01-pure-strike-and-combo-model`, `phase24-session02-camp-mission-linkage`, `phase24-session03-live-enemy-presentation`
* Depended by: `phase24-session06-world-cues-and-bark-reuse`, `phase24-session07-honesty-and-persistence-boundaries`

***

## Next Steps

Run the `implement` workflow step to begin 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-session04-combat-playback-effects-layer/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.
