Skip to content

fix(SUP-3332): reconcile final secondbrain mirror deltas - #95

Merged
levineam merged 5 commits into
mainfrom
SUP-3332/final-mirror-reconcile
Jul 17, 2026
Merged

fix(SUP-3332): reconcile final secondbrain mirror deltas#95
levineam merged 5 commits into
mainfrom
SUP-3332/final-mirror-reconcile

Conversation

@levineam

@levineam levineam commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Ports the final clawd mirror secondbrain deltas into public jarvOS:
    • SUP-3283 lightweight raw Idea: captures stay journal-only unless durable intent is explicit.
    • SUP-3301/#727 medium-confidence salience is ignored by default instead of writing a Flagged journal section.
    • SUP-3306 journal maintenance now guards mobile journaling conflicts, repairs stale/sync-replayed indexes, preserves existing auto sections on source failures, and keeps known-good/audit backup behavior.
  • Adds a CI Secret scan job so reconcile PRs carry a required diff-scoped secret-pattern check.

Branch Reconcile Notes

  • origin/SUP-2261/reconcile-jarvos-core: superseded by the public-canonical SUP-2261 PR already on main (a6ec23d, PR SUP-2261: reconcile jarvos-coding + jarvos-skills into public (public canonical) #70). Direct branch merge would revert/delete newer public release work, so it is not merged.
  • SUP-2266/jarvos-v050-release: no live local/remote ref found in the clean public checkout. Public main already contains v0.5.0 (f4679d1) and the follow-up v0.5 install-bundle PR (a1dd2a6), so no additional port is needed.

Verification

  • node --test modules/jarvos-secondbrain/tests/capture-dispatcher.test.js modules/jarvos-secondbrain/tests/universal-capture.test.js modules/jarvos-secondbrain/tests/personality-note-journal-contract.test.js modules/jarvos-secondbrain/tests/journal-maintenance.test.js modules/jarvos-secondbrain/tests/skill-contracts.test.js
  • npm test
  • git diff --check
  • Local diff-scoped secret scan: clean

Scope Check

  • Fresh clone/worktree based on origin/main at /Users/andrew/clawd-worktrees/SUP-3332-paperclip.
  • git diff --name-status origin/main..HEAD is limited to .github/workflows/ci.yml and modules/jarvos-secondbrain/**.

Summary by CodeRabbit

  • New Features

    • Journal capture now supports explicit durable-note options, so ideas can be promoted to notes only when intentionally marked.
    • Mobile journaling maintenance now includes improved index repair and clearer single-writer conflict reporting.
  • Bug Fixes

    • Medium-confidence captures are now ignored by default instead of being routed to a review section.
    • Long idea captures stay in the journal unless durable-note intent is explicitly provided.
  • Documentation

    • Updated routing and capture guidance to reflect the new idea handling and review behavior.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@levineam, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aad00049-3bdf-48c6-81ab-4f0341bb59cd

📥 Commits

Reviewing files that changed from the base of the PR and between c23a94f and 71c790a.

⛔ Files ignored due to path filters (1)
  • modules/jarvos/public-docs/export-manifest.tsv is excluded by !**/*.tsv
📒 Files selected for processing (65)
  • .github/workflows/ci.yml
  • modules/jarvos-memory/README.md
  • modules/jarvos-memory/docs/EXPERIENCE_MEMORY_AGENTMEMORY_CONTRACT.md
  • modules/jarvos-memory/docs/MEMORY_PROMOTION_RULES.md
  • modules/jarvos-memory/docs/STACK_MAP.md
  • modules/jarvos-memory/src/lib/memory-promotion.js
  • modules/jarvos-memory/src/lib/memory-schema.js
  • modules/jarvos-memory/test/memory-promotion.test.js
  • modules/jarvos-memory/test/memory-schema.test.js
  • modules/jarvos-ontology/src/intake.js
  • modules/jarvos-ontology/test/intake.test.js
  • modules/jarvos-secondbrain/README.md
  • modules/jarvos-secondbrain/adapters/index.js
  • modules/jarvos-secondbrain/adapters/openclaw/README.md
  • modules/jarvos-secondbrain/adapters/session-source/session-source-adapter.js
  • modules/jarvos-secondbrain/bridge/capture/README.md
  • modules/jarvos-secondbrain/bridge/capture/src/universal-capture.js
  • modules/jarvos-secondbrain/bridge/dispatch/README.md
  • modules/jarvos-secondbrain/bridge/dispatch/src/capture-dispatcher.js
  • modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js
  • modules/jarvos-secondbrain/bridge/routing/README.md
  • modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js
  • modules/jarvos-secondbrain/bridge/skills/README.md
  • modules/jarvos-secondbrain/bridge/skills/contracts/idea-parking.js
  • modules/jarvos-secondbrain/bridge/skills/schemas/skill-contract.schema.json
  • modules/jarvos-secondbrain/bridge/synthesis/src/retrieval-evals.js
  • modules/jarvos-secondbrain/bridge/synthesis/src/secondbrain-status.js
  • modules/jarvos-secondbrain/docs/architecture/automatic-secondbrain-public-boundary.md
  • modules/jarvos-secondbrain/docs/contracts/JARVOS_SECONDBRAIN_PACKAGE_MAP_2026-03-25.md
  • modules/jarvos-secondbrain/docs/contracts/SESSION_SOURCE_ADAPTERS.md
  • modules/jarvos-secondbrain/docs/operations/manual-note-maintenance.md
  • modules/jarvos-secondbrain/package.json
  • modules/jarvos-secondbrain/packages/jarvos-ambient/README.md
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/capture-contract.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/routing/index.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/test/intent-exports.test.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/README.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/config/journal-module.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/section-config.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/README.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/package.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/knowledge-optimizer.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/manual-notes-maintenance.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-wiki/README.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-wiki/package.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-wiki/src/index.js
  • modules/jarvos-secondbrain/tests/capture-dispatcher.test.js
  • modules/jarvos-secondbrain/tests/generated-wiki.test.js
  • modules/jarvos-secondbrain/tests/manual-notes-maintenance.test.js
  • modules/jarvos-secondbrain/tests/personality-note-journal-contract.test.js
  • modules/jarvos-secondbrain/tests/retrieval-evals.test.js
  • modules/jarvos-secondbrain/tests/secondbrain-status.test.js
  • modules/jarvos-secondbrain/tests/session-source-adapters.test.js
  • modules/jarvos-secondbrain/tests/skill-contracts.test.js
  • modules/jarvos-secondbrain/tests/universal-capture.test.js
  • modules/jarvos-starter-kit/README.md
  • modules/jarvos/ARCHITECTURE.md
  • modules/jarvos/CHANGELOG.md
  • modules/jarvos/README.md
  • modules/jarvos/RELEASE_NOTES.md
  • modules/jarvos/docs/INSTALL.md
  • modules/jarvos/docs/local-openclaw-profile.md
  • modules/jarvos/docs/maintenance-hygiene.md
  • modules/jarvos/src/doctor.js
  • modules/jarvos/templates/AGENTS-template.md
📝 Walkthrough

Walkthrough

This PR reverses the medium-confidence "flagged-review" capture routing across capture, dispatch, three-package/ambient routing, and skills contracts, replacing it with an "ignored" outcome and a caller-provided reviewQueue idea-parking flow. It adds durable-note capture flags controlling note promotion, removes the journal Flagged section, adds journal single-writer conflict detection and mobile journaling index repair, and adds a CI secret-scan job.

Changes

Capture routing and idea-parking behavior change

Layer / File(s) Summary
Capture event fields and durable-idea contract validation
bridge/capture/src/universal-capture.js, bridge/dispatch/src/capture-dispatcher.js, bridge/provenance/src/note-journal-contract.js, bridge/capture/README.md, tests/personality-note-journal-contract.test.js, tests/universal-capture.test.js
Capture events now carry createNote/createDurableNote/durable/durableNote/standaloneNote fields; the note-journal contract rejects lightweight idea captures unless durable intent is explicit.
Dispatcher: remove flagged-review skill, add ignored path
bridge/dispatch/src/capture-dispatcher.js, bridge/dispatch/README.md, tests/capture-dispatcher.test.js
The flagged-review skill and formatFlaggedLine helper are removed; a new ignoredPathForCapture returns salience_medium_ignored for unmatched medium-confidence captures.
Three-package and ambient routing cleanup
bridge/routing/src/three-package-router.js, packages/jarvos-ambient/src/routing/index.js, bridge/routing/README.md
FLAGGED_HEADING and flagged-route branches/exports are removed; noteWriteSucceeded is inlined; isSubstantiveIdea and shouldFlagForReview are simplified/stubbed.
Idea-parking contract: reviewQueue requirement and schema updates
bridge/skills/contracts/idea-parking.js, bridge/skills/schemas/skill-contract.schema.json, bridge/skills/README.md, tests/skill-contracts.test.js
The idea-parking contract (v0.3.0) now requires a caller-provided reviewQueue and writes via a review-queue adapter instead of appending to a journal Flagged section; salience_medium_flagged is removed from the schema enum.
Remove Flagged journal section from config/defaults
packages/jarvos-secondbrain-journal/config/journal-module.json, packages/jarvos-secondbrain-journal/src/section-config.js
The flagged required section is removed from journal configuration and default sections.

Journal single-writer guard and mobile journaling index repair

Layer / File(s) Summary
Daily journal writer conflict detection
packages/jarvos-secondbrain-journal/src/journal-maintenance.js, packages/jarvos-secondbrain-journal/README.md, tests/journal-maintenance.test.js
Adds detectDailyJournalWriters scanning Obsidian daily-notes/plugin config for conflicting journal ownership, stored in sync state and surfaced in reports.
Mobile journaling index detection and repair
packages/jarvos-secondbrain-journal/src/journal-maintenance.js, tests/journal-maintenance.test.js
Adds detection of transclusion-heavy mobile indexes and repair via backup plus link-based index rendering.
Section content normalization and shrink-repair refinement
packages/jarvos-secondbrain-journal/src/journal-maintenance.js, tests/journal-maintenance.test.js
Preserves existing material content when fetchers are unavailable, adjusts Paperclip execSync stdio handling, and rewrites resolveJournalDir resolution order.

CI Secret Scan

Layer / File(s) Summary
Secret-scan job and summary integration
.github/workflows/ci.yml
Adds a secret-scan job scanning diffs or repository content for secret patterns, wired into ci-summary's dependency and reporting logic.

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

Possibly related PRs

  • levineam/jarvOS#47: Introduced the original flagged-review routing that this PR reverses across the same capture-dispatcher/routing/journal/contract surfaces.
  • levineam/jarvOS#80: Also modifies journal-maintenance.js's single-writer guard and journal integrity/repair logic.
  • levineam/jarvOS#84: Modifies the same capture/dispatch and note-journal-contract code paths for medium-confidence routing and lightweight-idea validation.

Poem
A flag once waved for ideas half-formed,
Now folded quiet, the journal's calm.
Durable notes need a purposeful flair,
While mobile embeds get trimmed with care.
One writer owns the dated page —
CI now sniffs for secrets on stage. 🐇

🚥 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 is concise and accurately reflects the PR’s main goal of reconciling the remaining secondbrain mirror deltas.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SUP-3332/final-mirror-reconcile

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

❤️ Share

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

@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: c23a94f3e7

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +35 to +38
const {
createMemoryRecord,
checkMemoryDedup,
} = require('../../../../jarvos-memory/src');

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 Restore a valid memory dedup helper

When plan.routeToMemory is true for high-confidence decision/preference/fact/lesson captures, this import leaves checkMemoryDedup undefined because modules/jarvos-memory/src/index.js does not export it. The later call throws TypeError: checkMemoryDedup is not a function after journal/note storage has already been applied, so eligible captures fail instead of producing a memory result.

Useful? React with 👍 / 👎.

Comment on lines +156 to 157
if (keywordResult.note) {
params.noteRef = keywordResult.note.title || keywordResult.note.path || undefined;

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 Avoid referencing notes that failed to write

If the storage adapter returns a failed note object, e.g. { written: false, error: ... }, this truthiness check still copies the note title/path into the memory record. That creates memory noteRefs pointing at notes that were not persisted; the previous noteWriteSucceeded guard avoided this and the same failure case is still handled for journal backlinks above.

Useful? React with 👍 / 👎.

@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: 7a9c597d89

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

frontmatterToObject,
parseFrontmatter,
} = require('./lib/note-schema');
} = require('../../../../scripts/lib/note-schema.js');

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 Restore the local note-schema import

When manual-notes-maintenance is run or even required, this path resolves to modules/scripts/lib/note-schema.js, which is not present in this tree; the parser still lives under this package at src/lib/note-schema.js. That makes the manual-note maintenance CLI fail with MODULE_NOT_FOUND before it can parse args, so --dry-run, --apply, and watch mode are unusable.

Useful? React with 👍 / 👎.

Comment on lines +34 to +36
const { createMemoryRecord } = require('./memory-record');
const { HindsightAdapter } = require('./hindsight-adapter');
const { getHindsightConfig } = require('./memory-config');

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 Point promotion imports at existing files

In this commit modules/jarvos-memory/src/lib contains only memory-promotion.js and memory-schema.js, so requiring this new module throws MODULE_NOT_FOUND on these sibling imports before callers can reach reviewCandidate, promoteCandidate, or the recall helpers. The existing implementations are under the package-level lib/ tree, so the new memory promotion surface is currently unloadable.

Useful? React with 👍 / 👎.

Comment on lines 215 to 218
function resetGeneratedOutput(outputDir) {
assertManagedOutputDir(outputDir);
for (const entry of ['concepts', 'sources', 'daily', 'index.md']) {
fs.rmSync(path.join(outputDir, entry), { recursive: true, force: true });
}

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 Keep the generated-wiki reset guard

When outputDir is accidentally pointed at an existing folder that was not created by this generator, resetGeneratedOutput now unconditionally removes concepts, sources, daily, and index.md. That can delete user-authored content in a misconfigured visible wiki path; the previous managed-marker/nonempty-directory guard prevented this destructive reset.

Useful? React with 👍 / 👎.

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

Actionable comments posted: 7

🧹 Nitpick comments (3)
modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/README.md (1)

13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

LGTM! Consider also documenting the new mobile journaling index detection/repair behavior (plugin disabling, index rewrite, backups) somewhere in this README, since it's a new capability with real side effects not currently mentioned.

Also applies to: 25-28, 41-43

🤖 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 `@modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/README.md` at
line 13, The README currently describes JarvOS as an automated writer but does
not mention the new mobile journaling index detection/repair behavior. Update
the README narrative near the existing product description and any relevant
feature sections to document that the journaling workflow can detect a broken
index, disable the plugin when needed, rewrite the index, and create backups.
Use the existing README content and the journal package description to place
this capability where users will see its side effects.
modules/jarvos-secondbrain/bridge/capture/src/universal-capture.js (1)

102-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Five overlapping durable-note flags.

createNote, createDurableNote, durable, durableNote, and standaloneNote all appear to express the same "promote to a note" intent. Consider consolidating to a single canonical field (with legacy aliases normalized internally) to reduce contract surface and caller confusion.

🤖 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 `@modules/jarvos-secondbrain/bridge/capture/src/universal-capture.js` around
lines 102 - 106, The capture contract in universal-capture.js exposes five
overlapping note-promotion flags, which creates duplicate semantics and caller
confusion. Consolidate the raw.createNote, raw.createDurableNote, raw.durable,
raw.durableNote, and raw.standaloneNote fields into one canonical flag in the
capture normalization logic, and map any legacy aliases to that single internal
field inside the capture flow so existing callers still work.
modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js (1)

48-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Error message omits the forceDurable bypass.

The guard accepts substantive, createDurableNote, or forceDurable as escape hatches, but the thrown message only tells callers to use substantive:true or createDurableNote:true. Minor doc/DX gap for callers who discover forceDurable only by reading source.

🤖 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 `@modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js`
around lines 48 - 55, The guard in note-journal-contract.js throws an error from
the lightweight idea check without mentioning the forceDurable escape hatch,
even though that flag is accepted in the condition. Update the thrown message in
the lightweight idea branch so it clearly lists forceDurable alongside
substantive and createDurableNote, keeping the guidance in sync with the logic
in the same validation block.
🤖 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 @.github/workflows/ci.yml:
- Around line 141-143: The secret-scan pattern in the CI workflow is too broad
and is causing likely false positives in docs. Tighten the regex used by the
fallback scan in the workflow so it targets value-shaped secrets instead of bare
words like token, secret, password, and bearer, and consider limiting the `git
grep` fallback to non-markdown or non-doc paths. Update the scan logic around
the pattern definition and `scan_cmd` setup so legitimate documentation does not
fail the job.
- Around line 126-128: The checkout step in the read-only scan job currently
persists the Actions token in the local git config. Update the actions/checkout
configuration in this job to disable credential persistence by setting
persist-credentials to false, alongside the existing fetch-depth setting, so the
scan can read history without leaving credentials behind.
- Around line 141-146: The secret-scan logic in the CI workflow is inconsistent
between the fallback and diff-based paths, so make both paths use the same
case-insensitive matching and only inspect added content. Update the scan
command selection around the secret pattern in the workflow so the whole-repo
fallback and the diff path behave the same, and adjust the diff-based grep in
the scan command to ignore removed lines and diff headers while keeping the
existing pattern set.

In `@modules/jarvos-secondbrain/bridge/capture/README.md`:
- Around line 49-53: The capture routing docs currently mention only
createDurableNote, but the capture layer also recognizes several durable-note
aliases. Update the README guidance around the idea capture rules to explicitly
list all supported flags in the capture flow, including createNote, durable,
durableNote, standaloneNote, and createDurableNote, so callers know the full
alias set handled by the capture layer.

In `@modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js`:
- Around line 35-44: The `applyThreePackagePlan` flow in
`three-package-router.js` is importing and calling `checkMemoryDedup`, but
`modules/jarvos-memory/src/index.js` does not export it, so the memory capture
path will fail at runtime. Fix this by either exporting `checkMemoryDedup` from
the `jarvos-memory` index to match the existing `createMemoryRecord` import, or
remove the call from `applyThreePackagePlan` and any related dedup logic if it
is no longer needed.

In
`@modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js`:
- Around line 307-315: The fallback in resolveJournalingIndexPath ignores the
computed fileName and always uses JOURNALING_INDEX_FILE, so custom journaling
names are lost when no configured path matches. Update
resolveJournalingIndexPath to use the resolved fileName in both the matchingPath
branch and the fallback branch, keeping the existing path resolution logic in
journal-maintenance.js intact.
- Around line 404-417: The `repairMobileJournalingIndex` guard currently treats
a missing `Journaling.md` as stale content, so `main()` can create the index in
vaults that were never using the Journaling plugin. Update the applicability
check in `repairMobileJournalingIndex` to only repair when the journaling setup
is actually relevant (for example, the plugin is enabled/targets the journal, or
an index already exists), and use that condition together with `before.ok`
before returning the unchanged result.

---

Nitpick comments:
In `@modules/jarvos-secondbrain/bridge/capture/src/universal-capture.js`:
- Around line 102-106: The capture contract in universal-capture.js exposes five
overlapping note-promotion flags, which creates duplicate semantics and caller
confusion. Consolidate the raw.createNote, raw.createDurableNote, raw.durable,
raw.durableNote, and raw.standaloneNote fields into one canonical flag in the
capture normalization logic, and map any legacy aliases to that single internal
field inside the capture flow so existing callers still work.

In `@modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js`:
- Around line 48-55: The guard in note-journal-contract.js throws an error from
the lightweight idea check without mentioning the forceDurable escape hatch,
even though that flag is accepted in the condition. Update the thrown message in
the lightweight idea branch so it clearly lists forceDurable alongside
substantive and createDurableNote, keeping the guidance in sync with the logic
in the same validation block.

In `@modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/README.md`:
- Line 13: The README currently describes JarvOS as an automated writer but does
not mention the new mobile journaling index detection/repair behavior. Update
the README narrative near the existing product description and any relevant
feature sections to document that the journaling workflow can detect a broken
index, disable the plugin when needed, rewrite the index, and create backups.
Use the existing README content and the journal package description to place
this capability where users will see its side effects.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a1fc9d4-1cf8-415a-b44a-d23746e05167

📥 Commits

Reviewing files that changed from the base of the PR and between ee12229 and c23a94f.

📒 Files selected for processing (21)
  • .github/workflows/ci.yml
  • modules/jarvos-secondbrain/bridge/capture/README.md
  • modules/jarvos-secondbrain/bridge/capture/src/universal-capture.js
  • modules/jarvos-secondbrain/bridge/dispatch/README.md
  • modules/jarvos-secondbrain/bridge/dispatch/src/capture-dispatcher.js
  • modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js
  • modules/jarvos-secondbrain/bridge/routing/README.md
  • modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js
  • modules/jarvos-secondbrain/bridge/skills/README.md
  • modules/jarvos-secondbrain/bridge/skills/contracts/idea-parking.js
  • modules/jarvos-secondbrain/bridge/skills/schemas/skill-contract.schema.json
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/routing/index.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/README.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/config/journal-module.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/section-config.js
  • modules/jarvos-secondbrain/tests/capture-dispatcher.test.js
  • modules/jarvos-secondbrain/tests/journal-maintenance.test.js
  • modules/jarvos-secondbrain/tests/personality-note-journal-contract.test.js
  • modules/jarvos-secondbrain/tests/skill-contracts.test.js
  • modules/jarvos-secondbrain/tests/universal-capture.test.js
💤 Files with no reviewable changes (2)
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/section-config.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/config/journal-module.json

Comment thread .github/workflows/ci.yml
Comment on lines +126 to +128
- uses: actions/checkout@v4
with:
fetch-depth: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Set persist-credentials: false for this read-only scan job.

The checkout persists the Actions token in the local git config, but this job only reads history. Disabling persistence reduces credential-exposure surface.

🔒 Proposed change
       - uses: actions/checkout@v4
         with:
           fetch-depth: 0
+          persist-credentials: false
📝 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
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 126-128: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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 @.github/workflows/ci.yml around lines 126 - 128, The checkout step in the
read-only scan job currently persists the Actions token in the local git config.
Update the actions/checkout configuration in this job to disable credential
persistence by setting persist-credentials to false, alongside the existing
fetch-depth setting, so the scan can read history without leaving credentials
behind.

Source: Linters/SAST tools

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment on lines +141 to +146
pattern='(api[_-]?key|secret|token|password|bearer|private[_-]?key|BEGIN (RSA|OPENSSH|EC|DSA|PRIVATE) KEY|ghp_|sk-[A-Za-z0-9]|xox[baprs]-)'
if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
scan_cmd=(git grep -nI -E "$pattern" -- .)
else
scan_cmd=(bash -c "git diff -U0 '$base'...HEAD -- | grep -E -i '$pattern'")
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Two scan paths behave differently and the diff path over-matches.

  • Case sensitivity mismatch: the diff path (Line 145) uses grep -E -i, but the whole-repo fallback (Line 143) uses git grep -E without -i. Since the pattern keywords are lowercase, the fallback silently misses uppercase/mixed-case variants like API_KEY, SECRET, or Bearer.
  • Diff path matches removals and headers: git diff -U0 ... | grep ... scans the whole diff output, so it flags secrets that are being removed (leading - lines) and can match diff header lines (+++/---). Restrict to added content to avoid false positives.
🔧 Proposed fix
-          if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
-            scan_cmd=(git grep -nI -E "$pattern" -- .)
-          else
-            scan_cmd=(bash -c "git diff -U0 '$base'...HEAD -- | grep -E -i '$pattern'")
-          fi
+          if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
+            scan_cmd=(git grep -nI -E -i "$pattern" -- .)
+          else
+            scan_cmd=(bash -c "git diff -U0 '$base'...HEAD -- | grep -E '^\+' | grep -Ev '^\+\+\+' | grep -E -i '$pattern'")
+          fi
📝 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
pattern='(api[_-]?key|secret|token|password|bearer|private[_-]?key|BEGIN (RSA|OPENSSH|EC|DSA|PRIVATE) KEY|ghp_|sk-[A-Za-z0-9]|xox[baprs]-)'
if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
scan_cmd=(git grep -nI -E "$pattern" -- .)
else
scan_cmd=(bash -c "git diff -U0 '$base'...HEAD -- | grep -E -i '$pattern'")
fi
pattern='(api[_-]?key|secret|token|password|bearer|private[_-]?key|BEGIN (RSA|OPENSSH|EC|DSA|PRIVATE) KEY|ghp_|sk-[A-Za-z0-9]|xox[baprs]-)'
if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
scan_cmd=(git grep -nI -E -i "$pattern" -- .)
else
scan_cmd=(bash -c "git diff -U0 '$base'...HEAD -- | grep -E '^\+' | grep -Ev '^\+\+\+' | grep -E -i '$pattern'")
fi
🤖 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 @.github/workflows/ci.yml around lines 141 - 146, The secret-scan logic in
the CI workflow is inconsistent between the fallback and diff-based paths, so
make both paths use the same case-insensitive matching and only inspect added
content. Update the scan command selection around the secret pattern in the
workflow so the whole-repo fallback and the diff path behave the same, and
adjust the diff-based grep in the scan command to ignore removed lines and diff
headers while keeping the existing pattern set.

Comment on lines +49 to +53
- Raw `idea:` / `Idea:` captures append to Journal Ideas only by default, even
when the idea is a long single-line thought.
- Substantive `idea:` captures create a note and link that note from Journal
Ideas.
Ideas only when the capture explicitly sets `substantive:true`, supplies a
title, or sets a durable-note flag such as `createDurableNote:true`.

Copy link
Copy Markdown

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

Document the full durable-note alias set.

The routing contract here only names createDurableNote, but the capture layer also normalizes createNote, durable, durableNote, and standaloneNote. Please list the supported aliases so callers do not assume the others are unsupported.

Suggested wording
- Substantive `idea:` captures create a note and link that note from Journal
- Ideas only when the capture explicitly sets `substantive:true`, supplies a
- title, or sets a durable-note flag such as `createDurableNote:true`.
+ Substantive `idea:` captures create a note and link that note from Journal
+ Ideas only when the capture explicitly sets `substantive:true`, supplies a
+ title, or sets a durable-note flag such as `createNote:true`,
+ `createDurableNote:true`, `durable:true`, `durableNote:true`, or
+ `standaloneNote:true`.
📝 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
- Raw `idea:` / `Idea:` captures append to Journal Ideas only by default, even
when the idea is a long single-line thought.
- Substantive `idea:` captures create a note and link that note from Journal
Ideas.
Ideas only when the capture explicitly sets `substantive:true`, supplies a
title, or sets a durable-note flag such as `createDurableNote:true`.
- Raw `idea:` / `Idea:` captures append to Journal Ideas only by default, even
when the idea is a long single-line thought.
- Substantive `idea:` captures create a note and link that note from Journal
Ideas only when the capture explicitly sets `substantive:true`, supplies a
title, or sets a durable-note flag such as `createNote:true`,
`createDurableNote:true`, `durable:true`, `durableNote:true`, or
`standaloneNote:true`.
🤖 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 `@modules/jarvos-secondbrain/bridge/capture/README.md` around lines 49 - 53,
The capture routing docs currently mention only createDurableNote, but the
capture layer also recognizes several durable-note aliases. Update the README
guidance around the idea capture rules to explicitly list all supported flags in
the capture flow, including createNote, durable, durableNote, standaloneNote,
and createDurableNote, so callers know the full alias set handled by the capture
layer.

Comment on lines +307 to +315
function resolveJournalingIndexPath(journalDir, data) {
const vaultRoot = path.dirname(journalDir);
const fileName = String(data?.fileName || JOURNALING_INDEX_FILE).trim() || JOURNALING_INDEX_FILE;
const configuredPaths = configuredJournalingPaths(data);
const matchingPath = configuredPaths
.map((entry) => resolveConfigPath(entry, vaultRoot))
.find((configuredPath) => configuredPath && isSameOrSubPath(configuredPath, journalDir));
return matchingPath ? path.join(matchingPath, fileName) : path.join(journalDir, JOURNALING_INDEX_FILE);
}

Copy link
Copy Markdown

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

Fallback ignores the resolved fileName.

The computed fileName (which can come from data.fileName) is dropped in the no-match fallback, which always resolves to the hardcoded JOURNALING_INDEX_FILE ("Journaling.md") instead. If a vault configures a custom journaling file name, detection/repair will target the wrong path.

🐛 Proposed fix
-  return matchingPath ? path.join(matchingPath, fileName) : path.join(journalDir, JOURNALING_INDEX_FILE);
+  return matchingPath ? path.join(matchingPath, fileName) : path.join(journalDir, fileName);
📝 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
function resolveJournalingIndexPath(journalDir, data) {
const vaultRoot = path.dirname(journalDir);
const fileName = String(data?.fileName || JOURNALING_INDEX_FILE).trim() || JOURNALING_INDEX_FILE;
const configuredPaths = configuredJournalingPaths(data);
const matchingPath = configuredPaths
.map((entry) => resolveConfigPath(entry, vaultRoot))
.find((configuredPath) => configuredPath && isSameOrSubPath(configuredPath, journalDir));
return matchingPath ? path.join(matchingPath, fileName) : path.join(journalDir, JOURNALING_INDEX_FILE);
}
function resolveJournalingIndexPath(journalDir, data) {
const vaultRoot = path.dirname(journalDir);
const fileName = String(data?.fileName || JOURNALING_INDEX_FILE).trim() || JOURNALING_INDEX_FILE;
const configuredPaths = configuredJournalingPaths(data);
const matchingPath = configuredPaths
.map((entry) => resolveConfigPath(entry, vaultRoot))
.find((configuredPath) => configuredPath && isSameOrSubPath(configuredPath, journalDir));
return matchingPath ? path.join(matchingPath, fileName) : path.join(journalDir, fileName);
}
🤖 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
`@modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js`
around lines 307 - 315, The fallback in resolveJournalingIndexPath ignores the
computed fileName and always uses JOURNALING_INDEX_FILE, so custom journaling
names are lost when no configured path matches. Update
resolveJournalingIndexPath to use the resolved fileName in both the matchingPath
branch and the fallback branch, keeping the existing path resolution logic in
journal-maintenance.js intact.

Comment on lines +404 to +417
function repairMobileJournalingIndex(journalDir, opts = {}) {
const before = detectMobileJournalingIndex(journalDir);
const desiredIndex = renderJournalingLinkIndex(journalDir);
const currentIndex = readTextSafe(before.indexPath) || '';
const indexStale = currentIndex !== desiredIndex;
const pluginConflict = before.conflicts.some((conflict) => conflict.kind === 'obsidian-plugin:journaling');
if (before.ok && !indexStale) {
return {
...before,
changed: false,
backupPaths: [],
repairStatus: 'unchanged',
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file and inspect the functions around the reported lines.
FILE="modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js"

echo "== file outline =="
ast-grep outline "$FILE" --view expanded || true

echo
echo "== relevant slice =="
sed -n '1,260p' "$FILE" | nl -ba | sed -n '1,260p'

echo
echo "== later slice around repairMobileJournalingIndex =="
sed -n '260,520p' "$FILE" | nl -ba | sed -n '260,520p'

Repository: levineam/jarvOS

Length of output: 3991


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all references to the key helpers and the main entry point.
rg -n "repairMobileJournalingIndex|detectMobileJournalingIndex|renderJournalingLinkIndex|main\(" modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src -S

echo
echo "== related tests =="
rg -n "Journaling|mobile journaling|repairMobileJournalingIndex|detectMobileJournalingIndex|renderJournalingLinkIndex" modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal -S

Repository: levineam/jarvOS

Length of output: 4902


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js"

echo "== detect/render/repair slice =="
sed -n '300,460p' "$FILE" | cat -n

echo
echo "== test files mentioning journaling index =="
find modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal -path '*/test*' -o -path '*/tests*' | sort

echo
echo "== test snippets =="
rg -n "Journaling|repairMobileJournalingIndex|detectMobileJournalingIndex|renderJournalingLinkIndex|mobile journaling" modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal -S

Repository: levineam/jarvOS

Length of output: 10459


repairMobileJournalingIndex writes Journaling.md for untouched vaults. (modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js:404-417)

before.ok only means there’s no plugin conflict or embeds, but a missing index still makes indexStale true, so main() will create Journal/Journaling.md on every run even when the Journaling plugin was never enabled. Gate this on actual applicability (plugin enabled/targets journal, or an existing index) instead of a pure content diff.

🤖 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
`@modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/src/journal-maintenance.js`
around lines 404 - 417, The `repairMobileJournalingIndex` guard currently treats
a missing `Journaling.md` as stale content, so `main()` can create the index in
vaults that were never using the Journaling plugin. Update the applicability
check in `repairMobileJournalingIndex` to only repair when the journaling setup
is actually relevant (for example, the plugin is enabled/targets the journal, or
an index already exists), and use that condition together with `before.ok`
before returning the unchanged result.

levineam and others added 4 commits July 16, 2026 21:44
Port the final clawd mirror deltas for secondbrain capture and journal maintenance into the public jarvOS tree. Add a CI secret-scan check for reconcile PRs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@levineam
levineam force-pushed the SUP-3332/final-mirror-reconcile branch from 7a9c597 to 4648e88 Compare July 17, 2026 01:45
@levineam
levineam merged commit 9ddf78f into main Jul 17, 2026
8 checks passed
@levineam
levineam deleted the SUP-3332/final-mirror-reconcile branch July 17, 2026 01:47

@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: 71c790aea1

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const { sourcePathFor } = require('../../../packages/jarvos-secondbrain-notes/src/knowledge-optimizer');
const { getVaultNotesDir, getVaultJournalDir } = require('./lib/provenance-config');
const { frontmatterToObject, parseFrontmatter } = require('../../../packages/jarvos-secondbrain-notes/src/lib/note-schema');
const { frontmatterToObject, parseFrontmatter } = require('../../../../scripts/lib/note-schema');

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 Restore the contract's local note-schema import

When the Obsidian note/journal contract CLI is required or executed, this path resolves to modules/scripts/lib/note-schema, which is not present; the only note-schema.js in the tree is under packages/jarvos-secondbrain-notes/src/lib. This makes scripts/obsidian-note-journal-contract.js fail with MODULE_NOT_FOUND before it can handle any supported personality, so the contract smoke path is unusable.

Useful? React with 👍 / 👎.

Comment on lines 10 to 13
openclaw: 'openclaw',
codex: 'codex',
'claude-code': 'claude-code',
hermes: 'hermes',
};

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 Keep Hermes in the session source allowlist

For Hermes sessions, createHermesSessionAdapter() still calls createSessionSourceAdapter('hermes'), but normalizeSessionToCaptureEvents() rejects any tool not present in this TOOL_SOURCE map and returns unsupported-source-tool. Since the public contract still lists hermes as a supported source, every Hermes transcript now normalizes to zero capture events.

Useful? React with 👍 / 👎.

}

function ensurePortableWorkspaceFiles(workspace) {
const schemaSource = path.resolve(__dirname, '..', '..', 'jarvos.config.schema.json');

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 Copy the schema from the actual repo root

When initProfile() initializes a fresh workspace, __dirname is modules/jarvos/src, so this resolves to modules/jarvos.config.schema.json; that file does not exist, while the schema lives at the repository root. As a result ensurePortableWorkspaceFiles() leaves configSchema as missing-source, and the immediate doctor run reports the newly initialized workspace as missing jarvos.config.schema.json.

Useful? React with 👍 / 👎.

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