# ADR-148 The Sessions Memory Index Needs a Rollover Mechanism Like the Lessons Log Has

## Status

Proposed, 2026-09-02.

## Status History

```yaml
status_history:
  - date: 2026-09-02
    status: Proposed
    changed_by: claude (session close-out, advisor-endorsed)
    reason: >
      index_sessions.md breached its own size cap during a routine /close-session append;
      the toolchain-lessons log solved the same growth problem with a parts split
      (lessons_001-050.md / 051-100.md / 101-200.md / 201plus.md) two months earlier, but
      that fix was never generalised to the sessions index, which has no lower tier to
      move retiring content into.
    changed_via: adr-kit (360lm), via /adr skill inside a Claude Code session
```

## Context

`C:\Users\Lenovo\.claude\projects\C--Users-Lenovo\memory\index_sessions.md` is the domain index
for session narratives (`session_YYYY_MM_DD_*.md`) in DL's tiered memory system — one line per
session, newest first, size-guarded at **12,288 bytes** by `memory-line-guard.py` on write and
checked by `memory_lint.py`'s `size-caps` rule.

On 2026-09-02, appending a single new session-record pointer line (for the Claude/Gamma PPT
research + build session) pushed the file to **12,460 B, 172 B over its cap**. The immediate fix
was a workaround, not a structural one: an unrelated, already-stale line (`Yagya IGNOU`, last
touched 2026-08-30) was refreshed with current status and moved DOWN into `index_people.md` — a
domain index it was already filed in — purely to free space in `index_sessions.md`, per the
`memory_lint.py` output:

```
size-caps         index_sessions.md              12,460 B over its 12,288 B cap
```

This is the second time this exact file has hit its cap this session's own Canon diff: the prior
scan (before this session started) already showed `index_sessions.md:12364/12288` as an active
alert, which had apparently been resolved by some other move before this session began, only to
be re-breached by the very next legitimate append.

**The lessons log already solved this exact shape of problem.** `feedback_dl_toolchain.md` grew
past its own comfortable size and was split 2026-08-29 into `lessons_001-050.md`,
`lessons_051-100.md`, `lessons_101-200.md`, and the live append target `lessons_201plus.md` —
each part sized to stay well under the guard's cap, with `feedback_dl_toolchain.md` left as a
zero-content redirect stub. `index_sessions.md` has no equivalent: it is a single flat file
holding pointer lines for **34+ sessions and growing weekly**, with no smaller "current part" to
append to and no larger frozen part to shed old entries into (`ARCHIVE.md` is explicitly frozen
per the close-session skill's ONE-IN-ONE-DOWN policy — nothing may be added to it).

Every future `/close-session` that adds a session-record pointer line will re-hit this cap and
require another ad hoc unrelated-line eviction to make room, which is not a designed behaviour —
it is the cap doing its job (catching an oversized file) while exposing that there is nowhere
correct for the evicted content to go that is actually about sessions.

## Decision

**Deferred to hkl — this ADR names the gap and the candidate fixes without selecting one.**
The options below are not evaluated against each other in this document; a future ADR (or an
edit to this one's Decision section once Accepted) should record the actual choice.

**Decision Maker:** hkl (not yet made)

## Implementation Notes

Not applicable until a Decision is recorded — see Alternatives Considered for what each option
would concretely require.

## Alternatives Considered

- **(a) Monthly rollup parts, mirroring the lessons split.** e.g.
  `sessions_2026-08.md`, `sessions_2026-09.md`, with only the current month's part remaining as
  the live target referenced by `index_sessions.md`, and older months' pointer lines moved into
  their respective monthly part file. Mirrors an already-proven pattern (`lessons_201plus.md`'s
  "THE LIVE APPEND TARGET" convention) but requires deciding how far back old session pointer
  lines get pruned from `index_sessions.md` itself, and updating whatever currently reads
  `index_sessions.md` expecting every session to be listed there directly.
- **(b) A one-line-per-month rollup entry pointing at a monthly detail file.** Collapses each
  past month to a single summary line in `index_sessions.md`, with the full list of that month's
  sessions living in a separate file. Keeps `index_sessions.md` small indefinitely, but loses the
  "newest first, one line per session" browsability the index currently offers for anything
  older than the current rollup — a real usability trade-off, not just a storage one.
- **(c) Raise the byte cap.** Rejected in the writing, not left open: this defers the same
  failure to a larger N rather than solving the underlying unbounded-growth problem — the file
  will hit any fixed cap again given enough weeks of sessions, and a larger single file also
  costs more to load on every session-domain read.
- **(d) Do nothing; keep evicting an unrelated line at each close-out.** The status quo as of this
  ADR. Rejected as the default going forward because it silently borrows capacity from whichever
  domain index happens to hold the oldest-looking Active-now line that week, which is not a
  property anyone chose — it is incidental to which items happened to be in MEMORY.md's
  Active-now list at the moment the sessions index needed room.

## Revisit If

- **Revisit if:** `index_sessions.md` breaches its cap again before this ADR is Accepted — that
  is direct evidence the workaround-per-close-out pattern is recurring, not a one-off.
- **Revisit if:** the tiered-memory architecture itself changes (e.g. a future FTS/search layer
  makes the "one line per session in one flat file" browsability property in option (b)'s
  trade-off no longer load-bearing).
- **Does NOT govern:** the lessons log's own rollover scheme, which already works and is out of
  scope here; this ADR is specific to `index_sessions.md`.

## Consequences

**Positive:**
- Naming the gap explicitly (rather than re-discovering it at the next close-out) means the next
  session that hits this cap can act on a decided plan instead of improvising another eviction.

**Negative / Trade-offs:**
- Until hkl picks an option, the workaround (evict an unrelated stale line to free room) remains
  the only available fix, and will recur.

**Risks and mitigations:**
- **Risk:** the eviction workaround could someday move a line into a domain index without first
  refreshing its content (unlike this session, which did refresh the evicted Yagya IGNOU line
  before moving it) — a stale line surviving the eviction is worse than not evicting at all.
  **Mitigation:** the DOWN-first safety property already required by `/close-session` Step 5
  covers this if followed; this ADR does not change that requirement.

## Related Decisions

- None — first ADR governing the tiered-memory index architecture specifically. Related but not
  superseding: the memory tiering migration itself (2026-08-29, `MEMORY_TIERING_PLAN.md`) and the
  VPS-side memory domain tiering done 2026-09-02 (`project_vps_memory_tiering.md`), neither of
  which is an ADR.

## References

- `memory_lint.py` output, 2026-09-02: `size-caps FAIL 2` including
  `index_sessions.md 12,460 B over its 12,288 B cap`.
- `C:\Users\Lenovo\.claude\projects\C--Users-Lenovo\memory\index_sessions.md` (the file itself).
- `C:\Users\Lenovo\.claude\projects\C--Users-Lenovo\memory\lessons_201plus.md` frontmatter — the
  proven precedent this ADR proposes generalising: "DL toolchain lessons #201 onward (part 4,
  split 2026-08-29) — THE LIVE APPEND TARGET."
- Session record: `session_2026_09_02_claude_pptx_quality.md` — the close-out during which this
  gap was found and worked around.
- `Documents\memory-architecture\MEMORY_TIERING_PLAN.md` — the original tiering design this ADR
  extends.
