> 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/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md).

# Implementation Notes

**Session ID**: `phase23-session02-ranking-and-presentation-selectors` **Package**: apps/web **Started**: 2026-07-05 17:25 **Last Updated**: 2026-07-05 17:33

***

## Session Progress

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

***

## Task Log

### 2026-07-05 - Session Start

**Environment verified**:

* [x] Prerequisites confirmed
* [x] Tools available
* [x] Directory structure ready
* [x] Package context verified: `apps/web`
* [x] Node 26.2.0 available through nvm for session commands

***

### Task T001 - Verify Session 01 helper exports and current ranking baseline

**Started**: 2026-07-05 17:25 **Completed**: 2026-07-05 17:25 **Duration**: 1 minute

**Notes**:

* Confirmed `legionCamps.ts` already exports reconciliation helpers, camp ids, sector ids, severity/tier constants, `RankVisibleLegionCampsInput`, `RankedLegionCamp`, and base `rankVisibleLegionCamps`.
* Confirmed current ranking baseline filters zero-HP camps, clones camp issue ids and sectors, marks entrenched camps as muted, and sorts by muted state, tier, HP, timestamp, sector label, and camp id.

**Files Changed**:

* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md` - recorded setup evidence.
* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/tasks.md` - marked task complete.

**Verification**:

* Command/check: `nl -ba apps/web/src/lib/legionCamps.ts`
  * Result: PASS - inspected exports and baseline implementation.
  * Evidence: `rankVisibleLegionCamps` exists at lines 597-633 and returns cloned ranked camp records from `camps` and `sectors`.
* UI product-surface check: N/A - pure library inspection only.
* UI craft check: N/A - no UI surface changed.

***

### Task T002 - Verify existing focused test fixtures and package commands

**Started**: 2026-07-05 17:25 **Completed**: 2026-07-05 17:25 **Duration**: 1 minute

**Notes**:

* Confirmed focused Vitest fixtures cover scanner issue contracts, previous camp/sector records, reconciliation, aggregate-only output, and current ranking metadata.
* Confirmed root `npm test` runs `vitest run`, and web package `typecheck` runs `tsc -b --noEmit`.

**Files Changed**:

* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md` - recorded setup evidence.
* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/tasks.md` - marked task complete.

**Verification**:

* Command/check: `nl -ba apps/web/tests/legionCamps.test.ts`
  * Result: PASS - inspected focused test fixtures and current assertions.
  * Evidence: 12 existing tests cover fixture contracts, sector coalescing, reconciliation state, aggregate-only output, and base ranking metadata.
* Command/check: `cat package.json && cat apps/web/package.json`
  * Result: PASS - verified root and web workspace commands.
  * Evidence: root `test` is `vitest run`; web `typecheck` is `tsc -b --noEmit`.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused baseline tests pass.
  * Evidence: 1 file passed, 12 tests passed.
* UI product-surface check: N/A - pure library tests only.
* UI craft check: N/A - no UI surface changed.

***

### Task T003 - Extend ranking input and output types

**Started**: 2026-07-05 17:26 **Completed**: 2026-07-05 17:28 **Duration**: 2 minutes

**Notes**:

* Added typed roster mode, placement, selected-context input, and presentation metadata contracts.
* Extended `RankVisibleLegionCampsInput` and `RankedLegionCamp` with roster size/count, selected-context, rank, mode, limit, selected-context match, and placement fields.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added selector input/output contract fields and exported supporting types.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - TypeScript accepts the extended selector contract.
  * Evidence: `tsc -b --noEmit` completed successfully.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused tests still pass after contract extension.
  * Evidence: 1 file passed, 12 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T004 - Add Champion Mode visible limit constants and roster-mode helpers

**Started**: 2026-07-05 17:26 **Completed**: 2026-07-05 17:28 **Duration**: 2 minutes

**Notes**:

* Added `LEGION_CAMP_VISIBLE_LIMITS_BY_ROSTER_MODE` with zero/solo 3, duo 4, squad 6, and army 9 camp limits.
* Added pure helpers to derive roster mode from visible hero count and fetch the visible limit for a mode.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added Champion Mode roster constants and helpers.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - exported roster helpers typecheck.
  * Evidence: `tsc -b --noEmit` completed successfully.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused tests still pass after helper addition.
  * Evidence: 1 file passed, 12 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T005 - Add pure selected-context sector resolution

**Started**: 2026-07-05 17:27 **Completed**: 2026-07-05 17:28 **Duration**: 1 minute

**Notes**:

* Added `resolveLegionSelectedSectorId` to resolve sector id, safe sector key, or file path context against existing sectors only.
* File-path mapping uses the same sanitized primary/deep sector path helpers as camp reconciliation and falls back to no selected sector when unmappable.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added selected-context resolution helpers and wired selected-match metadata.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - context resolver contract typechecks.
  * Evidence: `tsc -b --noEmit` completed successfully.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - existing selector tests still pass.
  * Evidence: 1 file passed, 12 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T006 - Add presentation metadata helpers

**Started**: 2026-07-05 17:27 **Completed**: 2026-07-05 17:28 **Duration**: 1 minute

**Notes**:

* Added `legionCampPresentationForEntrenchment` to derive `entrenched`, `muted`, and `placement` from `entrenchedScans`.
* Ranking output now includes presentation metadata without mutating camp records.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added presentation metadata helper and ranked output fields.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - presentation metadata helper typechecks.
  * Evidence: `tsc -b --noEmit` completed successfully.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - existing ranking metadata tests still pass.
  * Evidence: 1 file passed, 12 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T007 - Prioritize selected-context sector matches

**Started**: 2026-07-05 17:29 **Completed**: 2026-07-05 17:31 **Duration**: 2 minutes

**Notes**:

* Updated ranking so a resolved selected sector sorts before non-selected camps.
* Added selected-context tests for sector key, file path, and unmappable fallback.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - comparator now ranks selected-context matches first.
* `apps/web/tests/legionCamps.test.ts` - covered selected-context priority and fallback.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused tests cover selected priority.
  * Evidence: 1 file passed, 15 tests passed.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - comparator changes typecheck.
  * Evidence: `tsc -b --noEmit` completed successfully.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T008 - Update deterministic camp comparator

**Started**: 2026-07-05 17:29 **Completed**: 2026-07-05 17:31 **Duration**: 2 minutes

**Notes**:

* Comparator order is now selected-context match, tier, HP, lower entrenchment, newest timestamp, and stable camp id.
* Removed the old muted-first ordering so entrenched state only affects comparable camps after tier and HP.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - updated `compareRankedLegionCamps`.
* `apps/web/tests/legionCamps.test.ts` - added lower-entrenchment and stable tie-break cases.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - deterministic comparator cases pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T009 - Apply roster-size visible trimming

**Started**: 2026-07-05 17:29 **Completed**: 2026-07-05 17:31 **Duration**: 2 minutes

**Notes**:

* Ranking now slices the returned list to the derived visible limit after sorting.
* The caller-owned `camps` record remains unchanged and available to richer inspection surfaces.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added visible-limit slice and final rank assignment.
* `apps/web/tests/legionCamps.test.ts` - added zero, solo, duo, squad, army, and roster-size precedence coverage.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - visible limit tests pass for all modes.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T010 - Preserve newest timestamp fallback

**Started**: 2026-07-05 17:29 **Completed**: 2026-07-05 17:31 **Duration**: 2 minutes

**Notes**:

* Added timestamp map normalization so invalid issue timestamps are ignored and absent timestamps fall back to the selector snapshot time.
* Duplicate issue timestamps now keep the newest valid ISO timestamp.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added `setNewestLegionIssueTimestamp`.
* `apps/web/tests/legionCamps.test.ts` - added invalid/missing timestamp fallback coverage.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - timestamp fallback case passes.
  * Evidence: 1 file passed, 15 tests passed.
* BQC Fixes:
  * Contract alignment: ignored invalid `CodebaseIssue.createdAt` values instead of letting them poison duplicate timestamp selection (`apps/web/src/lib/legionCamps.ts`).
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T011 - Clone returned camp, issue id, and sector data

**Started**: 2026-07-05 17:29 **Completed**: 2026-07-05 17:31 **Duration**: 2 minutes

**Notes**:

* Final ranked output re-clones camp, nested issue ids, top-level issue ids, and sector objects after sort/slice/rank.
* Mutating returned records no longer mutates the caller-owned projection inputs.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - added final clone pass in ranked output mapping.
* `apps/web/tests/legionCamps.test.ts` - added return-mutation assertions.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - immutability assertions pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library selector only.
* UI craft check: N/A - no UI surface changed.

***

### Task T012 - Add visible limit tests

**Started**: 2026-07-05 17:30 **Completed**: 2026-07-05 17:31 **Duration**: 1 minute

**Notes**:

* Added table-driven tests for zero, solo, duo, squad, and army visible limits.
* Verified rank, roster mode, and visible limit metadata on returned camps.

**Files Changed**:

* `apps/web/tests/legionCamps.test.ts` - added visible-limit test coverage.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - visible-limit tests pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library tests only.
* UI craft check: N/A - no UI surface changed.

***

### Task T013 - Add selected-context tests

**Started**: 2026-07-05 17:30 **Completed**: 2026-07-05 17:31 **Duration**: 1 minute

**Notes**:

* Added selected-context priority tests for file path and sector key resolution.
* Added unmappable context fallback assertion against unselected ranking order.

**Files Changed**:

* `apps/web/tests/legionCamps.test.ts` - added selected-context tests.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - selected-context tests pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library tests only.
* UI craft check: N/A - no UI surface changed.

***

### Task T014 - Add comparator fallback tests

**Started**: 2026-07-05 17:30 **Completed**: 2026-07-05 17:31 **Duration**: 1 minute

**Notes**:

* Added tests for lower-entrenchment priority, newest timestamp fallback, and stable camp-id tie-breaking.
* Covered invalid `createdAt` input and missing issue timestamp fallback to selector `now`.

**Files Changed**:

* `apps/web/tests/legionCamps.test.ts` - added comparator fallback tests.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - comparator fallback tests pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library tests only.
* UI craft check: N/A - no UI surface changed.

***

### Task T015 - Add presentation metadata and immutability tests

**Started**: 2026-07-05 17:30 **Completed**: 2026-07-05 17:31 **Duration**: 1 minute

**Notes**:

* Added tests for `muted` plus `edge` metadata on entrenched camps.
* Verified visible trimming does not truncate input records and returned camp, issue id, and sector data are detached from inputs.

**Files Changed**:

* `apps/web/tests/legionCamps.test.ts` - added presentation metadata and immutability tests.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - presentation and immutability tests pass.
  * Evidence: 1 file passed, 15 tests passed.
* UI product-surface check: N/A - pure library tests only.
* UI craft check: N/A - no UI surface changed.

***

### Task T016 - Run focused Vitest, web typecheck, and ASCII/LF checks

**Started**: 2026-07-05 17:32 **Completed**: 2026-07-05 17:33 **Duration**: 1 minute

**Notes**:

* Formatted the touched TypeScript files with Biome before the final verification pass.
* Ran focused Vitest, web typecheck, ASCII, LF, and focused lint checks successfully.

**Files Changed**:

* `apps/web/src/lib/legionCamps.ts` - formatted final selector implementation.
* `apps/web/tests/legionCamps.test.ts` - formatted final focused tests.
* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/tasks.md` - marked final task and completion checklist complete.
* `.spec_system/specs/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md` - recorded final verification evidence.

**Verification**:

* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused Vitest passed.
  * Evidence: 1 file passed, 15 tests passed.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck`
  * Result: PASS - web package typecheck passed.
  * Evidence: `tsc -b --noEmit` completed successfully.
* Command/check: `perl -ne 'if (/[^\\x00-\\x7F]/) { print "$ARGV:$.:$_"; $bad=1 } END { exit($bad ? 1 : 0) }' apps/web/src/lib/legionCamps.ts apps/web/tests/legionCamps.test.ts .spec_system/specs/phase23-session02-ranking-and-presentation-selectors/tasks.md .spec_system/specs/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md`
  * Result: PASS - no non-ASCII bytes found in touched session files.
  * Evidence: command exited 0 with no output.
* Command/check: `if grep -n $'\\r' apps/web/src/lib/legionCamps.ts apps/web/tests/legionCamps.test.ts .spec_system/specs/phase23-session02-ranking-and-presentation-selectors/tasks.md .spec_system/specs/phase23-session02-ranking-and-presentation-selectors/implementation-notes.md; then exit 1; else exit 0; fi`
  * Result: PASS - no CRLF line endings found in touched session files.
  * Evidence: command exited 0 with no output.
* Command/check: `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npx biome lint apps/web/src/lib/legionCamps.ts apps/web/tests/legionCamps.test.ts`
  * Result: PASS - focused lint passed.
  * Evidence: 2 files checked, no fixes applied.
* UI product-surface check: N/A - pure library selector and tests only.
* UI craft check: N/A - no UI surface changed.

***

## Checkpoints

### Checkpoint 1 - After T006

**Completed**: 2026-07-05 17:28

**Verification**:

* `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts` - PASS, 1 file and 12 tests passed.
* `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck` - PASS.
* Re-read session objectives from `spec.md`: next work remains ranking priority, deterministic comparator order, visible trimming, timestamp fallback, and clone guarantees.

**Next Task**: T007 - Update `rankVisibleLegionCamps` to prioritize selected-context sector matches before general camp ordering.

***

### Checkpoint 2 - After T015

**Completed**: 2026-07-05 17:31

**Verification**:

* `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm test -- apps/web/tests/legionCamps.test.ts` - PASS, 1 file and 15 tests passed.
* `. ~/.nvm/nvm.sh && nvm use 26.2.0 >/dev/null && npm --workspace @factionos/web run typecheck` - PASS.
* Re-read session objectives from `spec.md`: implementation now covers selected priority, documented comparator order, visible trimming, timestamp fallback, presentation metadata, clone guarantees, and focused tests.

**Next Task**: T016 - Run focused Vitest, web typecheck, and ASCII/LF checks.

***

### Checkpoint 3 - Session Complete

**Completed**: 2026-07-05 17:33

**Verification**:

* Focused Vitest, web typecheck, ASCII, LF, and focused lint all passed.
* Re-read session success criteria from `spec.md`: all functional, testing, non-functional, and quality gates for this implementation session are satisfied.

**Next Task**: none inside `implement`; hand off to `creview`.

***


---

# 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/phase23-session02-ranking-and-presentation-selectors/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.
