Skip to content

v0.2.0: bound search queries, record the embedding window, refresh unchanged stats, lock the inbox - #9

Merged
puretensor merged 2 commits into
mainfrom
fix/codex-audit-2026-10-25
Oct 26, 2026
Merged

puretensor merged 2 commits into
mainfrom
fix/codex-audit-2026-10-25

Conversation

@puretensor

Copy link
Copy Markdown
Owner

Fixes from a Codex security and correctness review of main @799d5cf, each re-checked. CHANGELOG updated under 0.2.0 (unreleased).

  • puremind_search refuses queries over 4,096 characters, in both the MCP schema (max_length) and the handler, instead of tokenizing and echoing them back.
  • The index records its embedding window (embed_max_seq). Changing it is refused like a model change until puremind index --rebuild, both in the indexer and at search time. An index that never recorded it adopts the current window without a forced rebuild, following the existing embedder_revision precedent, so upgrading doesn't cost every user a full re-embed.
  • An unchanged note whose mtime or size moved has its stat updated without re-embedding, so puremind_recent orders it correctly. It writes only when the stat actually changed, so large vaults don't pay a write per note per pass.
  • puremind_propose holds an fcntl lock across the dedupe, the cap check and the create, so concurrent agents can't exceed 100 proposals or store duplicates.

Tests: full suite, 691 passed, 18 skipped (fresh venv on Linux; macOS not exercised).

Not in this PR, needs the maintainer: the Homebrew formula pins v0.1.5, which predates the 0.1.6 symlink fix (1a571e9). CHANGELOG lists 0.1.6 as released on 2026-10-22, but there is no v0.1.6 tag or GitHub release, so Homebrew installs still ship the traversal bug. Tag and release, then bump the formula url/sha256.

🤖 Generated with Claude Code

puretensor and others added 2 commits October 26, 2026 13:30
…changed stats, lock the inbox

Findings from a Codex security and correctness review of main @799d5cf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…build noted in the README

- indexer.py: wrap the models import (ruff I001). A model or revision change is
  reported before a window change, so a user who changed both is told about the
  model. The window refusal names the recorded and the configured value, in
  `puremind index` and in `puremind_search`.
- README and the config.toml template: changing `embed_max_seq` takes
  `puremind index --rebuild`, and a running `puremind serve` must be restarted.
  `puremind_search` takes at most 4,096 characters.
- tests: `min()` instead of `sorted()[0]` (ruff FURB192); a model and window
  changed together report the model; the window label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@puretensor
puretensor force-pushed the fix/codex-audit-2026-10-25 branch from ba569e9 to 72d2fa6 Compare October 26, 2026 13:31
@puretensor puretensor changed the title 0.2.0: bound search queries, record the embedding window, refresh unchanged stats, lock the inbox v0.2.0: bound search queries, record the embedding window, refresh unchanged stats, lock the inbox Oct 26, 2026
@puretensor

Copy link
Copy Markdown
Owner Author

Verdict: fixed, then merged (merge commit, as with #7 and #8).

Examined: the four changes (query bound, recorded embedding window, stat refresh for unchanged notes, inbox lock) against main at 799d5cf, with three independent reviews (correctness, safety, integration) re-checked here. 0.2.0 is still unreleased (latest tag v0.1.5, CHANGELOG says "unreleased"), so the version stays 0.2.0.

Fixed in 72d2fa6:

  • ruff: wrapped the .models import in indexer.py (I001) and used min() in tests/test_indexer.py (FURB192). This was the only failing check.
  • When the model and the window change together, puremind index now reports the model change, as Service.search already did. The window refusal names the recorded and the configured value, in both puremind index and puremind_search.
  • README and the config.toml template now say that changing embed_max_seq takes puremind index --rebuild and that a running puremind serve needs a restart. The README also gives the 4,096-character query limit.
  • The first commits subject is reworded to the repos v0.2.0: form, and the PR title matches it.

Noted, not changed (design or perf follow-ups, not correctness bugs):

  • Each stat refresh is its own transaction. A bulk touch of 3,000 notes made one pass take about 10 s instead of 0.5 s, once.
  • The inbox lock waits with no timeout.
  • A rebuild for a window-only change empties the index first, as a model change does, although the vectors share one space.

Tests:

  • Full suite: 705 passed, 6 skipped (Linux, Python 3.12, CPU torch). ruff 0.17.1 and gitleaks are clean.
  • The two new tests fail against the previous indexer.
  • CI is green on 72d2fa6. real models runs only on schedule or dispatch.

#10 is stacked on this branch. Before it can merge, its own commit has to be rebased onto main and the PR retargeted to main.

@puretensor
puretensor merged commit 2d24b7d into main Oct 26, 2026
14 checks passed
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.

1 participant