Skip to content

SUP-3237 Prepare jarvOS v0.6 secondbrain release candidate - #84

Merged
levineam merged 3 commits into
mainfrom
SUP-3237/secondbrain-v06
Jun 22, 2026
Merged

SUP-3237 Prepare jarvOS v0.6 secondbrain release candidate#84
levineam merged 3 commits into
mainfrom
SUP-3237/secondbrain-v06

Conversation

@levineam

@levineam levineam commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • upstream public-safe jarvos-secondbrain capture, provenance, sidecar, generated wiki, retrieval eval, and manual-note maintenance work
  • add universal capture entrypoint and package-local note/journal contract CLI
  • document manual-note maintenance routine shape and defer Engraph behind a real adapter/eval gate
  • normalize public-facing jarvOS capitalization and update root smoke for v0.6 capture routing

Verification

  • npm test (repo root)
  • npm test (modules/jarvos-secondbrain)
  • git diff --check
  • npm pack --dry-run (modules/jarvos-secondbrain)
  • manual-notes-maintenance temp-vault dry-run/apply smoke
  • privacy/capitalization scan: no JarVOS/JarvOS hits; no Andrew-private absolute paths in modules/jarvos-secondbrain

Notes

  • Engraph is deferred for v0.6 because the binary is not installed locally and the current graph path is an eval harness, not a real Engraph adapter.
  • Paperclip assignment remains tracker-only where a Codex assignee identity is unavailable; no Michael/Charlie handoff.

Summary by CodeRabbit

Release Notes

  • New Features

    • Universal capture entrypoint supporting multiple AI source tools
    • Automated Markdown wiki generation from knowledge artifacts
    • Configurable journal sections and headings with migration support
    • Enhanced session normalization for Claude Code, Codex, and OpenClaw
  • Improvements

    • Centralized configuration resolution with portable path handling
    • Improved journal maintenance with known-good snapshots and repair
    • Refined frontmatter normalization and source material provenance tracking
    • Journal spine synthesis for knowledge exploration
  • Documentation

    • Architecture specifications and package boundaries
    • Skill contracts and adapter interfaces
    • Configuration and deployment guides

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

More reviews will be available in 37 minutes and 42 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

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

🚦 How do rate limits work?

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

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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0fef351b-4c81-432f-9bd9-e1b7fdf5330a

📥 Commits

Reviewing files that changed from the base of the PR and between f7f8ce0 and eee1475.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • modules/jarvos-secondbrain/adapters/ambient-local-storage-adapter.js
  • modules/jarvos-secondbrain/bridge/provenance/src/journal-note-audit.js
  • modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js
  • modules/jarvos-secondbrain/package.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lib/notes-config.js
  • modules/jarvos-secondbrain/tests/ambient-local-storage-adapter.test.js
  • modules/jarvos-secondbrain/tests/journal-note-audit-touched.test.js
  • modules/jarvos-secondbrain/tests/three-package-router-invariant.test.js
  • package.json
📝 Walkthrough

Walkthrough

This PR introduces portable ambient capture contracts and routing, adds session-source and universal capture entrypoints, centralizes config resolution and vault onboarding, expands provenance and journal repair tooling, adds note schema and knowledge-unit outputs, and introduces generated wiki, synthesis, retrieval evaluation, status reporting, and boundary documentation.

Changes

jarvos-secondbrain boundary and runtime stack

Layer / File(s) Summary
Ambient contracts and routing primitives
modules/jarvos-secondbrain/packages/jarvos-ambient/..., modules/jarvos-secondbrain/bridge/skills/..., .../test/*
Adds the side-effect-free ambient package with CaptureEvent validation, intent and salience detection, routing plan builders, adapter result/dispatch helpers, skill contracts and schema, plus package docs and tests.
Capture routing and storage execution
modules/jarvos-secondbrain/bridge/routing/..., modules/jarvos-secondbrain/bridge/dispatch/..., modules/jarvos-secondbrain/adapters/ambient-local-storage-adapter.js, modules/jarvos-secondbrain/tests/*capture*, .../three-package-router-invariant.test.js
Refactors bridge routing to ambient primitives, adds capture dispatch and storage-plan execution, composes an ambient local storage adapter, and updates routing behavior and invariants around note links and flagged entries.
Session adapters, universal capture, and Paperclip bridge
modules/jarvos-secondbrain/adapters/session-source/..., modules/jarvos-secondbrain/adapters/{openclaw,codex,claude-code}/..., modules/jarvos-secondbrain/bridge/capture/..., modules/jarvos-secondbrain/bridge/paperclip/..., modules/jarvos-secondbrain/scripts/jarvos-capture.js
Adds source-session normalization into CaptureEvent v2, new tool-specific adapter factories, a universal capture CLI/runtime, a standalone Paperclip HTTP client, and related exports, docs, and tests.
Config resolution, onboarding, and path shims
modules/jarvos-secondbrain/bridge/config/..., modules/jarvos-secondbrain/tests/config-resolution.test.js, .../jarvos-paths*.test.js
Introduces shared config and Paperclip resolution, shared-vault onboarding, a resolveConfig()-backed path shim, updated package exports, and tests for path precedence, XDG discovery, vault guardrails, and onboarding.
Journal structure and provenance enforcement
modules/jarvos-secondbrain/bridge/provenance/..., modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/..., modules/jarvos-secondbrain/scripts/obsidian-note-journal-contract.js, modules/jarvos-secondbrain/tests/journal-*.test.js, .../personality-note-journal-contract.test.js, .../section-config.test.js
Updates journal maintenance and section configuration, adds fail-closed note↔journal contract tooling, structural journal audits and normalization helpers, wiki-link integrity auditing, and tests for repair, backlinks, and contract verification.
Notes schema, knowledge units, and generated wiki
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/..., modules/jarvos-secondbrain/packages/jarvos-secondbrain-wiki/..., modules/jarvos-secondbrain/tests/{concept-title,knowledge-units,generated-wiki,source-material-provenance-lint}.test.js
Adds canonical note frontmatter parsing/rendering, concept-title generation, source-material linting, note writer and maintenance updates, knowledge-unit sidecars and queue payloads, and a generated Markdown wiki compiler with tests.
Synthesis, retrieval, and status surfaces
modules/jarvos-secondbrain/bridge/synthesis/..., modules/jarvos-secondbrain/tests/{journal-spine-synthesis,retrieval-evals,secondbrain-status,spine-synthesis}.test.js
Adds journal-spine synthesis, retrieval evaluation adapters, secondbrain status reporting, deterministic spine synthesis helpers, package exports, and tests for reports, eval summaries, and fail-closed status output.
Boundary docs, package maps, and top-level exports
modules/jarvos-secondbrain/README.md, modules/jarvos-secondbrain/docs/..., modules/jarvos-secondbrain/package.json, modules/jarvos-secondbrain/src/index.js, tests/modules-smoke-test.js
Rewrites the module README, adds architecture and migration docs describing public/private boundaries and package ownership, expands top-level exports and workspaces, and updates smoke-test expectations for default note-biased routing.

Sequence Diagram(s)

sequenceDiagram
  participant Tool as Session Tool
  participant Adapter as Session Adapter
  participant Capture as Universal Capture
  participant Routing as Ambient Routing
  participant Storage as Vault/Memory/Paperclip Adapters

  Tool->>Adapter: parsed session
  Adapter->>Capture: CaptureEvent v2
  Capture->>Routing: normalized capture + frontmatter
  Routing->>Storage: note/journal/memory/work actions
  Storage-->>Capture: written results
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • levineam/jarvOS#47: Both PRs change the capture-routing stack, including bridge/routing/src/keyword-capture-router.js and flagged/idea/note handling.
  • levineam/jarvOS#80: Both PRs modify packages/jarvos-secondbrain-journal/src/journal-maintenance.js around journal health classification and repair behavior.
  • levineam/jarvOS#41: Both PRs touch provenance and journal-link enforcement, including journal-note-audit.js and Obsidian journal backlink behavior.

Poem

🐇 I hopped through notes and journals bright,
And packed the captures up just right.
With ambient trails and wiki hay,
The secondbrain can hum away.
Soft paws applaud this clever spree.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: preparing jarvOS v0.6 secondbrain for release, which matches the comprehensive updates across capture, provenance, wiki, and package structure documented in the changeset.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SUP-3237/secondbrain-v06

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 and usage tips.

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

ℹ️ 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 {
createVaultStorageAdapter,
} = require('./obsidian/src/vault-storage-adapter.js');
const memoryRecord = 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 Use a packaged dependency for memory records

When @jarvos/secondbrain is installed from its own npm tarball, this relative import escapes the package and looks for ../../jarvos-memory/src; the tarball only contains modules/jarvos-secondbrain, and adapters/index.js eagerly loads this file, so simply requiring the package fails with MODULE_NOT_FOUND. Use a declared package dependency such as @jarvos/memory or lazy-load this only when an injected memory adapter is absent.

Useful? React with 👍 / 👎.

// A note belongs in a given day's journal Notes section if it was CREATED that day
// or UPDATED that day (per the journal-module contract: "created or updated that day").
function noteMatchesDate(note, dateYmd, fmt) {
return fmt(note.createdAt) === dateYmd || note.updated === dateYmd;

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 mtime-updated notes in the audit

For notes edited manually or by external tools that do not maintain updated frontmatter, note.updated is null even though the file mtime is on the audited day, so these notes are no longer returned by findNotesForDate and their journal backlinks are missed. This regresses the existing behavior/test that used mtime to satisfy the “created or updated that day” contract.

Useful? React with 👍 / 👎.


const test = require('node:test');
const assert = require('node:assert/strict');
const Ajv = require('ajv');

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 Declare Ajv for skill-contract tests

In a clean checkout there is no ajv dependency declared for the repo root or modules/jarvos-secondbrain, so npm test in this package fails immediately with Cannot find module 'ajv' before these skill-contract checks run. Add it as a dev dependency or avoid the external validator so the advertised package test command works.

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

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js (1)

157-159: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid attaching noteRef when note persistence failed.

Line 157 currently checks only truthiness, so a failed write result (e.g., written: false) can still produce memory.noteRef to a non-existent note.

Proposed fix
-    if (keywordResult.note) {
+    const noteWritten = Boolean(keywordResult.note)
+      && keywordResult.note.written !== false
+      && keywordResult.note.error == null;
+    if (noteWritten) {
       params.noteRef = keywordResult.note.title || keywordResult.note.path || undefined;
     }
🤖 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/routing/src/three-package-router.js` around
lines 157 - 159, In the condition that checks `keywordResult.note` to assign
`params.noteRef`, add an additional check to verify that the note was
successfully written to persistence (checking the written status). Currently,
the code only verifies that the note object exists, but does not confirm that
the write operation succeeded. Modify the if condition to require both that the
note exists AND that it was successfully persisted before assigning the noteRef
value to params.
🟡 Minor comments (14)
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lib/notes-config.js-25-31 (1)

25-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Treat Source Material as valid only when it is a directory.

On Line 29, existsSync also returns true for regular files. Returning a file path here can break downstream directory reads.

Suggested fix
 function getVaultSourceMaterialDir() {
   const config = loadConfig();
   if (config.paths.sourceMaterial) return config.paths.sourceMaterial;
   const plainSourceMaterial = path.join(config.paths.vault, 'Source Material');
-  if (fs.existsSync(plainSourceMaterial)) return plainSourceMaterial;
+  if (fs.existsSync(plainSourceMaterial) && fs.statSync(plainSourceMaterial).isDirectory()) {
+    return plainSourceMaterial;
+  }
   return path.join(config.paths.vault, '2 - Source Material');
 }
🤖 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-notes/src/lib/notes-config.js`
around lines 25 - 31, In the getVaultSourceMaterialDir function, the check on
line 29 uses fs.existsSync which returns true for both files and directories.
Replace this check with a method that specifically validates that
plainSourceMaterial is a directory, not just any existing path. Use fs.statSync
with isDirectory() method or an equivalent approach, and wrap it in proper error
handling to ensure only actual directories are returned as valid source material
paths.
modules/jarvos-secondbrain/bridge/config/src/shared-vault-onboarding.js-29-35 (1)

29-35: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Require Notes and Journal to be directories, not just existing paths.

On Line 32 and Line 33, existsSync alone will also pass regular files. That can onboard an invalid vault and fail later when code assumes directory semantics.

Suggested fix
 function hasSharedVaultShape(vaultDir) {
+  const notesPath = path.join(vaultDir || '', 'Notes');
+  const journalPath = path.join(vaultDir || '', 'Journal');
   return Boolean(
     vaultDir
-    && fs.existsSync(path.join(vaultDir, 'Notes'))
-    && fs.existsSync(path.join(vaultDir, 'Journal')),
+    && fs.existsSync(notesPath)
+    && fs.existsSync(journalPath)
+    && fs.statSync(notesPath).isDirectory()
+    && fs.statSync(journalPath).isDirectory(),
   );
 }
🤖 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/config/src/shared-vault-onboarding.js`
around lines 29 - 35, The hasSharedVaultShape function uses fs.existsSync to
validate the Notes and Journal paths, but this method returns true for both
files and directories. Replace the fs.existsSync calls for the 'Notes' and
'Journal' paths with checks that specifically verify these are directories, not
just that they exist. Use fs.statSync combined with isDirectory() method on the
returned stats object, or an equivalent method that ensures the paths are actual
directories rather than regular files.
modules/jarvos-secondbrain/bridge/config/src/shared-vault-onboarding.js-104-118 (1)

104-118: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate option values so flags cannot be consumed as argument values.

On Line 104–118, value-taking flags always consume the next token. Inputs like --vault --workspace /tmp/ws set vaultDir to --workspace and desynchronize parsing.

Suggested fix
 function parseArgs(argv) {
   const options = {};
+  function readValue(flag, index) {
+    const value = argv[index + 1];
+    if (!value || value.startsWith('--')) {
+      throw new Error(`Missing value for ${flag}`);
+    }
+    return value;
+  }
   for (let index = 0; index < argv.length; index += 1) {
     const arg = argv[index];
-    const next = argv[index + 1];
     if (arg === '--vault') {
-      options.vaultDir = next;
+      options.vaultDir = readValue(arg, index);
       index += 1;
     } else if (arg === '--workspace') {
-      options.workspaceRoot = next;
+      options.workspaceRoot = readValue(arg, index);
       index += 1;
     } else if (arg === '--config') {
-      options.configPath = next;
+      options.configPath = readValue(arg, index);
       index += 1;
     } else if (arg === '--name') {
-      options.user = { ...(options.user || {}), name: next };
+      options.user = { ...(options.user || {}), name: readValue(arg, index) };
       index += 1;
     } else if (arg === '--timezone') {
-      options.user = { ...(options.user || {}), timezone: next };
+      options.user = { ...(options.user || {}), timezone: readValue(arg, index) };
       index += 1;
🤖 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/config/src/shared-vault-onboarding.js`
around lines 104 - 118, Add validation to prevent flags from being consumed as
argument values in the option parsing logic. In the conditional blocks handling
arg === '--vault', arg === '--workspace', arg === '--config', arg === '--name',
and arg === '--timezone', add a check to verify that next exists and does not
start with '--' before assigning it as the option value and incrementing the
index. This prevents misalignment when flags appear consecutively without proper
values.
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lint-source-material.js-68-72 (1)

68-72: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update help usage to the actual executable path.

Line 71 advertises node scripts/lint-source-material.js, but this file lives under src/. The current help text will direct users to a non-existent path in package-local usage.

🤖 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-notes/src/lint-source-material.js`
around lines 68 - 72, The console.log statement displaying the usage help text
in the linting script incorrectly references the command as `node
scripts/lint-source-material.js` when the file is actually located in the `src/`
directory. Update the Usage line in the console.log help message to show the
correct path to this executable file, which should reflect where the file
actually lives so that users can correctly invoke the script from the command
line.
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/docs/SOURCE_MATERIAL_PROVENANCE_CONTRACT.md-35-37 (1)

35-37: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the lint command path in the contract doc.

Line 36 points to scripts/lint-source-material.js, but this PR adds the CLI at package src/lint-source-material.js (and as jarvos-lint-source-material via bin). This will mislead users running the documented audit command.

Suggested doc patch
- node scripts/lint-source-material.js --json
+ node src/lint-source-material.js --json
+# or, if installed via package bin:
+# jarvos-lint-source-material --json
🤖 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-notes/docs/SOURCE_MATERIAL_PROVENANCE_CONTRACT.md`
around lines 35 - 37, The bash command in the
SOURCE_MATERIAL_PROVENANCE_CONTRACT.md documentation references an incorrect
path for the lint tool. Update the lint command from pointing to
scripts/lint-source-material.js to use the correct CLI reference. Either update
it to reference src/lint-source-material.js from the package location, or better
yet, use the binary command jarvos-lint-source-material which is exposed via the
bin configuration and provides a more user-friendly way to run the audit
command.
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/migrations/note_contract_migration.py-525-525 (1)

525-525: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Apply the same path normalization to JARVOS_ARTIFACTS_DIR.

Line 525 skips .expanduser().resolve() in the env-default branch, unlike the explicit --report-dir path branch. This can produce literal ~ folders or cwd-dependent artifact locations.

Suggested fix
-        report_dir = Path(os.environ.get("JARVOS_ARTIFACTS_DIR", os.path.join(os.path.expanduser("~"), "clawd", "artifacts", "note-contract-migration"))) / utc_stamp()
+        base = Path(
+            os.environ.get(
+                "JARVOS_ARTIFACTS_DIR",
+                os.path.join(os.path.expanduser("~"), "clawd", "artifacts", "note-contract-migration"),
+            )
+        ).expanduser().resolve()
+        report_dir = base / utc_stamp()
🤖 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-notes/migrations/note_contract_migration.py`
at line 525, The report_dir assignment is missing path normalization on the
JARVOS_ARTIFACTS_DIR environment variable default branch. The path constructed
from os.environ.get("JARVOS_ARTIFACTS_DIR", ...) needs to have .expanduser() and
.resolve() applied to it, consistent with how the explicit --report-dir path is
normalized elsewhere in the code. Convert the report_dir Path object to apply
these normalization methods to ensure tilde expansion and absolute path
resolution are consistently handled for both the environment variable branch and
the default fallback path.
modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/migrations/backfill_notes_frontmatter.py-214-214 (1)

214-214: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize --notes-dir defaults before use.

Line 214 now directly consumes JARVOS_VAULT_NOTES; if it contains ~, this script keeps it unexpanded (later Path(args.notes_dir)), which can break discovery. Expand/resolve this path before use.

Suggested fix
-    ap.add_argument("--notes-dir", default=os.environ.get("JARVOS_VAULT_NOTES", os.path.join(os.path.expanduser("~"), "Vaults", "Vault v3", "Notes")))
+    ap.add_argument(
+        "--notes-dir",
+        default=os.path.expanduser(
+            os.environ.get(
+                "JARVOS_VAULT_NOTES",
+                os.path.join(os.path.expanduser("~"), "Vaults", "Vault v3", "Notes"),
+            )
+        ),
+    )
🤖 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-notes/migrations/backfill_notes_frontmatter.py`
at line 214, The `--notes-dir` default value on line 214 may contain an
unexpanded `~` from the `JARVOS_VAULT_NOTES` environment variable, which will
cause path discovery to fail when later used with `Path(args.notes_dir)`. Wrap
the `os.environ.get("JARVOS_VAULT_NOTES", ...)` call with `os.path.expanduser()`
to ensure any tilde characters in the environment variable are properly expanded
to the user's home directory, matching the behavior already applied to the
fallback default path.
modules/jarvos-secondbrain/README.md-102-103 (1)

102-103: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize jarvOS capitalization in the universal-capture section.

jarVOS-owned is inconsistent with the release-wide capitalization normalization.

📝 Suggested doc fix
-Agents should call the jarVOS-owned capture entrypoint instead of raw-writing
+Agents should call the jarvOS-owned capture entrypoint instead of raw-writing
🤖 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/README.md` around lines 102 - 103, The
capitalization of `jarVOS-owned` in the universal-capture section is
inconsistent with the release-wide capitalization normalization standard. Update
the capitalization of `jarVOS-owned` in the sentence beginning with "Agents
should call the jarVOS-owned capture entrypoint" to match the standardized
capitalization used consistently throughout the release documentation.
modules/jarvos-secondbrain/README.md-86-89 (1)

86-89: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Bootstrap-state bullet is outdated for this release.

The statement that bridge/adapter directories contain no logic no longer matches the current code surface and release scope, so the README now misrepresents what ships in v0.6.

📝 Suggested doc fix
-- Bridge and adapter directories are present but intentionally contain no logic yet.
+- Bridge and adapter directories now contain capture/routing and adapter integration logic for the public secondbrain surface.
🤖 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/README.md` around lines 86 - 89, The README.md
statement in the bootstrap-state section that claims "Bridge and adapter
directories are present but intentionally contain no logic yet" is outdated and
no longer reflects the current v0.6 release implementation. Update or remove
this bullet point to accurately represent that bridge and adapter directories
now contain actual logic and implementation in this release, ensuring the
documentation matches what is actually shipped in the code.
modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/capture-contract.js-228-232 (1)

228-232: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Evidence offsets should enforce start <= end.

start and end are each validated independently, but reversed spans are currently accepted.

🛠️ Suggested fix
   for (const field of ['start', 'end']) {
     if (entry[field] != null && (!Number.isInteger(entry[field]) || entry[field] < 0)) {
       errors.push(`${prefix}.${field} must be a non-negative integer`);
     }
   }
+  if (
+    Number.isInteger(entry.start) &&
+    Number.isInteger(entry.end) &&
+    entry.end < entry.start
+  ) {
+    errors.push(`${prefix}.end must be greater than or equal to ${prefix}.start`);
+  }
 }
🤖 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-ambient/src/intent/capture-contract.js`
around lines 228 - 232, The validation loop for the `start` and `end` fields
checks that each field is independently a non-negative integer, but does not
enforce the constraint that start must be less than or equal to end. After the
loop that validates individual fields, add an additional check to ensure that
when both start and end are present and valid, start is not greater than end. If
this condition is violated, push an error message to the errors array indicating
that the start offset must be less than or equal to the end offset.
modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/salience-detector.js-137-143 (1)

137-143: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Manual salience override is not validated against canonical classes.

Any truthy capture.salienceClass replaces classifier output, including unknown values.

🛠️ Suggested fix
 'use strict';
+const { SALIENCE_CLASSES } = require('./capture-contract');
@@
-  if (capture.salienceClass) {
+  if (
+    typeof capture.salienceClass === 'string' &&
+    SALIENCE_CLASSES.includes(capture.salienceClass)
+  ) {
     return {
       ...classification,
       salienceClass: capture.salienceClass,
       keywordOverride: false,
     };
   }
🤖 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-ambient/src/intent/salience-detector.js`
around lines 137 - 143, The code in the salience-detector.js file currently
accepts any truthy value for capture.salienceClass without validating it against
canonical salience classes. To fix this, add a validation check before returning
the overridden classification that verifies capture.salienceClass is a
valid/canonical salience class value. Only return the object with the overridden
salienceClass if the validation passes; otherwise, allow the code to continue to
the next condition or return the original classification based on the classifier
output.
modules/jarvos-secondbrain/bridge/capture/README.md-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix product-name capitalization drift in docs.

Line 3 uses jarVOS-owned; this conflicts with the release normalization target (jarvOS) and can cause public-facing inconsistency.

Suggested fix
-jarVOS-owned universal capture entrypoint for intentional notes and ideas.
+jarvOS-owned universal capture entrypoint for intentional notes and ideas.
🤖 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` at line 3, The product
name in the README.md file has inconsistent capitalization. The text
"jarVOS-owned" in the description uses a different capitalization format than
the normalized standard "jarvOS". Update the product name reference in the
introductory sentence to use the correct capitalization that matches the release
normalization target to ensure consistency across all public-facing
documentation.
modules/jarvos-secondbrain/bridge/routing/README.md-13-14 (1)

13-14: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize product capitalization in this public doc.

Line 13 says jarVOS-owned; this conflicts with the release-wide jarvOS capitalization normalization and should be aligned.

🤖 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/routing/README.md` around lines 13 - 14,
The capitalization of the product name in the README.md file is inconsistent
with the release-wide normalization standard. In the line describing the
CaptureEvent v2 entrypoint that currently reads "jarVOS-owned CaptureEvent v2",
change "jarVOS-owned" to "jarvOS-owned" to align with the standardized "jarvOS"
capitalization convention used across the release.
modules/jarvos-secondbrain/bridge/provenance/src/journal-note-audit.js-5-6 (1)

5-6: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the usage contract aligned with updated-note matching.

Line 5 says the audit detects notes “created” on the date, but Lines 152-155 now include notes whose frontmatter updated: matches. Please update this wording so dry-run output and operator expectations match the actual audit scope.

Proposed wording update
- * Detects notes created today (or on a given date) in the vault Notes/
- * directory and checks whether each is already linked in that day's journal
+ * Detects notes created or updated today (or on a given date) in the vault
+ * Notes/ directory and checks whether each is already linked in that day's journal
🤖 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/journal-note-audit.js`
around lines 5 - 6, The documentation comment at the beginning of the file
describing the audit detection scope is outdated and does not match the current
implementation. The comment at lines 5-6 states the audit detects notes
"created" on the date, but the actual implementation in lines 152-155 includes
notes where the frontmatter "updated:" field matches the date as well. Update
the opening comment to clarify that the audit detects both notes created and
updated on the given date to align the usage contract with the actual audit
behavior and operator expectations.
🧹 Nitpick comments (6)
modules/jarvos-secondbrain/docs/contracts/JARVOS_SECONDBRAIN_PACKAGE_MAP_2026-03-25.md (1)

52-54: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Reduce repetitive sentence structure in the classification rule.

Three successive sentences (lines 52–54) begin with "If", affecting readability. Consider restructuring to vary the pattern.

📝 Suggested rephrase
 ## Rule of interpretation

-If a surface owns human-readable content, it belongs in `jarvos-secondbrain`.
-If it owns compact durable recall, it belongs in `jarvos-memory`.
-If it owns execution state, it belongs in Paperclip.
+- Human-readable content belongs in `jarvos-secondbrain`.
+- Compact durable recall belongs in `jarvos-memory`.
+- Execution state belongs in Paperclip.
🤖 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/docs/contracts/JARVOS_SECONDBRAIN_PACKAGE_MAP_2026-03-25.md`
around lines 52 - 54, The three classification rules in the document (lines
52-54) all begin with "If", creating repetitive sentence structure that impacts
readability. Restructure these three sentences to vary the opening pattern while
preserving the classification logic and clarity. You can vary the structure by
rephrasing some sentences to use different grammatical constructions or
inversions, ensuring each rule about human-readable content, compact durable
recall, and execution state ownership remains clear and distinct.
modules/jarvos-secondbrain/docs/architecture/automatic-secondbrain-public-boundary.md (1)

51-54: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Reduce repetitive sentence structure in the checklist.

Four successive sentences (lines 51–54) begin with "Run", which affects readability. Consider varying the structure while preserving clarity.

📝 Suggested rephrase
 Before public promotion:

-- Run the secondbrain package tests.
-- Run memory and ontology promotion-gate tests.
-- Run release-intake lint.
-- Run privacy/path scans over public docs, fixtures, generated pages, and config
-  templates.
+- The secondbrain package tests should pass.
+- Memory and ontology promotion-gate tests should pass.
+- Release-intake lint should complete without errors.
+- Privacy/path scans over public docs, fixtures, generated pages, and config templates should find no issues.

(Alternately, use a bullet-list structure with imperative verbs: "Verify X", "Confirm Y", "Record Z".)

🤖 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/docs/architecture/automatic-secondbrain-public-boundary.md`
around lines 51 - 54, The four consecutive checklist items starting with "Run"
(secondbrain package tests, memory and ontology promotion-gate tests,
release-intake lint, and privacy/path scans) create repetitive sentence
structure that reduces readability. Vary the imperative verbs used to start each
bullet point by replacing some instances of "Run" with alternative verbs such as
"Verify", "Confirm", "Check", or "Execute" while preserving the clarity of what
actions need to be performed for each item.
modules/jarvos-secondbrain/tests/generated-wiki.test.js (1)

46-81: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a regression case for same-title sources from different note paths.

Current suite misses the collision scenario where two artifacts share a title. Add one test asserting both source pages are preserved with distinct output paths.

🤖 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/tests/generated-wiki.test.js` around lines 46 -
81, Add a new test case in the test file that specifically covers the scenario
where multiple artifacts share the same title but originate from different note
paths. This test should call writeArtifact at least twice with identical titles
but different journalPath values, then invoke compileSecondbrainWiki and verify
that both source pages are generated with distinct output paths to ensure they
are not overwritten or merged. Include assertions to confirm both source page
files exist and contain the expected content from their respective artifacts.
modules/jarvos-secondbrain/tests/secondbrain-status.test.js (1)

19-109: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a regression test for enabled: false adapters in retrieval eval reports.

This file should assert that disabled adapters do not affect retrievalEval.total/status, so the status gate matches adapter enablement semantics.

🤖 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/tests/secondbrain-status.test.js` around lines 19
- 109, Add a new test case after the existing tests to verify that adapters with
enabled set to false do not affect the retrievalEval.total or status
calculations. The test should create a scenario where the eval report contains
both enabled and disabled adapters, then call buildSecondbrainStatus and
renderSecondbrainStatus to assert that only the enabled adapters influence the
overall retrievalEval status outcome, ensuring the status gate properly respects
adapter enablement semantics.
modules/jarvos-secondbrain/packages/jarvos-ambient/test/intent-exports.test.js (1)

244-299: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a regression test for substantive-idea skill dispatch

Please add one test asserting that an IDEA plan with createNote === true also includes a note-creation skill invocation (not only journal behavior). This would catch action/skill divergence in the IDEA path.

Example test shape
+test('substantive idea includes note-creation skill invocation', () => {
+  const plan = routing.buildThreePackagePlan({
+    text: 'Here is an idea: define adapter boundaries so routing stays portable and testable over time.',
+    date: '2026-05-19',
+  });
+
+  assert.equal(plan.route, 'idea');
+  assert.equal(plan.createNote, true);
+  assert.ok(plan.actions.some((action) => action.kind === 'note'));
+  assert.ok(plan.skillInvocations.some((invocation) => invocation.skillId === 'note-creation'));
+});
🤖 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-ambient/test/intent-exports.test.js`
around lines 244 - 299, Add a new test after the existing three tests to verify
the IDEA salienceClass routing behavior. Create a test that calls
routing.buildThreePackagePlan with salienceClass set to 'idea' and include text
and confidence properties. Assert that the resulting plan has createNote equal
to true, that the actions array includes an action with kind 'journal', and that
the skillInvocations array includes an invocation with skillId 'note-creation'.
This test will prevent divergence between the action and skill invocation
behavior for the IDEA routing path.
modules/jarvos-secondbrain/bridge/skills/index.js (1)

10-16: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Harden the registry against external mutation.

Line 28 exports the live contracts array, so downstream code can mutate it and silently break contract lookup behavior in this module instance.

Proposed fix
-const contracts = [
+const contracts = Object.freeze([
   journalEntry,
   noteCreation,
   ideaParking,
   memoryPromotion,
   workIntake,
-];
+]);

 function listSkillContracts() {
   return contracts.slice();
 }

 module.exports = {
   skillContractSchema,
-  contracts,
+  contracts: contracts.slice(),
   listSkillContracts,
   getSkillContract,
   journalEntry,

Also applies to: 26-30

🤖 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/skills/index.js` around lines 10 - 16, The
contracts array is exported directly, allowing downstream code to mutate it and
break contract lookup behavior. Apply Object.freeze() to the contracts array
definition to prevent external mutation while still allowing read access. This
will ensure the array cannot be modified by external code that imports it,
protecting the integrity of the contract registry in this module instance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b70c210-40ea-4d24-a783-c48ea4b643eb

📥 Commits

Reviewing files that changed from the base of the PR and between f4679d1 and f7f8ce0.

📒 Files selected for processing (125)
  • modules/jarvos-secondbrain/README.md
  • modules/jarvos-secondbrain/adapters/ambient-local-storage-adapter.js
  • modules/jarvos-secondbrain/adapters/claude-code/index.js
  • modules/jarvos-secondbrain/adapters/codex/index.js
  • modules/jarvos-secondbrain/adapters/index.js
  • modules/jarvos-secondbrain/adapters/obsidian/src/vault-storage-adapter.js
  • modules/jarvos-secondbrain/adapters/openclaw/README.md
  • modules/jarvos-secondbrain/adapters/openclaw/index.js
  • 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/config/README.md
  • modules/jarvos-secondbrain/bridge/config/index.js
  • modules/jarvos-secondbrain/bridge/config/jarvos-paths.js
  • modules/jarvos-secondbrain/bridge/config/src/paperclip.js
  • modules/jarvos-secondbrain/bridge/config/src/resolve-config.js
  • modules/jarvos-secondbrain/bridge/config/src/shared-vault-onboarding.js
  • modules/jarvos-secondbrain/bridge/dispatch/README.md
  • modules/jarvos-secondbrain/bridge/dispatch/src/capture-dispatcher.js
  • modules/jarvos-secondbrain/bridge/paperclip/README.md
  • modules/jarvos-secondbrain/bridge/paperclip/client.js
  • modules/jarvos-secondbrain/bridge/provenance/README.md
  • modules/jarvos-secondbrain/bridge/provenance/src/journal-note-audit.js
  • modules/jarvos-secondbrain/bridge/provenance/src/lib/provenance-config.js
  • modules/jarvos-secondbrain/bridge/provenance/src/link-to-journal.js
  • modules/jarvos-secondbrain/bridge/provenance/src/note-journal-contract.js
  • modules/jarvos-secondbrain/bridge/provenance/src/notes-section-normalizer.js
  • modules/jarvos-secondbrain/bridge/provenance/src/wiki-link-integrity.js
  • modules/jarvos-secondbrain/bridge/routing/README.md
  • modules/jarvos-secondbrain/bridge/routing/src/capture-contract.js
  • modules/jarvos-secondbrain/bridge/routing/src/capture-that.js
  • modules/jarvos-secondbrain/bridge/routing/src/keyword-capture-router.js
  • modules/jarvos-secondbrain/bridge/routing/src/salience-detector.js
  • modules/jarvos-secondbrain/bridge/routing/src/three-package-router.js
  • modules/jarvos-secondbrain/bridge/routing/test/test-capture-system.js
  • modules/jarvos-secondbrain/bridge/skills/README.md
  • modules/jarvos-secondbrain/bridge/skills/contracts/idea-parking.js
  • modules/jarvos-secondbrain/bridge/skills/contracts/journal-entry.js
  • modules/jarvos-secondbrain/bridge/skills/contracts/memory-promotion.js
  • modules/jarvos-secondbrain/bridge/skills/contracts/note-creation.js
  • modules/jarvos-secondbrain/bridge/skills/contracts/work-intake.js
  • modules/jarvos-secondbrain/bridge/skills/index.js
  • modules/jarvos-secondbrain/bridge/skills/schemas/skill-contract.schema.json
  • modules/jarvos-secondbrain/bridge/synthesis/README.md
  • modules/jarvos-secondbrain/bridge/synthesis/index.js
  • modules/jarvos-secondbrain/bridge/synthesis/src/journal-spine-synthesis.js
  • modules/jarvos-secondbrain/bridge/synthesis/src/retrieval-evals.js
  • modules/jarvos-secondbrain/bridge/synthesis/src/secondbrain-status.js
  • modules/jarvos-secondbrain/bridge/synthesis/src/spine-synthesis.js
  • modules/jarvos-secondbrain/docs/architecture/automatic-secondbrain-public-boundary.md
  • modules/jarvos-secondbrain/docs/architecture/jarvos-secondbrain-monorepo-spec.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/decisions/engraph-retrieval-decision.md
  • modules/jarvos-secondbrain/docs/migration/JARVOS_SECONDBRAIN_MONOREPO_BOOTSTRAP_CHECKLIST_2026-03-25.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/package.json
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/adapters/contract.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/adapters/index.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/adapters/local-storage.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/adapters/skill-dispatch.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/index.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/capture-contract.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/index.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/keyword-capture-router.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/retroactive-capture.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/intent/salience-detector.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/src/routing/index.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/test/adapters.test.js
  • modules/jarvos-secondbrain/packages/jarvos-ambient/test/integration.test.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/docs/JARVOS_SECONDBRAIN_JOURNAL_PACKAGE_DECISION_2026-03-25.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-journal/package.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/packages/jarvos-secondbrain-notes/README.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/docs/JARVOS_SECONDBRAIN_NOTES_PACKAGE_DECISION_2026-03-25.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/docs/SOURCE_MATERIAL_PROVENANCE_CONTRACT.md
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/migrations/backfill_notes_frontmatter.py
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/migrations/note_contract_migration.py
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/package.json
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/concept-title.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/knowledge-optimizer.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lib/note-schema.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lib/notes-config.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lint-frontmatter.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lint-source-material.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/manual-notes-maintenance.js
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/write-to-vault.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/scripts/jarvos-capture.js
  • modules/jarvos-secondbrain/scripts/obsidian-note-journal-contract.js
  • modules/jarvos-secondbrain/src/index.js
  • modules/jarvos-secondbrain/tests/ambient-local-storage-adapter.test.js
  • modules/jarvos-secondbrain/tests/capture-dispatcher.test.js
  • modules/jarvos-secondbrain/tests/concept-title.test.js
  • modules/jarvos-secondbrain/tests/config-resolution.test.js
  • modules/jarvos-secondbrain/tests/generated-wiki.test.js
  • modules/jarvos-secondbrain/tests/infer-title-concept.test.js
  • modules/jarvos-secondbrain/tests/jarvos-paths-shim.test.js
  • modules/jarvos-secondbrain/tests/jarvos-paths.test.js
  • modules/jarvos-secondbrain/tests/journal-maintenance.test.js
  • modules/jarvos-secondbrain/tests/journal-note-audit-touched.test.js
  • modules/jarvos-secondbrain/tests/journal-spine-synthesis.test.js
  • modules/jarvos-secondbrain/tests/keyword-capture-router.test.js
  • modules/jarvos-secondbrain/tests/knowledge-units.test.js
  • modules/jarvos-secondbrain/tests/paperclip-client.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/section-config.test.js
  • modules/jarvos-secondbrain/tests/session-source-adapters.test.js
  • modules/jarvos-secondbrain/tests/skill-contracts.test.js
  • modules/jarvos-secondbrain/tests/source-material-provenance-lint.test.js
  • modules/jarvos-secondbrain/tests/spine-synthesis.test.js
  • modules/jarvos-secondbrain/tests/three-package-router-invariant.test.js
  • modules/jarvos-secondbrain/tests/universal-capture.test.js
  • modules/jarvos-secondbrain/tests/wiki-link-integrity.test.js
  • tests/modules-smoke-test.js
💤 Files with no reviewable changes (1)
  • modules/jarvos-secondbrain/packages/jarvos-secondbrain-notes/src/lint-frontmatter.js

Comment on lines +258 to +262
function validateCaptureEvent(event = {}) {
const errors = [];

if (event.schemaVersion != null && !SUPPORTED_CAPTURE_EVENT_SCHEMA_VERSIONS.includes(String(event.schemaVersion))) {
pushEnumError(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

validateCaptureEvent(null) crashes before validation completes.

The validator dereferences event.schemaVersion without first ensuring event is an object. Passing null throws instead of returning validation errors.

🛠️ Suggested fix
 function validateCaptureEvent(event = {}) {
-  const errors = [];
+  const errors = [];
+  if (!isPlainObject(event)) {
+    return ['CaptureEvent must be an object'];
+  }
 
   if (event.schemaVersion != null && !SUPPORTED_CAPTURE_EVENT_SCHEMA_VERSIONS.includes(String(event.schemaVersion))) {
🤖 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-ambient/src/intent/capture-contract.js`
around lines 258 - 262, The validateCaptureEvent function crashes when null is
explicitly passed because the default parameter event = {} does not override an
explicit null argument. Add a guard check at the beginning of the
validateCaptureEvent function to validate that event is a valid object before
attempting to access event.schemaVersion. If event is null, undefined, or not an
object, push an appropriate validation error to the errors array and continue
validation or return early. This ensures the validator gracefully handles
invalid input and returns validation errors instead of throwing.

@levineam
levineam merged commit 375a992 into main Jun 22, 2026
7 checks passed
@levineam
levineam deleted the SUP-3237/secondbrain-v06 branch June 22, 2026 19:57

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

ℹ️ 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 +53 to +56
return require('@jarvos/memory');
} catch (packageError) {
try {
return 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 Load the persistent memory API for promotions

When high-confidence captures route to memory, this loader resolves to @jarvos/memory's package main or the monorepo jarvos-memory/src fallback; both expose the schema-only createMemoryRecord that returns {written:false,path:null} and do not export checkMemoryDedup, while the durable writer/deduper lives under lib/memory-record.js. As a result decision/preference/lesson captures report a memory route but never create the MEMORY.md/memory/decisions artifacts or skip duplicates.

Useful? React with 👍 / 👎.

...captureEvent,
frontmatter,
};
const routing = applyRoutingPlan(routingInput, { ...options, adapter });

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 Use fail-closed routing for universal capture

For the public jarvos-capture/captureWithJarvos path with an adapter that reports a failed note write (for example {written:false,error:'...'} or an ambient adapter result with ok:false), applyRoutingPlan still appends the planned [[note]] journal line and returns ok: true. The three-package path added a fail-closed guard for this exact invariant, so this entrypoint can still leave dangling journal backlinks whenever the note backend is unavailable or misrouted.

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