Skip to content

Do not register a stem when probing a session in the in-memory locator - #576

Merged
senamakel merged 4 commits into
mainfrom
tinyagents-locator-probe
Oct 26, 2026
Merged

senamakel merged 4 commits into
mainfrom
tinyagents-locator-probe

Conversation

@senamakel

@senamakel senamakel commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Summary

InMemoryTranscriptLocator answered "does this session exist?" by registering an empty, unwritten stem for the generation it probed. The TranscriptLocator::read_session_transcript default probes through open_stem, which binds a handle whether or not anything was ever written. head_generation walks the successor chain through session_exists, so resolving the head of a session probed (and so registered) the next generation, g1. If the same turn then began that generation (begin_generation_from_baseline, e.g. refreshing a changed system prompt on resume), begin_generation_locked found the g1 stem and failed with session generation already exists or is reserved.

Persistent locators count only written records and were not affected; this only hit the in-memory store (tests, deployments with no database).

Cause and fix

An existence probe must not create state. InMemoryTranscriptLocator now overrides read_session_transcript with an exact lookup that never registers a stem and reports a transcript only when it has been written, which is the contract documented on the trait and what the persistent locators already do. session_exists, head_generation and session_chain all go through it, so every probe is fixed at once.

Reserved-generation semantics are unchanged: begin_generation still records its successor in reserved_generations, so a second begin for the same generation is still refused while the first is unwritten or dropped. That is pinned by the existing an_unwritten_successor_is_reserved_until_written_or_dropped and by a new test that probes a begun, unwritten generation and checks it is still reserved.

Tests

New in crates/tinyagents-session/src/port/memory/mod_tests.rs:

  • probing_for_the_head_generation_does_not_reserve_the_next_one (fails before the fix with session generation already exists or is reserved)
  • a_begun_generation_stays_reserved_after_probing_for_it

Commands run:

  • cargo test -p tinyagents-session (529 + 1 passing)
  • cargo test --workspace (green)
  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings

API / behavior changes

None to the public API. In-memory read_session_transcript, session_exists and head_generation no longer leave an empty stem behind.

Note: the branch also carries a pair of checkpoint commits that moved and then restored the vendor/tinytools and vendor/tinyinference gitlinks; the net diff against main is the two files above only.

Summary by CodeRabbit

  • Bug Fixes
    • Session transcript lookups now return results only for registered sessions with written history, without registering unknown sessions as a side effect.
    • Checking the next session generation no longer reserves it. The generation can still be created afterward, while generations already begun but not written remain reserved.

senamakel and others added 4 commits October 26, 2026 03:29
Update the vendored tinyinference and tinytools submodule pointers to their latest revisions.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…sors

Add tests asserting that probing for the head generation leaves no
reserved successor behind, and that a generation begun explicitly stays
reserved so a second begin attempt fails.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the vendored tinytools and tinyinference submodules to their latest
commits.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The in-memory locator inherited the trait default for read_session_transcript, which probes through open_stem and leaves an empty handle behind for every generation queried, causing begin_generation to see its own successor as already existing. It now performs a read-only lookup that only returns a transcript when one has actually been written.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@tinysweeper

tinysweeper Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Reviewed head: 28b21684da4d55a5b2b2c51c00976bfc0e35403e

Verdict: Ready for maintainer review · Priority: none
Coverage: Reviewed 2 of 2 files.
Pull request purpose (title): Do not register a st…

Diagnostics and supporting details

Full summary

Pull request purpose (title): Do not register a stem when probing a session in the in-memory locator. Tiny Sweeper completed its review; deterministic results follow.

Review snapshot

Change surface Files Review signal Count
Production 1 Active findings 0
Tests 1 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 0 Pending checks/questions 0

Completeness: Complete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

What changed

`InMemoryTranscriptLocator` gains an override of `read_session_transcript` at `crates/tinyagents-session/src/port/memory/mod.rs#impl TranscriptLocator for InMemoryTranscriptLocator {` that derives the stem from `SessionRef`, looks up an existing entry under the lock without calling `open_stem`, and returns a handle only when `read_session` yields a written transcript, falling through to `None` otherwise. Because `session_exists`, `head_generation` and `session_chain` all route through that method, every probe stops creating state, and `begin_generation_locked` no longer finds its own successor already present. Reserved-generation semantics are unchanged: `begin_generation` still records the successor in `reserved_generations`. The public API is unchanged.

Features

  • Modified — Non-registering session existence probe in the in-memory locator: Probing for a session no longer leaves an empty, unwritten stem behind, so a head-generation probe does not make the next generation appear to already exist and `begin_generation_from_baseline` no longer fails with `session generation already exists or is reserved` for in-memory stores. Only written transcripts are reported, aligning the in-memory locator with the trait contract and the persistent locators. (crates/tinyagents-session/src/port/memory/mod.rs impl TranscriptLocator for InMemoryTranscriptLocator {)
  • Added — Probe/reservation tests: Two tests pin the fixed behavior and the preserved reservation semantics: one checks that probing the head leaves no state for the next generation to collide with, the other that a begun, unwritten generation still counts as reserved after being probed. Tests are placed in the sibling test module as the repository requires and assert on behavior rather than internals. (crates/tinyagents-session/src/port/memory/mod_tests.rs fn an_unwritten_successor_is_reserved_until_written_or_dropped() {, crates/tinyagents-session/src/port/memory/mod_tests.rs)

Tests

  • unit — Begins a generation, then asserts the successor does not exist, that `read_session_transcript` for it returns `None`, and that a second `begin_generation` for the same generation is rejected.: Pins that reserved-generation semantics survive the probe change, with the reservation still held while the successor is unwritten. Not executed as part of this review. (crates/tinyagents-session/src/port/memory/mod_tests.rs)

Findings

No active actionable findings.

Before merge

None.

Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The critique lane answered and reported no defect: the override matches the trait default's contract that only written transcripts count and matches the persistent locator behavior, with the new tests aligned to existing `begin_generation` semantics.
  • Lane summary: The change overrides `read_session_transcript` in the in-memory locator so probing no longer registers an empty stem, and adds two tests covering the probe and the reservation cases. The override matches the trait default's contract (only written transcripts count) and the persistent locator's behaviour, and the new tests align with existing `begin_generation` semantics — I found no defect to report. _The code index is behind this pull request (indexed at `dfa5f161ad4b`), so retrieved context may be out of date._

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The security lane answered and reported no security-relevant defect: the stem is deterministically derived from `SessionRef`, the lookup reads only existing entries without registering, and no untrusted-input sink, network or subprocess call, or permission change is introduced.
  • Lane summary: The change adds an exact, non-registering `read_session_transcript` override to the in-memory locator so probing for a head generation no longer leaves an unwritten stem behind that `begin_generation` would then see as already existing. `session_stem` derives a deterministic stem from `SessionRef`, the lookup reads only existing entries, and `read_session` returns `None` for unwritten histories, so the reservation logic in `begin_generation_locked` stays correct. The two added tests exercise the probe and reservation behaviour directly. No security-relevant defect found; the new code introduces no untrusted-input sink, network/subprocess call, or permission change. _The code index is behind this pull request (indexed at `dfa5f161ad4b`), so retrieved context may be out of date._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The tests lane answered and reported no reportable defect, noting the fix addresses a real behavioral bug and that the non-`Ok(Some(_))` arm returning `None` is consistent with the existing `written_roots`/`root_for_thread_scoped` treatment of unwritten handles.
  • Lane summary: The behavioural fix is a real one: overriding `read_session_transcript` on `InMemoryTranscriptLocator` so that probing the head no longer registers an empty stem via `open_stem`, which previously made `begin_generation` see its own successor as existing. Two tests come with it that pin the behaviour — `probing_for_the_head_generation_does_not_reserve_the_next_one` fails if the default (registering) probe comes back, and `a_begun_generation_stays_reserved_after_probing_for_it` pins that a real reservation still counts and is not cleared by a probe. Both are in the sibling `mod_tests.rs` as the repository requires, and assertions are behavioural. The `_ => None` arm swallowing non-`Ok(Some(_))` reads is consistent with the existing `written_roots`/`root_for_thread_scoped` treatment of unwritten handles. I found no reportable defect. _The code index is behind this pull request (indexed at `dfa5f161ad4b`), so retrieved context may be out of date._

commits

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The commits lane answered and found no sensitive content in committed files.
  • Lane summary: No sensitive content in committed files. _The code index is behind this pull request (indexed at `dfa5f161ad4b`), so retrieved context may be out of date._

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The description lane answered and found the description consistent with the diff, with the new tests named and placed per repository rules.
  • Lane summary: The change adds an exact `read_session_transcript` override to `InMemoryTranscriptLocator` that looks up the stem without calling `open_stem` and only returns a handle for a written transcript, matching the trait contract and the persistent locators, with two focused tests covering the probe/reservation interaction. The description matches the diff, and the new tests are named and placed per the repository rules; I found nothing to report. _The code index is behind this pull request (indexed at `dfa5f161ad4b`), so retrieved context may be out of date._
Evidence and run details
  • Models: ladder/vectors-oai3, deepseek-v4.1-flash
  • Spend: $0.000483
  • Tokens: 266306 input · 4538 output · 0 cached · 204 embedding
  • Updated: 2026-10-26T03:33:39Z
Head State Pass summary
28b21684da4d ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-10-26T03:33:39Z)

tinysweeper 0.1.2

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T03:34:20.437104Z 28b2168 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ab933a8a-9b64-4b3b-b3c5-badc53478f3a
Commits

Reviewing files that changed from the base of the PR and between 7d41f2c and 28b2168.

Files selected for processing: 2
  • crates/tinyagents-session/src/port/memory/mod.rs
  • crates/tinyagents-session/src/port/memory/mod_tests.rs

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

Walkthrough

The in-memory transcript locator now performs exact, non-registering transcript lookup. Added tests cover generation probes that do not create a successor and preserve reservations for begun, unwritten generations.

Changes: In-memory session lookup

Layer / File(s) Summary
Transcript lookup and generation probes
crates/tinyagents-session/src/port/memory/mod.rs, crates/tinyagents-session/src/port/memory/mod_tests.rs
The locator returns history only for a registered stem with a written session. Tests verify that probing a successor does not create it, and that a begun but unwritten generation remains reserved.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix

Possibly related PRs

  • tinyhumansai/tinyagents#573: Adds Session::reset_history, which creates and writes a successor transcript generation. Both changes involve successor-generation behavior.
Merge Risk: Minimal · up to 28b21

The supplied change context identifies no issue that needs resolution before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: preventing session stem registration during in-memory session probing.
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.
Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks the session trail,
Finds written pages by their stem.
It probes ahead; no new page grows,
A reserved leaf stays held in place.
Then hops away with notes in tow.

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

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tinysweeper found nothing blocking. Approving.

Diagnostics

Total spend: $0.0005

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Oct 26, 2026
@senamakel
senamakel merged commit b23ebad into main Oct 26, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant