Skip to content

Promote main -> release (conflict-resolved) - #5433

Merged
M3gA-Mind merged 188 commits into
tinyhumansai:releasefrom
M3gA-Mind:promote/main-to-release-2026-08-07
Aug 7, 2026
Merged

Promote main -> release (conflict-resolved)#5433
M3gA-Mind merged 188 commits into
tinyhumansai:releasefrom
M3gA-Mind:promote/main-to-release-2026-08-07

Conversation

@M3gA-Mind

@M3gA-Mind M3gA-Mind commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Base is release. This is the promote direction — it advances what staging and production build from. A separate PR carries the mirror (release → main, base main); do not confuse their resolutions, they hold the version files in opposite directions.

What this does

Brings release to main's tree at 8deb5f276.

Only the six version-bearing files differ from main, and they are held at release's higher v0.63.10 rather than main's v0.63.6 — a release must never go backwards.

$ git diff --stat upstream/main
 Cargo.lock                    | 2 +-
 Cargo.toml                    | 2 +-
 app/package.json              | 2 +-
 app/src-tauri/Cargo.lock      | 4 ++--
 app/src-tauri/Cargo.toml      | 2 +-
 app/src-tauri/tauri.conf.json | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

Every hunk in those six is the same substitution, 0.63.60.63.10. Nothing else in the tree differs from main in either direction.

It is a real two-parent merge, which is the point of doing it this way:

$ git log -1 --pretty=%P
2ba803a246f8af20e3278c8acb62f34be2b421f5   ← release, v0.63.10
8deb5f2769c97ad059be2a6acae9f23c9c00dc3b   ← main, #5427

Release carried no unique code

Two independent checks, because the promote commits in release's history were hand-resolved and a wrong resolution is exactly the thing that would hide release-only content.

By commit. Release's nine unique commits are five version bumps (v0.63.6v0.63.10), three squashed promotes of main's own content (#5242, #5256, #5414), and one real change — 42cdf77e7, the appimage userns fix (#5251). That fix's two files, scripts/release/test-strip-appimage-rpaths.sh and scripts/release/validate-appimage-runtime.sh, are byte-identical between main and release: it reached main separately as #5252 (9750b8077).

By tree, which is the stronger check. main and release differ in 37 paths, every one a modification — nothing added and nothing deleted in either direction:

$ git diff --name-status upstream/main upstream/release | awk '{print $1}' | sort | uniq -c
  37 M

For each of the 31 non-version paths, release's blob is reachable in main's history, appearing as the pre-image of a later main commit — i.e. release holds an older state of a file main has since moved past. There is no path where release's content is novel.

So taking main's tree wholesale discards nothing.

The 14 conflicts are squash-trap artifacts

13 unmerged entries (the 14th line in the conflict output is the rename/delete half of a pair whose unmerged entry sits on the new path):

Cargo.lock, Cargo.toml, app/package.json,
app/src-tauri/{Cargo.lock, Cargo.toml, tauri.conf.json}        ← the six version files
app/src/components/intelligence/MemoryTreeStatusPanel.test.tsx (content)
app/src/features/human/voice/useRealtimeVoiceSession.ts        (add/add)
app/src/features/human/voice/useRealtimeVoiceSession.test.ts   (add/add)
src/openhuman/config/schema/load/mod.rs                        (content)
src/openhuman/inference/embeddings/cloud_adapter.rs            (add/add, paired with a
    rename/delete from src/openhuman/embeddings/cloud_adapter.rs)
src/openhuman/memory/tree/tree/rpc.rs                          (content)
vendor/tinycortex                                              (submodule)

None of them is divergence. The promotes were squash-merged, so no merge commit recorded main as an ancestor and the merge-base is frozen at 2219d4207. Git therefore cannot see that release already holds main's tree, and re-derives moves main made itself during the kernelization as add/add and rename/delete pairs — embeddings/cloud_adapter.rsinference/embeddings/cloud_adapter.rs is precisely that.

Resolution: git read-tree -u --reset upstream/main to set index and worktree to main's tree exactly — which is also what clears the rename/delete leftover a per-file checkout would have stranded — then the six version files restored from upstream/release. MERGE_HEAD survives that, so the result is a genuine merge commit rather than a squashed snapshot.

Maintainer note — please read before merging

Squashing this PR will recreate the problem it is fixing.

The repository allows squash merges only (allow_merge_commit: false). Squashed, this lands as a single commit with one parent, main is again not recorded as an ancestor, the merge-base stays at 2219d4207, and the next promote and the next back-merge re-fight this same conflict set — with everything merged in between added to it.

That has now cost three hand-resolutions in one day (#5414, this, and the mirror back-merge). It is not a git accident; it is a settings consequence, and it compounds.

Two durable fixes, either of which ends it:

  1. Enable merge commits for this branch so a promote can land as a real merge and the merge-base advances.
  2. Unblock the Promote main to release workflow so the sanctioned path works. It is currently unusable for two separate reasons: a dispatch from 17:40 is stuck waiting on the Release-PR-Automation environment approval, which M3gA-Mind cannot grant; and even once it runs it cannot resolve conflicts by hand, so it would fail on these 13 regardless.

Until one of those happens, every promote needs a human to re-derive this resolution from scratch, and the conflict set only grows.

Verification

  • git diff --stat upstream/main → the six version files, nothing else (pasted above)
  • git log -1 --pretty=%P → two parents, release then main (pasted above)
  • git merge-base --is-ancestor upstream/main HEAD → yes; same for upstream/release
  • git status --porcelain → clean; no path present here and absent on main
  • No build was run locally. CI is the gate.

Summary by CodeRabbit

  • New Features

    • Retry failed memory tasks directly from the status panel, with progress, success/error feedback, and refreshed results.
    • Upload custom mascot avatars using supported image formats, with size and type validation, previews, and reset controls.
    • Improved realtime voice session identity handling for more reliable connections.
  • Bug Fixes

    • Resolved outdated failure notices after newer memory tasks complete successfully.
    • Improved credential resolution across account and workspace contexts.
  • Localization

    • Added and updated translations for retry actions and custom image avatar settings across supported languages.

YellowSnnowmann and others added 30 commits July 21, 2026 19:01
…eature (tinyhumansai#5049) (tinyhumansai#5061)

Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
…ai#4786)

Co-authored-by: Sami Rusani <14844597+samrusani@users.noreply.github.com>
Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
…nsai#5103)

Co-authored-by: Sami Rusani <14844597+samrusani@users.noreply.github.com>
…4929) (tinyhumansai#4998)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
Co-authored-by: Cyrus Gray <144336577+graycyrus@users.noreply.github.com>
Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
Co-authored-by: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: sanil-23 <sanil@tinyhumans.ai>
Co-authored-by: M3gA-Mind <elvin@mahadao.com>
Co-authored-by: oxoxDev <oxoxdev@users.noreply.github.com>
Co-authored-by: Sami Rusani <14844597+samrusani@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
…roval prompt (tinyhumansai#5094)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
…completes epic tinyhumansai#4795 (tinyhumansai#5029)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
YellowSnnowmann and others added 22 commits August 4, 2026 14:59
…transcript soak (tinyhumansai#5396)

Co-authored-by: Medulla <medulla@tinyhumans.ai>
…ers (tinyhumansai#5367)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…the parked queue (tinyhumansai#5427)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Brings release to main's tree at 8deb5f2. The only files that differ from
main are the six version-bearing ones, held at release's v0.63.10 rather than
main's v0.63.6 — a release must never go backwards.

All 13 conflicts were squash-trap artifacts, not divergence. Release's nine
unique commits are five version bumps, three squashed promotes of main's own
content, and one appimage fix (tinyhumansai#5251) whose two files are byte-identical to
main's copy (tinyhumansai#5252). Verified further: main and release differ in 37 paths,
every one a modification with nothing added or deleted in either direction,
and every one of release's blobs is reachable in main's history — so release
carries no code main lacks.

The conflicts arise because the promotes were squash-merged, freezing the
merge-base at 2219d42, so git cannot see that release already holds main's
tree and re-derives the kernelization's own moves as add/add and rename/delete
pairs.

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@M3gA-Mind

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds failed Memory Tree job retries, local mascot image uploads, realtime voice token forwarding, scoped cloud credential resolution, failure-cause supersession, localized messages, tests, analytics support, and a TinyCortex revision update.

Changes

Memory Tree retry flow

Layer / File(s) Summary
Failure status supersession
src/openhuman/memory/tree/tree/rpc.rs
Failure causes are hidden when a newer successful job supersedes them. Legacy and active failure cases remain supported.
Retry command and status panel
app/src/utils/tauriCommands/memoryTree.ts, app/src/components/intelligence/MemoryTreeStatusPanel.tsx, app/src/services/analytics.ts, app/src/components/intelligence/MemoryTreeStatusPanel.test.tsx
Failed jobs can be requeued with busy-state protection, analytics, toasts, status refresh, and test coverage.
Retry translations
app/src/lib/i18n/*
Retry action, progress, success, count, and error messages are localized.

Mascot image avatars

Layer / File(s) Summary
Avatar validation and persistence
app/src/store/mascotSlice.ts, app/src/store/__tests__/mascotSlice.test.ts
Safe raster sources and bounded base64 data URLs are accepted. Unsafe, malformed, and oversized values are rejected.
Avatar upload interaction
app/src/components/settings/panels/MascotPanel.tsx, app/src/components/settings/panels/__tests__/MascotPanel.test.tsx
The panel supports validated uploads, data-URL previews, reset handling, and stale-read protection.
Avatar translations
app/src/lib/i18n/*
Mascot image upload, validation, size, read-error, and custom-image text is localized.

Realtime voice session

Layer / File(s) Summary
Voice session token forwarding
app/src/features/human/voice/useRealtimeVoiceSession.ts, app/src/features/human/voice/useRealtimeVoiceSession.test.ts
The authenticated token is sent through customLlmExtraBody.user, while userId remains available for provider attribution.

Cloud credentials

Layer / File(s) Summary
Workspace resolver availability
src/openhuman/config/mod.rs, src/openhuman/config/schema/mod.rs, src/openhuman/config/schema/load/mod.rs
The workspace configuration-directory resolver is available to production consumers.
Credential directory resolution
src/openhuman/inference/embeddings/cloud_adapter.rs
Cloud embedding credentials use workspace mapping and active or pre-login user scopes, with tests for each path.

TinyCortex reference

Layer / File(s) Summary
Vendored revision
vendor/tinycortex
The submodule reference is updated.

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

Possibly related PRs

Suggested reviewers: senamakel, yomxxx, obchain

Poem

A rabbit retries the jobs in line,
Uploads a bright avatar sign.
Voice tokens hop through the air,
Credentials find their proper lair.
Tests and translations bloom—
TinyCortex thumps in tune.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: promoting main to release with conflict resolution.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@M3gA-Mind
M3gA-Mind merged commit 18db547 into tinyhumansai:release Aug 7, 2026
32 of 36 checks passed

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c3d648263

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

type MemorySyncStatusRow,
memoryTreePipelineStatus,
type MemoryTreePipelineStatus,
memoryTreeRetryFailed,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Recreate this as a real promote merge

This is a commit-level issue rather than a problem with this import: git rev-list --parents -n 1 40a0edc4 shows only parent 2ba803a246f8af20e3278c8acb62f34be2b421f5 and does not record 8deb5f2769c97ad059be2a6acae9f23c9c00dc3b as a second parent, even though the release promotion path is supposed to be a merge from main into release. If this lands, main is still not an ancestor of release, so the next promote/back-merge keeps the stale merge-base and re-fights these same conflicts; recreate it as a true two-parent merge before merging.

Useful? React with 👍 / 👎.

Comment on lines +202 to +205
if (!isAllowedMimeType(file.type)) {
console.debug('[mascot-avatar] rejected upload: unsupported type', file.type);
setCustomGifError(t('settings.mascot.customGifInvalidType'));
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Invalidate pending uploads on rejected file picks

If a valid avatar is already being read and the user then chooses an unsupported or too-large file, these early-return validation branches do not increment avatarWriteIdRef. The older read still sees its writeId as current, clears the new error, and dispatches the stale avatar, so a rejected second selection can still leave the first image saved; bump the write id before any validation return.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/components/settings/panels/MascotPanel.tsx`:
- Around line 223-226: Update the Upload image Button and accepted-upload
handling in MascotPanel: assign the Button a stable content-free analyticsId,
and call trackAnalyticsEvent only after the accepted upload has been stored via
setCustomMascotGifUrl. Use only non-sensitive fixed dimensions, excluding
File.name, the data URL, and error text.
- Around line 200-213: Update onUploadAvatarFile so avatarWriteIdRef is
incremented immediately after the !file guard, before MIME-type and size
validation, invalidating any pending valid read when a replacement file is
rejected. Preserve the existing rejection errors and add coverage for a pending
valid read followed by an invalid file selection.

In `@app/src/lib/i18n/ar.ts`:
- Line 5726: Update the Arabic translation string for
settings.mascot.customGifError to remove the local-URL wording while preserving
the HTTPS URL option, upload action, and supported image formats.

In `@app/src/lib/i18n/de.ts`:
- Around line 1354-1355: Update the German translations for
memoryTree.status.retryFailed and memoryTree.status.retryFailedBusy to describe
requeuing failed jobs rather than executing them, matching the wording used by
memoryTree.status.retryFailedDone and keeping the action and busy-state
terminology consistent.
- Line 6020: Update the German user-facing message in the translation entry to
describe HTTPS, file://, and local paths as parallel supported Bild-URL forms,
while retaining the existing PNG, GIF, JPEG, WebP, and BMP formats and the
upload option. Keep the message limited to normal URL and file-upload paths.

In `@app/src/lib/i18n/fr.ts`:
- Around line 5998-6000: Update the French custom mascot localization entries,
including settings.mascot.customGifHeading, settings.mascot.customGifLabel, and
the related message at the second occurrence, to use natural “image d’avatar
personnalisée” wording. Replace implementation-specific file:// language with
concise user-facing guidance describing a local path, while preserving the
supported image-format and URL/upload guidance.

In `@app/src/lib/i18n/hi.ts`:
- Line 5970: Update the persona appearance description string in hi.ts to use
the plural Hindi agreement ending for the three listed settings, replacing the
singular “कॉन्फ़िगर किया गया है” while preserving the rest of the translation.
- Around line 5855-5863: Update the user-facing custom mascot image URL error
message near the preceding mascot settings translations to mention only HTTPS
image URLs and file uploads. Remove the file:// and स्थानीय इमेज URL guidance,
while retaining PNG, GIF, JPEG, WebP, and BMP in the supported format list.

In `@src/openhuman/memory/tree/tree/rpc.rs`:
- Around line 1889-1933: Extend the test coverage around plant_failed_and_done
to create a failed job with a typed failure and completed_at_ms set to NULL,
then assert latest_failed_job_failure returns the expected PipelineFailure. Add
a separate helper or test setup path rather than requiring failed_at_ms, while
preserving the existing timestamped failed-row coverage.

In `@vendor/tinycortex`:
- Line 1: Update requeue_failed_where so failed rows whose dedupe key exists in
active_keys are marked cancelled and have their failure fields cleared before
being skipped. Ensure retry_all_failed no longer leaves these stale failures
counted, while preserving existing requeue behavior for other failed rows.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 349a0a86-4d8e-44bd-bc31-089da4e0391b

📥 Commits

Reviewing files that changed from the base of the PR and between 2ba803a and 6c3d648.

📒 Files selected for processing (31)
  • app/src/components/intelligence/MemoryTreeStatusPanel.test.tsx
  • app/src/components/intelligence/MemoryTreeStatusPanel.tsx
  • app/src/components/settings/panels/MascotPanel.tsx
  • app/src/components/settings/panels/__tests__/MascotPanel.test.tsx
  • app/src/features/human/voice/useRealtimeVoiceSession.test.ts
  • app/src/features/human/voice/useRealtimeVoiceSession.ts
  • 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/services/analytics.ts
  • app/src/store/__tests__/mascotSlice.test.ts
  • app/src/store/mascotSlice.ts
  • app/src/utils/tauriCommands/memoryTree.test.ts
  • app/src/utils/tauriCommands/memoryTree.ts
  • src/openhuman/config/mod.rs
  • src/openhuman/config/schema/load/mod.rs
  • src/openhuman/config/schema/mod.rs
  • src/openhuman/inference/embeddings/cloud_adapter.rs
  • src/openhuman/memory/tree/tree/rpc.rs
  • vendor/tinycortex

Comment on lines +200 to +213
const onUploadAvatarFile = async (file: File | undefined) => {
if (!file) return;
if (!isAllowedMimeType(file.type)) {
console.debug('[mascot-avatar] rejected upload: unsupported type', file.type);
setCustomGifError(t('settings.mascot.customGifInvalidType'));
return;
}
if (file.size > MAX_CUSTOM_MASCOT_AVATAR_UPLOAD_BYTES) {
console.debug('[mascot-avatar] rejected upload: too large', file.size);
setCustomGifError(t('settings.mascot.customGifTooLarge'));
return;
}
avatarWriteIdRef.current += 1;
const writeId = avatarWriteIdRef.current;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Invalidate pending reads before rejecting a replacement file.

Lines 202-211 return before incrementing avatarWriteIdRef. If a valid upload is still reading, then the user selects an invalid or oversize file, the earlier read remains current and can later set the avatar despite the rejection error.

Increment the write ID immediately after the !file check. Add a test where a pending valid read is followed by an invalid file selection.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/components/settings/panels/MascotPanel.tsx` around lines 200 - 213,
Update onUploadAvatarFile so avatarWriteIdRef is incremented immediately after
the !file guard, before MIME-type and size validation, invalidating any pending
valid read when a replacement file is rejected. Preserve the existing rejection
errors and add coverage for a pending valid read followed by an invalid file
selection.

Comment on lines +223 to +226
console.debug('[mascot-avatar] upload accepted', file.type, file.size);
setCustomGifError(null);
setCustomGifDraft('');
dispatch(setCustomMascotGifUrl(dataUri));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add required analytics for the upload flow.

Give the Upload image Button a stable, content-free analyticsId. Call trackAnalyticsEvent only after an accepted upload is stored. Do not send File.name, the data URL, or error text in analytics dimensions.

Also applies to: 690-697

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/components/settings/panels/MascotPanel.tsx` around lines 223 - 226,
Update the Upload image Button and accepted-upload handling in MascotPanel:
assign the Button a stable content-free analyticsId, and call
trackAnalyticsEvent only after the accepted upload has been stored via
setCustomMascotGifUrl. Use only non-sensitive fixed dimensions, excluding
File.name, the data URL, and error text.

Sources: Coding guidelines, Learnings

Comment thread app/src/lib/i18n/ar.ts
'settings.mascot.customGifHeading': 'الصورة الرمزية GIF المخصصة',
'settings.mascot.customGifLabel': 'الصورة الرمزية GIF المخصصة URL',
'settings.mascot.customGifPlaceholder': 'https://example.com/avatar.gif',
'أدخل رابط صورة HTTPS أو file:// أو رابطًا محليًا (PNG أو GIF أو JPEG أو WebP أو BMP)، أو ارفع ملفًا.',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the local-URL implementation detail.

“رابطًا محليًا” exposes the developer-oriented loopback URL path. Keep the HTTPS URL, upload action, and supported format list.

Proposed fix
-    'أدخل رابط صورة HTTPS أو file:// أو رابطًا محليًا (PNG أو GIF أو JPEG أو WebP أو BMP)، أو ارفع ملفًا.',
+    'أدخل رابط صورة HTTPS أو file:// (PNG أو GIF أو JPEG أو WebP أو BMP)، أو ارفع ملفًا.',

Based on learnings, “Do not enumerate … developer-oriented loopback HTTP URLs” in settings.mascot.customGifError.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'أدخل رابط صورة HTTPS أو file:// أو رابطًا محليًا (PNG أو GIF أو JPEG أو WebP أو BMP)، أو ارفع ملفًا.',
'أدخل رابط صورة HTTPS أو file:// (PNG أو GIF أو JPEG أو WebP أو BMP)، أو ارفع ملفًا.',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/ar.ts` at line 5726, Update the Arabic translation string
for settings.mascot.customGifError to remove the local-URL wording while
preserving the HTTPS URL option, upload action, and supported image formats.

Source: Learnings

Comment thread app/src/lib/i18n/de.ts
Comment on lines +1354 to +1355
'memoryTree.status.retryFailed': 'Fehlgeschlagene Jobs erneut ausführen',
'memoryTree.status.retryFailedBusy': 'Wird wiederholt...',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the retry wording with the command behavior.

memoryTree.status.retryFailed says that failed jobs are executed again. This command requeues them. Use the same wording as memoryTree.status.retryFailedDone for the action and busy state.

Based on the PR objective, the retry command requeues failed Memory Tree jobs rather than executing them immediately.

Suggested wording
-  'memoryTree.status.retryFailed': 'Fehlgeschlagene Jobs erneut ausführen',
-  'memoryTree.status.retryFailedBusy': 'Wird wiederholt...',
+  'memoryTree.status.retryFailed': 'Fehlgeschlagene Jobs erneut einreihen',
+  'memoryTree.status.retryFailedBusy':
+    'Fehlgeschlagene Jobs werden erneut eingereiht…',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'memoryTree.status.retryFailed': 'Fehlgeschlagene Jobs erneut ausführen',
'memoryTree.status.retryFailedBusy': 'Wird wiederholt...',
'memoryTree.status.retryFailed': 'Fehlgeschlagene Jobs erneut einreihen',
'memoryTree.status.retryFailedBusy':
'Fehlgeschlagene Jobs werden erneut eingereiht…',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/de.ts` around lines 1354 - 1355, Update the German
translations for memoryTree.status.retryFailed and
memoryTree.status.retryFailedBusy to describe requeuing failed jobs rather than
executing them, matching the wording used by memoryTree.status.retryFailedDone
and keeping the action and busy-state terminology consistent.

Comment thread app/src/lib/i18n/de.ts
'settings.mascot.customGifHeading': 'Benutzerdefinierter GIF-Avatar',
'settings.mascot.customGifLabel': 'URL für benutzerdefinierten GIF-Avatar',
'settings.mascot.customGifPlaceholder': 'https://example.com/avatar.gif',
'Gib eine HTTPS-, file:// oder lokale Bild-URL (PNG, GIF, JPEG, WebP oder BMP) ein oder lade eine Datei hoch.',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clarify the URL forms in the error message.

HTTPS-, file:// oder lokale Bild-URL is not a parallel German phrase. Keep the same supported schemes and formats, but describe them as one Bild-URL list.

Based on learnings, keep this user-facing message limited to normal URL and upload paths, and keep BMP in the format list.

Suggested wording
-    'Gib eine HTTPS-, file:// oder lokale Bild-URL (PNG, GIF, JPEG, WebP oder BMP) ein oder lade eine Datei hoch.',
+    'Gib eine Bild-URL über HTTPS oder file:// (PNG, GIF, JPEG, WebP oder BMP) ein oder lade eine Datei hoch.',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'Gib eine HTTPS-, file:// oder lokale Bild-URL (PNG, GIF, JPEG, WebP oder BMP) ein oder lade eine Datei hoch.',
'Gib eine Bild-URL über HTTPS oder file:// (PNG, GIF, JPEG, WebP oder BMP) ein oder lade eine Datei hoch.',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/de.ts` at line 6020, Update the German user-facing message
in the translation entry to describe HTTPS, file://, and local paths as parallel
supported Bild-URL forms, while retaining the existing PNG, GIF, JPEG, WebP, and
BMP formats and the upload option. Keep the message limited to normal URL and
file-upload paths.

Source: Learnings

Comment thread app/src/lib/i18n/fr.ts
Comment on lines +5998 to +6000
'Saisissez une URL d’image HTTPS, file:// ou locale (PNG, GIF, JPEG, WebP ou BMP), ou importez un fichier.',
'settings.mascot.customGifHeading': 'Avatar image personnalisé',
'settings.mascot.customGifLabel': 'URL de l’avatar image personnalisé',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use natural French for the custom avatar wording.

Avatar image personnalisé, URL de l’avatar image personnalisé, and avatar personnalisé en image are not idiomatic French. The file:// wording is also too implementation-specific and ambiguous for users.

Use image d’avatar personnalisée and describe the local option as a local path.

Proposed wording
-    'Saisissez une URL d’image HTTPS, file:// ou locale (PNG, GIF, JPEG, WebP ou BMP), ou importez un fichier.',
-  'settings.mascot.customGifHeading': 'Avatar image personnalisé',
-  'settings.mascot.customGifLabel': 'URL de l’avatar image personnalisé',
+    'Saisissez une URL d’image HTTPS ou un chemin local (PNG, GIF, JPEG, WebP ou BMP), ou importez un fichier.',
+  'settings.mascot.customGifHeading': 'Image d’avatar personnalisée',
+  'settings.mascot.customGifLabel': 'URL de l’image d’avatar personnalisée',
...
-    "La couleur de la mascotte, l'avatar personnalisé en image et la voix de réponse sont configurés dans les paramètres de la mascotte.",
+    "La couleur de la mascotte, l'image d'avatar personnalisée et la voix de réponse sont configurées dans les paramètres de la mascotte.",

Based on learnings, keep custom avatar messages concise and focused on user-facing URL and upload guidance.

Also applies to: 6117-6117

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/fr.ts` around lines 5998 - 6000, Update the French custom
mascot localization entries, including settings.mascot.customGifHeading,
settings.mascot.customGifLabel, and the related message at the second
occurrence, to use natural “image d’avatar personnalisée” wording. Replace
implementation-specific file:// language with concise user-facing guidance
describing a local path, while preserving the supported image-format and
URL/upload guidance.

Source: Learnings

Comment thread app/src/lib/i18n/hi.ts
Comment on lines +5855 to +5863
'HTTPS, file://, या स्थानीय इमेज URL (PNG, GIF, JPEG, WebP, या BMP) दर्ज करें, या कोई फ़ाइल अपलोड करें।',
'settings.mascot.customGifHeading': 'कस्टम इमेज अवतार',
'settings.mascot.customGifLabel': 'कस्टम इमेज अवतार URL',
'settings.mascot.customGifPlaceholder': 'https://example.com/avatar.png',
'settings.mascot.customGifUpload': 'इमेज अपलोड करें',
'settings.mascot.customGifInvalidType':
'असमर्थित फ़ाइल प्रकार। PNG, GIF, JPEG, WebP, या BMP इमेज अपलोड करें।',
'settings.mascot.customGifTooLarge': 'इमेज बहुत बड़ी है। 1.5 MB तक की फ़ाइल अपलोड करें।',
'settings.mascot.customGifReadError': 'यह इमेज पढ़ी नहीं जा सकी। कृपया दूसरी फ़ाइल आज़माएँ।',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove implementation-only URL schemes from the user-facing error.

The message already directs users to upload a file, but it also lists file:// and स्थानीय इमेज URL. These inputs are not clear normal user guidance. Focus the message on HTTPS image URLs and file uploads. Keep BMP in the format list.

Based on learnings: custom mascot avatar errors should omit developer-only URL inputs and include BMP when upload validation supports it.

Proposed wording
   'settings.mascot.customGifError':
-    'HTTPS, file://, या स्थानीय इमेज URL (PNG, GIF, JPEG, WebP, या BMP) दर्ज करें, या कोई फ़ाइल अपलोड करें।',
+    'एक HTTPS इमेज URL दर्ज करें, या PNG, GIF, JPEG, WebP, या BMP फ़ाइल अपलोड करें।',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'HTTPS, file://, या स्थानीय इमेज URL (PNG, GIF, JPEG, WebP, या BMP) दर्ज करें, या कोई फ़ाइल अपलोड करें।',
'settings.mascot.customGifHeading': 'कस्टम इमेज अवतार',
'settings.mascot.customGifLabel': 'कस्टम इमेज अवतार URL',
'settings.mascot.customGifPlaceholder': 'https://example.com/avatar.png',
'settings.mascot.customGifUpload': 'इमेज अपलोड करें',
'settings.mascot.customGifInvalidType':
'असमर्थित फ़ाइल प्रकार। PNG, GIF, JPEG, WebP, या BMP इमेज अपलोड करें।',
'settings.mascot.customGifTooLarge': 'इमेज बहुत बड़ी है। 1.5 MB तक की फ़ाइल अपलोड करें।',
'settings.mascot.customGifReadError': 'यह इमेज पढ़ी नहीं जा सकी। कृपया दूसरी फ़ाइल आज़माएँ।',
'एक HTTPS इमेज URL दर्ज करें, या PNG, GIF, JPEG, WebP, या BMP फ़ाइल अपलोड करें।',
'settings.mascot.customGifHeading': 'कस्टम इमेज अवतार',
'settings.mascot.customGifLabel': 'कस्टम इमेज अवतार URL',
'settings.mascot.customGifPlaceholder': 'https://example.com/avatar.png',
'settings.mascot.customGifUpload': 'इमेज अपलोड करें',
'settings.mascot.customGifInvalidType':
'असमर्थित फ़ाइल प्रकार। PNG, GIF, JPEG, WebP, या BMP इमेज अपलोड करें।',
'settings.mascot.customGifTooLarge': 'इमेज बहुत बड़ी है। 1.5 MB तक की फ़ाइल अपलोड करें।',
'settings.mascot.customGifReadError': 'यह इमेज पढ़ी नहीं जा सकी। कृपया दूसरी फ़ाइल आज़माएँ।',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/hi.ts` around lines 5855 - 5863, Update the user-facing
custom mascot image URL error message near the preceding mascot settings
translations to mention only HTTPS image URLs and file uploads. Remove the
file:// and स्थानीय इमेज URL guidance, while retaining PNG, GIF, JPEG, WebP, and
BMP in the supported format list.

Source: Learnings

Comment thread app/src/lib/i18n/hi.ts
'settings.persona.appearanceHeading': 'अवतार और आवाज',
'settings.persona.appearanceDesc':
'Mascot रंग, कस्टम GIF अवतार, और उत्तर आवाज Mascot सेटिंग्स में कॉन्फ़िगर किया गया है।',
'Mascot रंग, कस्टम इमेज अवतार, और उत्तर आवाज Mascot सेटिंग्स में कॉन्फ़िगर किया गया है।',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix plural agreement in the persona appearance description.

The sentence lists three settings but uses the singular ending कॉन्फ़िगर किया गया है. Use plural agreement.

Proposed wording
-    'Mascot रंग, कस्टम इमेज अवतार, और उत्तर आवाज Mascot सेटिंग्स में कॉन्फ़िगर किया गया है।',
+    'Mascot का रंग, कस्टम इमेज अवतार और उत्तर की आवाज़ Mascot सेटिंग्स में कॉन्फ़िगर किए जाते हैं।',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'Mascot रंग, कस्टम इमेज अवतार, और उत्तर आवाज Mascot सेटिंग्स में कॉन्फ़िगर किया गया है।',
'Mascot का रंग, कस्टम इमेज अवतार और उत्तर की आवाज़ Mascot सेटिंग्स में कॉन्फ़िगर किए जाते हैं।',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/hi.ts` at line 5970, Update the persona appearance
description string in hi.ts to use the plural Hindi agreement ending for the
three listed settings, replacing the singular “कॉन्फ़िगर किया गया है” while
preserving the rest of the translation.

Comment on lines +1889 to +1933
fn plant_failed_and_done(
cfg: &Config,
reason: &str,
failed_at_ms: i64,
done_at_ms: Option<i64>,
) {
use crate::openhuman::memory::queue::store as queue_store;
use crate::openhuman::memory::queue::types::{FlushStalePayload, NewJob};

let failed_job =
NewJob::flush_stale(&FlushStalePayload::default(), "2026-07-10", 3).unwrap();
let failed_id = queue_store::enqueue(cfg, &failed_job)
.unwrap()
.expect("enqueue failed-row");

let done_id = done_at_ms.map(|_| {
let done_job =
NewJob::flush_stale(&FlushStalePayload::default(), "2026-08-06", 3).unwrap();
queue_store::enqueue(cfg, &done_job)
.unwrap()
.expect("enqueue done-row")
});

chunk_store::with_connection(cfg, |conn| {
conn.execute(
"UPDATE mem_tree_jobs
SET status = 'failed',
failure_reason = ?2,
failure_class = 'unrecoverable',
completed_at_ms = ?3
WHERE id = ?1",
rusqlite::params![failed_id, reason, failed_at_ms],
)?;
if let (Some(done_id), Some(done_at_ms)) = (done_id.as_ref(), done_at_ms) {
conn.execute(
"UPDATE mem_tree_jobs
SET status = 'done', completed_at_ms = ?2
WHERE id = ?1",
rusqlite::params![done_id, done_at_ms],
)?;
}
Ok(())
})
.unwrap();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover the legacy failed-row branch.

Line 1892 requires a non-null failed_at_ms. Line 1920 always writes it to completed_at_ms. The new tests therefore do not exercise Lines 743-748, where a typed failure without a timestamp must remain visible.

Add a test that writes completed_at_ms = NULL for a typed failed row and asserts that latest_failed_job_failure returns its PipelineFailure.

As per coding guidelines, add tests for new or changed behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/memory/tree/tree/rpc.rs` around lines 1889 - 1933, Extend the
test coverage around plant_failed_and_done to create a failed job with a typed
failure and completed_at_ms set to NULL, then assert latest_failed_job_failure
returns the expected PipelineFailure. Add a separate helper or test setup path
rather than requiring failed_at_ms, while preserving the existing timestamped
failed-row coverage.

Source: Coding guidelines

Comment thread vendor/tinycortex
@@ -1 +1 @@
Subproject commit e0a8738980965411f514f4a62c09f941efdea90c
Subproject commit 5fabcf18d9e3907d6b26b59528ad49cebfc1c271

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
old="e0a8738980965411f514f4a62c09f941efdea90c"
new="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

test -n "$url"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$old" "$new"

git -C "$tmp/repo" cat-file -e "${old}^{commit}"
git -C "$tmp/repo" cat-file -e "${new}^{commit}"

echo "Changed files:"
git -C "$tmp/repo" diff --name-status "$old" "$new"

echo "Diff summary:"
git -C "$tmp/repo" diff --stat "$old" "$new"

echo "Relevant API definitions:"
for revision in "$old" "$new"; do
  echo "== $revision =="
  git -C "$tmp/repo" grep -n -E 'self_heal|run_summarization_observed' "$revision" -- || true
done

Repository: tinyhumansai/openhuman

Length of output: 10544


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
old="e0a8738980965411f514f4a62c09f941efdea90c"
new="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$old" "$new"

echo "=== TinyCortex diff ==="
git -C "$tmp/repo" diff --find-renames --find-copies --unified=80 "$old" "$new" -- \
  src/memory/queue/store_settle.rs \
  src/memory/queue/store_settle_tests.rs

echo "=== API definitions at both revisions ==="
for revision in "$old" "$new"; do
  echo "--- $revision: scheduler.rs ---"
  git -C "$tmp/repo" show "$revision:src/memory/queue/scheduler.rs" | sed -n '1,180p'
  echo "--- $revision: tree/runtime/engine.rs ---"
  git -C "$tmp/repo" show "$revision:src/memory/tree/runtime/engine.rs" | sed -n '1,180p'
done

echo "=== Parent call sites ==="
rg -n -C 8 'tinycortex|self_heal|run_summarization_observed' \
  src vendor/tinycortex 2>/dev/null || true

Repository: tinyhumansai/openhuman

Length of output: 50379


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

log="/tmp/coderabbit-shell-logs/shell-output-qMXSEv"

echo "=== Diff section markers ==="
rg -n '^===|^---|^diff --git|^@@' "$log" | head -n 200

echo "=== Relevant caller sections ==="
rg -n -C 12 'self_heal|run_summarization_observed' "$log" | head -n 500

echo "=== TinyCortex changed-file diff excerpts ==="
python3 - "$log" <<'PY'
from pathlib import Path
import sys

text = Path(sys.argv[1]).read_text(errors="replace")
start = text.find("=== TinyCortex diff ===")
end = text.find("=== API definitions at both revisions ===")
if start < 0 or end < 0:
    raise SystemExit("diff markers not found")
section = text[start:end]
lines = section.splitlines()
for i, line in enumerate(lines):
    if line.startswith("diff --git") or line.startswith("@@") or "self_heal" in line or "store_settle" in line:
        lo = max(0, i - 20)
        hi = min(len(lines), i + 80)
        print("\n".join(lines[lo:hi]))
        print("\n--- excerpt boundary ---")
PY

Repository: tinyhumansai/openhuman

Length of output: 47144


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

log="/tmp/coderabbit-shell-logs/shell-output-wgRFSN"

echo "=== Exact changed implementation ==="
sed -n '1,240p' "$log"

echo "=== Parent scheduler and tree callers ==="
sed -n '5280,5320p' "$log"
sed -n '1675,1710p' "$log"

echo "=== New tests and all changed implementation identifiers ==="
rg -n 'requeue_failed_where|requeue_failed|requeue_transient_failed|active|dedup|duplicate|cancel|job_key|payload' "$log" | head -n 300

Repository: tinyhumansai/openhuman

Length of output: 18448


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
old="e0a8738980965411f514f4a62c09f941efdea90c"
new="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$old" "$new"

for revision in "$old" "$new"; do
  echo "=== $revision: store_settle.rs relevant range ==="
  git -C "$tmp/repo" show "$revision:src/memory/queue/store_settle.rs" |
    nl -ba | sed -n '200,390p'
done

echo "=== Raw diff, implementation only ==="
git -C "$tmp/repo" diff --unified=12 "$old" "$new" -- src/memory/queue/store_settle.rs |
  sed -n '1,260p'

echo "=== Queue schema and key definitions at new revision ==="
for path in \
  src/memory/queue/store.rs \
  src/memory/queue/types.rs \
  src/memory/queue/schema.rs \
  src/memory/queue/mod.rs
do
  if git -C "$tmp/repo" cat-file -e "$new:$path" 2>/dev/null; then
    echo "--- $path ---"
    git -C "$tmp/repo" show "$new:$path" |
      rg -n -C 8 'CREATE TABLE|CREATE UNIQUE|job_key|dedup|payload|status|failure_class'
  fi
done

Repository: tinyhumansai/openhuman

Length of output: 282


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
old="e0a8738980965411f514f4a62c09f941efdea90c"
new="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$old" "$new"

for revision in "$old" "$new"; do
  echo "=== $revision: store_settle.rs relevant range ==="
  git -C "$tmp/repo" show "$revision:src/memory/queue/store_settle.rs" |
    sed -n '200,390p'
done

echo "=== Raw diff, implementation only ==="
git -C "$tmp/repo" diff --unified=12 "$old" "$new" -- src/memory/queue/store_settle.rs |
  sed -n '1,260p'

echo "=== Queue schema and key definitions at new revision ==="
for path in \
  src/memory/queue/store.rs \
  src/memory/queue/types.rs \
  src/memory/queue/schema.rs \
  src/memory/queue/mod.rs
do
  if git -C "$tmp/repo" cat-file -e "$new:$path" 2>/dev/null; then
    echo "--- $path ---"
    git -C "$tmp/repo" show "$new:$path" |
      rg -n -C 8 'CREATE TABLE|CREATE UNIQUE|job_key|dedup|payload|status|failure_class'
  fi
done

Repository: tinyhumansai/openhuman

Length of output: 39923


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
revision="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$revision"

echo "=== Dedupe-key implementations ==="
git -C "$tmp/repo" grep -n -E -C 8 'fn dedupe_key|dedupe_key\(' "$revision" -- \
  src/memory/queue/payloads.rs src/memory/queue

echo "=== New settlement tests ==="
git -C "$tmp/repo" show "$revision:src/memory/queue/store_settle_tests.rs" |
  sed -n '150,430p'

echo "=== All uses of cancelled status ==="
git -C "$tmp/repo" grep -n -E -C 5 \"cancelled|JobStatus::Cancelled\" "$revision" -- src

echo "=== Commit identity and changed paths ==="
git -C "$tmp/repo" cat-file -e "${revision}^{commit}"
git -C "$tmp/repo" show --format='%H%n%P%n%s' --no-patch "$revision"
git -C "$tmp/repo" diff-tree --no-commit-id --name-status -r "$revision"

Repository: tinyhumansai/openhuman

Length of output: 47559


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

submodule="vendor/tinycortex"
revision="5fabcf18d9e3907d6b26b59528ad49cebfc1c271"
url="$(git config -f .gitmodules --get "submodule.${submodule}.url")"

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init -q "$tmp/repo"
git -C "$tmp/repo" remote add origin "$url"
git -C "$tmp/repo" fetch --quiet --no-tags origin "$revision"

echo "=== Failed-job status consumers ==="
git -C "$tmp/repo" grep -n -E -C 6 \
  "count_by_status|JobStatus::Failed|status = 'failed'|retry_all_failed|requeue_failed" \
  "$revision" -- src

echo "=== Queue status schema and retired-job handling ==="
git -C "$tmp/repo" grep -n -E -C 10 \
  "idx_mem_tree_jobs_dedupe_active|CREATE TABLE mem_tree_jobs|topic_route|digest_daily|purge_retired_jobs" \
  "$revision" -- src

echo "=== Settlement API documentation ==="
git -C "$tmp/repo" show "$revision:src/memory/queue/store_settle.rs" |
  sed -n '225,370p'

Repository: tinyhumansai/openhuman

Length of output: 50379


Clear failed duplicates when an active row owns the dedupe key.

requeue_failed_where skips the failed row but leaves it in failed when active_keys contains the same key. This allows retry_all_failed to return while stale failures remain counted. Mark the skipped row cancelled and clear its failure fields.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@vendor/tinycortex` at line 1, Update requeue_failed_where so failed rows
whose dedupe key exists in active_keys are marked cancelled and have their
failure fields cleared before being skipped. Ensure retry_all_failed no longer
leaves these stale failures counted, while preserving existing requeue behavior
for other failed rows.

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.