Skip to content

fix(memory): tell a credit refusal and an outage apart from an empty memory (#6718) - #7013

Merged
senamakel merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:fix/6718-memory-stabilise
Oct 5, 2026
Merged

senamakel merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:fix/6718-memory-stabilise

Conversation

@CodeGhost21

@CodeGhost21 CodeGhost21 commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • A credit refusal and an outage get their own codes again. Memory RPCs now fail with INSUFFICIENT_CREDITS (the hosted engine's 402) or UNAVAILABLE (unreachable, timed out, overloaded) instead of the generic ENGINE.
  • A refused recall is no longer an empty one. When the pre-turn recall comes back empty because the engine refused the account, the turn gets a short notice saying memory is unavailable and why. Before, the model saw no pack and told the user nothing was stored.
  • Source sync stops on an account-wide refusal instead of failing every item in turn.
  • Background jobs wait for credits instead of being dropped. An account-wide refusal no longer uses up one of a job's five attempts. The run that drops a job says so.
  • UI: the Memory tabs show translated text for the two new codes, in all 14 locales.

Problem

openhuman#6841 fixed these on the old memory module. Memory v2 (#6949, #6993) replaced that module, and the fixes did not survive:

  • memory/error.rs folded Conflict, Unavailable and Engine into ENGINE. The hosted 402 arrives as Engine with a [USER_INSUFFICIENT_CREDITS] prefix. tinymemory exports is_insufficient_credits for exactly this, but nothing in openhuman called it.
  • lifecycle/hooks.rs::pre_turn logged a refused recall at warn and ran the turn with no pack, so a user out of credits got answers that read as "I don't know that".
    • Error handling alone would not have caught it: TinyMemory's holistic_recall does not fail when a section's read fails. It skips the section, keeps the engine error's text as the skip reason, and returns Ok with an empty pack.
  • sources/sync.rs stopped only on Unauthorized / Off, so a 402 failed every item one by one.
  • lifecycle/jobs.rs dropped a job after five failed runs, whatever the cause. About 25 minutes without credits left a permanent gap in the beliefs.

Solution

  • MemoryError:
    • InsufficientCredits and Unavailable variants, mapped in From<tinymemory_api::Error>.
    • is_account_wide(): off, unauthorized, out of credits or unavailable.
    • refusal_from_skip_reason(): reads the refusal back from a skip reason through the tinymemory_api::Error Display tags.
    • Both new codes are expected user states, so they are not reported as engine faults.
  • pre_turn: the session-start and turn recalls now keep their errors. If no pack is produced, refusal_of takes the first account-wide error, or the first refusing skipped section, and TurnPack::refused renders the notice. The notice sets TurnPack.refusal to the code and cites nothing.
    • An engine fault that is not account-wide still injects nothing, as before.
    • A timeout is unchanged: no pack.
  • Sync and jobs: both use is_account_wide().
  • UI: memoryErrorMessage(err, t) maps the two new codes to memory.error.* keys. UNAUTHORIZED keeps its raw message, which names the rejected key; the engine-save test depends on that. t is memoized on locale, so it was added to the hook dependency arrays.
  • Docs: docs/specs/memory-v2.md lists the codes, the refusal notice, and the job retry rule.
  • Left alone: memory/import.rs and MemoryImportBanner.tsx belong to openhuman#7011, which works around the merged code by reading the engine error directly. Once this lands, fix(memory): stop a v1 import on credits or outage instead of skipping every item #7011 can switch to the new codes.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy: 9 Rust tests (credits notice, unreachable notice, non-account-wide fault injects nothing, skip-reason read-back, error mapping, jobs keep attempts, dropped job says so) and 2 Vitest cases
  • Diff coverage ≥ 80%: not measured locally. Every changed Rust branch has a unit test; CI's diff-cover is the gate.
  • N/A: behaviour-only change. Coverage matrix rows 8.2.1, 8.2.3, 8.2.4, 8.2.5 and 8.2.10 already cite the changed test files.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per Testing Strategy): tests use TinyMemory's reference engine and a new in-process RefusingEngine fixture
  • N/A: no release-cut surface changes
  • N/A: part of a larger tracking issue that stays open (see Related)

Impact

  • Desktop and CLI (core), plus the desktop Memory UI.
  • Wire: two new structured error codes on openhuman.memory_*. Consumers that switch on code and treat unknown codes as generic failures are unaffected.
  • No migration and no config changes. jobs.json is unchanged; an existing job's attempts count is kept.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/6718-memory-stabilise
  • Commit SHA: 3b4415f

Validation Run

  • pnpm --filter openhuman-app format:check: prettier run on every changed file
  • pnpm typecheck: tsc --noEmit clean
  • Focused tests: vitest run src/services/api/memoryApi.test.ts src/components/memory src/lib/i18n src/pages: 643 passed; cargo test -p openhuman --lib -- memory:: agent::tinyagents::middleware::memory_pack: 148 passed
  • Rust fmt/check (if changed): rustfmt on changed files; cargo clippy -p openhuman --lib --tests: no findings in memory/
  • Tauri fmt/check (if changed): N/A, pre-push hook's app clippy passed

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: account-wide memory refusals are named instead of reading as an empty memory or a generic engine error.
  • User-visible effect: out of credits shows "Memory is unavailable: your account is out of credits…", and the agent says memory is unavailable rather than claiming it doesn't know.

Parity Contract

  • Legacy behavior preserved: a non-account-wide engine fault and a timeout still inject nothing; UNAUTHORIZED text is unchanged.
  • Guard/fallback/dispatch parity checks: an_engine_fault_that_is_not_account_wide_injects_nothing, existing hook and jobs tests.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: N/A
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • New Features
    • Memory errors now explain when access is blocked by insufficient credits or temporary unavailability, with localized messages in supported languages.
    • When memory can’t be accessed, the app clarifies that it may be unavailable—not empty—and that saved data remains intact.
  • Bug Fixes
    • Background memory jobs remain queued during account-wide access refusals, rather than using up retry attempts. Other failed jobs report when they reach the retry limit and are dropped.
    • Memory error messages now use the current language across memory screens.

…memory (tinyhumansai#6718)

Memory v2 folded the hosted engine's 402 and every transport fault into the
generic ENGINE code, and a refused pre-turn recall only logged a warning, so
a user out of credits got turns that read as "nothing is stored". Both were
fixed for the old memory module in tinyhumansai#6841 and did not survive the rewrite.

- MemoryError gains INSUFFICIENT_CREDITS (via tinymemory's
  is_insufficient_credits) and UNAVAILABLE, plus is_account_wide().
- pre_turn: when nothing was recalled because the engine refused the account,
  the turn gets a short notice saying memory is unavailable and why. The
  refusal is read from the hook's errors and from holistic recall's skipped
  sections, which is where a section's engine error ends up.
- Source sync stops on any account-wide refusal instead of failing each item.
- Background jobs: an account-wide refusal no longer uses up an attempt, so a
  belief build waits for credits instead of being dropped after five runs;
  the run that does drop a job says so.
- UI: memoryErrorMessage(err, t) shows translated text for the two new codes
  in all 14 locales.
@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (2)
gitbooks/developing/architecture/frontend.md — auto-discovered
AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f0d8e8ad-b3a6-44ca-86b1-182e02ade1b1
📥 Commits

Reviewing files that changed from the base of the PR and between 6c8c7ad and 3b4415f.

📒 Files selected for processing (40)
  • app/src/components/memory/MemoryAskTab.tsx
  • app/src/components/memory/MemoryBackgroundTab.tsx
  • app/src/components/memory/MemoryBrainSearch.tsx
  • app/src/components/memory/MemoryBrainTab.tsx
  • app/src/components/memory/MemoryConversationsBackfill.tsx
  • app/src/components/memory/MemoryConversationsTab.tsx
  • app/src/components/memory/MemoryEngineTab.tsx
  • app/src/components/memory/MemoryExplorerTab.tsx
  • app/src/components/memory/MemoryItemDialog.tsx
  • app/src/components/memory/MemoryLearningsTab.tsx
  • app/src/components/memory/MemoryPackPreview.tsx
  • app/src/components/memory/MemorySettingsTab.tsx
  • app/src/components/memory/MemorySyncedSources.tsx
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/Memory.tsx
  • app/src/services/api/memoryApi.test.ts
  • app/src/services/api/memoryApi.ts
  • crates/openhuman-core/src/agent/tinyagents/middleware/memory_pack_tests.rs
  • crates/openhuman-core/src/memory/error.rs
  • crates/openhuman-core/src/memory/error_tests.rs
  • crates/openhuman-core/src/memory/lifecycle/hooks.rs
  • crates/openhuman-core/src/memory/lifecycle/hooks_tests.rs
  • crates/openhuman-core/src/memory/lifecycle/jobs.rs
  • crates/openhuman-core/src/memory/lifecycle/jobs_tests.rs
  • crates/openhuman-core/src/memory/sources/sync.rs
  • crates/openhuman-core/src/memory/test_fixtures.rs
  • docs/specs/memory-v2.md

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


📝 Walkthrough

Walkthrough

The change adds insufficient-credit and unavailable memory error codes. Recall hooks can create refusal notice packs for account-wide errors, and background jobs do not count those errors as retry attempts. The API and memory interface now support translated messages for both error types.

Changes

Memory Refusal Handling

Layer / File(s) Summary
Account-wide memory error codes
crates/openhuman-core/src/memory/error.rs, crates/openhuman-core/src/memory/error_tests.rs, docs/specs/memory-v2.md
Adds INSUFFICIENT_CREDITS and UNAVAILABLE codes and error variants. Account-wide errors can be classified, and skip reasons can be parsed into refusal codes.
Recall refusal notice packs
crates/openhuman-core/src/memory/lifecycle/hooks.rs, crates/openhuman-core/src/memory/lifecycle/hooks_tests.rs, crates/openhuman-core/src/memory/test_fixtures.rs, crates/openhuman-core/src/agent/tinyagents/middleware/memory_pack_tests.rs, docs/specs/memory-v2.md
Recall errors and skipped-section refusals are checked for account-wide errors. Those errors produce notice packs; non-account-wide engine faults do not.
Background job refusal and retry handling
crates/openhuman-core/src/memory/lifecycle/jobs.rs, crates/openhuman-core/src/memory/lifecycle/jobs_tests.rs, crates/openhuman-core/src/memory/sources/sync.rs, docs/specs/memory-v2.md
Account-wide refusals do not increase job attempts. Other failures count toward the attempt limit, and dropped jobs record why. Source sync returns account-wide errors immediately.
API error recognition and formatting
app/src/services/api/memoryApi.ts, app/src/services/api/memoryApi.test.ts
The API recognizes the new error codes and maps them to translation keys when given a translator. Tests cover translated output and existing fallback behavior.
Localized memory interface errors
app/src/components/memory/*, app/src/pages/Memory.tsx, app/src/lib/i18n/*
Memory error handlers pass the translator to the formatter. Translation-dependent effects and callbacks include t, and locale files add messages for both errors.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant MemoryLifecycleHooks
  participant MemoryEngine
  participant MemoryError
  participant TurnPack
  MemoryLifecycleHooks->>MemoryEngine: recall
  MemoryEngine-->>MemoryLifecycleHooks: recall result or error
  MemoryLifecycleHooks->>MemoryError: classify refusal
  MemoryLifecycleHooks->>TurnPack: build notice for account-wide refusal
  TurnPack-->>MemoryLifecycleHooks: refusal notice pack
Loading

Suggested reviewers: al629176

Merge Risk: ⚪ Minimal · up to 3b441

The identified notice gap is not reachable in normal recall handling, and skipped refusal reasons retain their intended classification. The change is mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 3b441

The reviewed changes preserve existing access controls and use fixed refusal notices rather than forwarding raw errors to the model. However, a refusal partway through source sync can leave already-written documents without their follow-up processing.

Retained concerns

  • Medium · reliability · observed: A credit or availability refusal after successful source writes now exits before enqueueing their belief-build jobs. Those writes remain, but this sync creates no durable follow-up work for them. The source is marked Error; scheduled sources wait for their normal interval, while manual sources require another explicit sync. This broadens an existing partial-write recovery gap beyond unauthorized/off failures and weakens failure containment between stored documents and derived beliefs. Existing queued builds or hosted self-scheduling may mitigate the impact, but are not guaranteed by this path.
Security review details

Security Blast Radius

  • inferred — The demonstrated recovery concern affects documents and derived beliefs in the source's configured memory layout. The shared store_all path also serves connector records. No cross-account authority expansion was demonstrated; the maximum service-wide exposure is not established by the available coverage.

Trust Boundaries and Controls

  • observed — Engine error text can influence refusal classification, but its raw suffix is not copied into the new model notice. Fixed text crosses the pre-existing ephemeral memory-instruction boundary, without introducing a new prompt role or persisted transcript entry.

Resilience and Maintainability Implications

  • observed — Source failure recording exposes an Error state but does not reconstruct skipped follow-up jobs. Startup recovery only resets interrupted Syncing states. Neither mechanism repairs the newly expanded partial-write case; another build or successful sync is needed.

Hardening Proposals

  • proposed — Preserve durable follow-up work for sources successfully touched before an account-wide abort, while still stopping further writes. Validate recovery after a mid-batch refusal, including a manually synced source with no existing build job.
🚥 Pre-merge checks | ✅ 4 | ❓ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ❓ Inconclusive Docstring coverage is 52.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 55 functions across 36 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 summarizes the main change: distinguish memory credit refusals and outages from empty memory.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 52.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 55 functions across 36 files. (4 skipped: 1 unsupported, 3 too large.)

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit reads the memory code,
And finds two errors on the road.
“No credits” and “not here,” they say,
While saved thoughts safely stay.
Jobs wait, and notices appear,
Then carrots mark a happy year.

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

@CodeGhost21
CodeGhost21 marked this pull request as ready for review October 5, 2026 20:42
@tinysweeper

tinysweeper Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 6 lane(s) and found 1 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Reviewing pending checks
Priority: medium
Reviewed head: 3b4415f268f4
Updated: 1791233596 (Unix time)

Review snapshot

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

Completeness: Complete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

What changed

The review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

Findings

  • medium · critique · Avoid refetching policy when translations change — When the active locale changes, `t` normally gets a new function identity, so this effect runs again and `memoryPolicyGet()` calls `apply()`. That replaces `drafts` with the stored (app/src/components/memory/MemorySettingsTab\.tsx:146)

Pending checks: Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS)

Before merge

  • Wait for Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS).

How this fits together

flowchart LR
  n0["german"]:::impacted
  n1["missingKeys"]:::impacted
  n2["simplifiedChinese"]:::impacted
  n1 -->|uses| n0
  n1 -->|uses| n2
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Reviewed 40 files; 1 finding. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._
  • Evidence: app/src/components/memory/MemorySettingsTab\.tsx — Avoid refetching policy when translations change

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Reviewed 39 files; 0 findings. 1 file was not security-reviewed: docs/specs/memory-v2.md (prose or tabular data). _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: This change splits two account-wide refusals (out of credits, unreachable) out of the ENGINE memory error code, stops them from consuming job attempts or failing sync loops, and turns a refused recall into an explanatory notice for the model, with a translated message in the UI. Every new behaviour is pinned by a test that would fail on regression — the refusing-engine fixture drives the hooks and jobs tests, the skip-reason read-back is tested both ways, and the frontend mapping covers each code and the no-translator fallback. The i18n keys are added in every locale file in the diff. The change looks sound and safe to merge. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The description accurately matches the diff: the two new structured error codes, the pre-turn refusal notice, sync short-circuit, job attempt preservation, translated UI messages across all 14 locales, and the docs update are all present and behave as described. The change looks sound. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

e2e

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: This change splits two account-wide memory refusals (`INSUFFICIENT_CREDITS`, `UNAVAILABLE`) out of `ENGINE`, translates them in the memory UI, injects a refusal notice into refused recalls, and stops account-wide refusals from consuming job attempts or per-item sync. All new behaviour is covered end to end: Rust E2E tests drive `memory_v2_e2e.rs` through the JSON-RPC surface with a 402 fixture, and the frontend error mapping is verified in `app/src/services/api/memoryApi.test.ts` (unit lane, not E2E) — but the user-facing surface the E2E reaches is the RPC error code itself, which the Rust E2E harness covers. The frontend i18n keys are exercised by the colocated Vitest and the i18n coverage checks. No E2E test was weakened. The change looks sound from the E2E coverage standpoint; the frontend refusal path (a real 402 surfacing as the translated message in the running app) has no browser/desktop E2E spec, but the RPC contract that feeds it is E2E-covered in Rust and the mapping is unit-tested, so I judge the residual gap low-severity and report it as such. Waiting on end-to-end jobs: `Rust E2E (mock backend)`, `Build Playwright E2E Artifact`, `E2E (Playwright / web lane)`, `Desktop E2E (full suite, 3 OS)`.
  • Unresolved questions/checks: Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS)
Evidence and run details
  • Models: gpt-5.6-luna, glm-5.3-flash, deepseek-v4.1-flash
  • Spend: $0.014665
  • Tokens: 1179313 input · 45870 output · 100105 cached · 0 embedding
Head State Pass summary
3b4415f268f4 pending 1 active finding(s), 0 resolved finding(s) (at 1791233596)

tinysweeper 0.1.0

@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.

             $0.0147 · 1,179,313 in / 45,870 out · 100,105 cached (8%) · gpt-5.6-luna, glm-5.3-flash, deepseek-v4.1-flash
critique:    $0.0064 · 530,446 in   / 21,713 out · 51,162 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security:    $0.0069 · 496,579 in   / 18,378 out · 43,311 cached (9%)  · gpt-5.6-luna
tests:       $0.0006 · 48,706 in    / 1,475 out  · 2,752 cached (6%)   · glm-5.3-flash
description: $0.0003 · 24,062 in    / 293 out    · 64 cached (0%)      · glm-5.3-flash
e2e:         $0.0004 · 55,320 in    / 1,996 out  · 2,816 cached (5%)   · glm-5.3-flash, deepseek-v4.1-flash

cancelled = true;
};
}, [apply]);
}, [apply, t]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium critique likely

Avoid refetching policy when translations change

When the active locale changes, t normally gets a new function identity, so this effect runs again and memoryPolicyGet() calls apply(). That replaces drafts with the stored policy, meaning a user who has edited a field but has not yet blurred or pressed Enter loses the edit merely by changing language. It can also overwrite a just-completed save if the refetch returns an older snapshot. Translate the error without making the policy-loading effect rerun on translation changes.

[RULE] unrelated-effect-dependency ·

@tinysweeper tinysweeper Bot added the priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later. label Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants