Skip to content

feat(profiles): add session profile encoder and active-branch replay - #1919

Open
noxsystems wants to merge 3 commits into
Gentleman-Programming:mainfrom
noxsystems:feat/1064-3b-i-2-codec-encoder-replay
Open

noxsystems wants to merge 3 commits into
Gentleman-Programming:mainfrom
noxsystems:feat/1064-3b-i-2-codec-encoder-replay

Conversation

@noxsystems

@noxsystems noxsystems commented Oct 8, 2026 •

Copy link
Copy Markdown

Review size: this slice adds 236 changed lines (+212/-24) on top of #1918. GitHub's Files tab shows the cumulative diff with #1918 until it merges; review only commit 732a11f1b.

Summary

Part of #1064, slice 3b-i (persistence codec). Second and last pure PR of the codec: the encoder and the active-branch replay rule. Still no disk access, Pi API, Enter or routing change.

  • Encoder: createSessionProfileBind(name, modelProfiles) creates only explicit user selections and rejects invalid input instead of manufacturing an empty snapshot; typed normalized routes may carry model/thinking as undefined and those are omitted, while effort stays strict. createSessionProfileClear() is the minimal {kind:"clear"}.
  • Replay replaySessionProfileBranch(entries): the caller supplies entries already corroborated on disk, oldest to newest, on the active branch. The newest profile-family entry is terminal, including invalid and unsupported; an older binding is never revived. entryIndex is the actual branch offset for a later location warning. In-memory getBranch() alone is not corroboration; a subsequent disk-reader slice supplies it.
  • Both directions return defensive snapshots.

This is PR 2 of 2.

Issue

Part of #1064

PR type

  • New feature (type:feature)

Changes

Commit Change
732a11f1b Encoder, encoderInput mode in the route/snapshot readers, replaySessionProfileBranch, their tests, and the Replay section of docs/session-profile-format.md.

Test plan

Verified on top of PR 1, main 9782d26df, Node 25.2.1:

  • tests/session-profile-persistence.test.ts: 18 pass, 0 fail (adds writer fields, undefined handling, defensive copies, terminal newest entry, branch order, sibling exclusion).
  • tests/agent-profiles.test.ts + tests/model-routing-authority.test.ts: 59 pass, 0 fail.
  • node scripts/check-types.mjs: 186 recorded diagnostics, no regressions.
  • The same three files were independently verified byte-identical inside a bwrap sandbox against the pinned baseline (f5a42a5): 18/18, 59/59, ratchet 186 on both lanes.
  • Native review (RDD): not run on this slice.

Chain Context

Field Value
Chain #1064 slice 3b-i: session profile persistence codec
Tracker PR Not needed
Position 2 of 2
Base main (fork PRs cannot stack bases; rebased as #1918 lands)
Depends on #1918
Follow-up #1922 disk corroboration, then Enter persistence wiring around #1824's selection path
Review budget 236 changed lines (+212/-24), of which 137 are tests and 29 docs.
main
 └─ #1918 decoder: record format, readSessionProfileEntry
   └─ PR 2 encoder + replaySessionProfileBranch                📍 this PR
     └─ #1922 readSessionProfileDisk: on-disk corroboration
       └─ (later) append controller, authority, Enter persistence wiring

Summary by CodeRabbit

  • Documentation
    • Added guidance for the optional session profile format, including how profiles are bound or cleared, validated, and replayed across a session’s active history.
    • Clarified how invalid or unsupported profile entries affect replay and how model and route settings are represented.
  • New Features
    • Added support for creating, reading, and replaying session profile entries, including preserving the selected entry’s position in session history.

Part of Gentleman-Programming#1064 (slice 3b-i, codec). Standalone decoder for the
gentle-pi.session-profile/v1 custom entry: closed origin set, own-property
checks, one invalid route invalidates the whole snapshot, unknown fields
ignored, prototype keys kept as own data. No Pi API, disk access, Enter,
startup or routing changes.

Chain: main -> [this] decoder -> encoder + active-branch replay (next).
Out of scope: encoder, replay, disk-reader corroboration, Enter wiring.
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: fb99714d-db4e-41a5-8fe2-782212c65959
📥 Commits

Reviewing files that changed from the base of the PR and between 9782d26 and 409ff09.

📒 Files selected for processing (3)
  • docs/session-profile-format.md
  • lib/session-profile-persistence.ts
  • tests/session-profile-persistence.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

This change adds a v1 session-profile codec and active-branch replay utility. It validates bind payloads and route snapshots, classifies profile entries, and selects the newest non-absent result. Tests and documentation describe payload, validation, and replay behavior.

Changes

Session profile persistence

Layer / File(s) Summary
Payload contracts and validation
lib/session-profile-persistence.ts, tests/session-profile-persistence.test.ts
Adds payload and result types, validates profile bindings and routes, and creates bind and clear payloads. Tests cover payload creation, invalid input, and defensive copies.
Entry classification and branch replay
lib/session-profile-persistence.ts, tests/session-profile-persistence.test.ts, docs/session-profile-format.md
Classifies entries as absent, bound, cleared, invalid, or unsupported. Replay returns the newest non-absent result and its branch index. Tests and documentation cover decoding and replay rules.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant replaySessionProfileBranch
  participant readSessionProfileEntry
  Caller->>replaySessionProfileBranch: Supply entries in oldest-to-newest branch order
  replaySessionProfileBranch->>readSessionProfileEntry: Classify each entry
  readSessionProfileEntry-->>replaySessionProfileBranch: Return entry status
  replaySessionProfileBranch-->>Caller: Return newest non-absent result and branch index
Loading

Merge Risk: ⚪ Minimal · up to 409ff

This adds a standalone session-profile codec and replay utility with tests and documentation. It is not yet wired into runtime behavior, so merge risk is minimal.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main changes: adding a session profile encoder and active-branch replay utility.
Full details: Docstring Coverage

Explanation

Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…dicate

Export isSafeAgentName from model-routing-authority and use it in the
session profile decoder instead of probing normalizeModelConfig. Assert
constructor and prototype keys stay own data in the hostile-keys test.
Addresses the two CodeRabbit comments on Gentleman-Programming#1918.
Part of Gentleman-Programming#1064 (slice 3b-i, codec). Adds createSessionProfileBind and
createSessionProfileClear (explicit user selections only, typed undefined
model/thinking omitted, effort stays strict) and replaySessionProfileBranch:
the newest profile-family entry on a caller-supplied, already disk-corroborated
active branch is terminal, including invalid and unsupported, and never revives
an older binding. Still no disk access, Pi API, Enter or routing changes.

Chain: main -> decoder (previous) -> [this] encoder + replay.
Depends on: feat/1064-3b-i-1-codec-decoder.
Out of scope: disk-reader corroboration, Enter wiring, guards.
@noxsystems
noxsystems force-pushed the feat/1064-3b-i-2-codec-encoder-replay branch from 409ff09 to 732a11f Compare October 8, 2026 04:50
noxsystems pushed a commit to noxsystems/gentle-shell that referenced this pull request Oct 8, 2026
Part of Gentleman-Programming#1064 (slice 3b-i, disk reader). readSessionProfileDisk reads the
session's public active branch and JSONL file, selects the newest
profile-family entry (excluding known failed append IDs) and admits it only
when the record on disk is byte-identical; otherwise it returns one
indeterminate reason without record contents. No writes, fallback, cache,
ancestry repair or fsync; a missing file never restores a memory-only
profile. Verified against a real SessionManager session file.

Chain: main -> decoder (Gentleman-Programming#1918) -> encoder + replay (Gentleman-Programming#1919) -> [this].
Depends on: Gentleman-Programming#1919.
Out of scope: append controller, authority publication, Enter wiring.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants