Skip to content

Add Codex app startup hydration hook - #31

Merged
levineam merged 3 commits into
mainfrom
feat/codex-app-hydration
May 13, 2026
Merged

Add Codex app startup hydration hook#31
levineam merged 3 commits into
mainfrom
feat/codex-app-hydration

Conversation

@levineam

@levineam levineam commented May 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a bounded startup hydration packet for Codex app sessions
  • expose the packet through a new MCP tool and SessionStart hook
  • update the Codex runtime setup to install and trust the hook safely

Verification

  • npm test in modules/jarvos-agent-context passes: 11/11
  • syntax checks pass for the agent-context module, MCP script, Codex hook scripts, and setup script
  • staged diff check passes

Notes

  • hook failures fail open and log locally instead of blocking Codex startup
  • the hydration packet includes a source/omission/budget report and redacts obvious secrets before injection
  • linked-note hydration rejects journal wikilinks that resolve outside the configured notes directory
  • hook setup preserves existing startup hooks while adding jarvOS

Summary by CodeRabbit

  • New Features

    • Added jarvos_hydrate tool that generates a "jarvOS Working Context Packet" by aggregating current work items, journal entries, linked notes, and ontology context
    • Implemented automatic redaction of secrets and tokens from aggregated content
    • Integrated Codex runtime with session start hooks for automatic context hydration
    • Added configurable character budget (default 12,000) for hydration output
  • Documentation

    • Updated Codex runtime documentation with hydration setup instructions and scope details

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 594589bb-bb63-43b9-8dda-f3b9df8bfa59

📥 Commits

Reviewing files that changed from the base of the PR and between 671b7a6 and c06f9ec.

📒 Files selected for processing (6)
  • modules/jarvos-agent-context/src/index.js
  • modules/jarvos-agent-context/test/agent-context.test.js
  • runtimes/codex/README.md
  • runtimes/codex/jarvos-session-start-hook.js
  • runtimes/codex/setup.sh
  • runtimes/codex/trust-session-start-hook.js
🚧 Files skipped from review as they are similar to previous changes (5)
  • runtimes/codex/README.md
  • runtimes/codex/jarvos-session-start-hook.js
  • modules/jarvos-agent-context/test/agent-context.test.js
  • runtimes/codex/setup.sh
  • runtimes/codex/trust-session-start-hook.js

📝 Walkthrough

Walkthrough

This PR integrates a new hydration workflow into jarvOS that aggregates current work, journal entries, linked notes, and ontology content into a working context packet. The packet is exposed as an MCP tool, CLI command, and Codex session hook, with automatic trust establishment via the Codex app-server.

Changes

jarvOS Hydration and Codex Session Integration

Layer / File(s) Summary
Core Hydration Implementation and MCP Exposure
modules/jarvos-agent-context/src/index.js, modules/jarvos-agent-context/scripts/jarvos-mcp.js
hydrate() builds a working context packet from current work, today's journal, linked wikilink notes, and compacted ontology spine, with configurable size budgets and redaction of obvious secrets. The function is exposed as the jarvos_hydrate MCP tool and as a CLI hydrate command accepting --max-chars.
Issue Filtering by Review Signals and Hydration Statuses
modules/jarvos-agent-context/src/index.js
currentWork() gains configurable status filtering via normalizeStatusList() and omits in_review items lacking concrete review signals (detected by scanning issue fields for URLs, PR tokens, and artifact links via issueHasConcreteReviewSignal()).
Hydration Feature Tests
modules/jarvos-agent-context/test/agent-context.test.js
Tests cover currentWork filtering by hydration statuses and review artifacts, secret pattern redaction, end-to-end hydrate() output composition with maxChars enforcement, and MCP tool integration.
Codex SessionStart Hook Configuration and Execution
runtimes/codex/hooks.json, runtimes/codex/jarvos-session-start-hook.js
Defines a synchronous SessionStart hook that invokes the session-start hook script. The script calls hydrate(), formats output as a Codex hook payload with additionalContext, and logs failures to ~/.codex/jarvos-hydration.log without blocking startup (fail-open).
Codex Hook Validation, Registration, and TOML Configuration
runtimes/codex/setup.sh
Validates required hook files upfront, registers the jarvOS MCP server, ensures Codex config directory/file exist, then updates the TOML to inject the SessionStart hook command, enable hooks feature, and remove legacy codex_hooks, with timestamped config backup on changes.
Codex App-Server Hook Trust Protocol
runtimes/codex/trust-session-start-hook.js
Spawns the Codex app-server, negotiates trust via newline-delimited JSON RPC: initializes protocol, discovers the jarvos SessionStart hook, checks trust status, and conditionally upserts hooks.state with trusted_hash via config/batchWrite before confirming trust. Includes 30-second watchdog and controlled shutdown.
README Documentation for Hydration and Hook Setup
runtimes/codex/README.md
Describes the jarvOS adapter as supporting both CLI and app sessions, details SessionStart hook setup and trust persistence, expands hydration scope with packet budget and contents (ontology spine, hydration report markers), and documents hook failure logging behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • levineam/jarvOS#30: Introduced the foundational @jarvos/agent-context MCP server and Codex adapter that this PR extends with the jarvos_hydrate tool and SessionStart hook integration.

Poem

🐰 I gathered notes and trimmed them tight,

Secrets tucked safely, kept out of sight,
Journals and issues, a compacted spine,
Hooks wake a session with context in line,
A rabbit applauds this hydration delight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 accurately summarizes the main change: adding a Codex app startup hydration hook as a new feature for bounded context injection.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/codex-app-hydration

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: 671b7a6df5

ℹ️ 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 +305 to +307
const normalized = title.replace(/[\\/]/g, path.sep);
const direct = path.join(notesDir, `${normalized}.md`);
if (fs.existsSync(direct)) return direct;

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 Prevent wikilinks from escaping the notes directory

When today's journal contains a wikilink with .. path components, this direct path is normalized by path.join and can resolve outside notesDir before readIfExists injects the file into the startup hydration packet. For example, [[../../private/session-notes]] would read a sibling markdown file if it exists, bypassing the intended “notes linked from today” scope and potentially exposing unrelated local content to Codex startup context; reject traversal or verify the resolved path remains under notesDir before reading it.

Useful? React with 👍 / 👎.

@levineam levineam changed the title Add Codex app startup hydration hook SUP-1558: Add Codex app startup hydration hook May 13, 2026
@levineam levineam changed the title SUP-1558: Add Codex app startup hydration hook Add Codex app startup hydration hook May 13, 2026

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

🧹 Nitpick comments (1)
runtimes/codex/README.md (1)

46-46: ⚡ Quick win

Make the budget value more precise.

The phrase "about 12,000 characters" is imprecise for a technical specification. If this is a configurable value, state that it's the default. If it's a hard-coded constant, provide the exact value.

📝 Suggested precision improvement
-Default budget is about 12,000 characters. The packet includes:
+Default budget is 12,000 characters (configurable via JARVOS_MAX_HYDRATION_CHARS). The packet includes:

or if it's a hard-coded value:

-Default budget is about 12,000 characters. The packet includes:
+The packet is capped at 12,000 characters and includes:
🤖 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 `@runtimes/codex/README.md` at line 46, Replace the imprecise phrase "Default
budget is about 12,000 characters" in the README with an exact value and clarify
whether it is a default or a hard-coded constant: update the sentence that
currently reads "Default budget is about 12,000 characters" to either "Default
budget: X characters (configurable via <config_key>)" if it's configurable, or
"Budget: X characters (hard-coded constant)" if not, and ensure the exact
numeric value X matches the implementation where the budget is defined; edit the
README line containing "Default budget is about 12,000 characters. The packet
includes:" accordingly.
🤖 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 `@modules/jarvos-agent-context/src/index.js`:
- Around line 474-487: The current two-stage truncation can still exceed
maxChars if the hydration report itself is too large; add a final safety check
after computing markdown (and after replacing the "Final size" text) that
ensures markdown.length <= maxChars by trimming the body portion (or falling
back to truncating markdown) and pushing an omission like `final packet forcibly
trimmed from X to maxChars chars` into report.omissions; update
report.finalChars to the new length and re-run the `Final size:` replacement so
the final markdown returned by the logic (which uses variables body, maxChars,
renderHydrationReport, report, and markdown) is guaranteed to be <= maxChars.

In `@runtimes/codex/jarvos-session-start-hook.js`:
- Line 31: The environment variable JARVOS_HYDRATION_MAX_CHARS is being passed
through Number(...) directly into hydrate(), which can produce NaN or
non-positive values and silently change behavior; before calling hydrate({
maxChars: ... }) validate and normalize the env: read
process.env.JARVOS_HYDRATION_MAX_CHARS, parse as an integer (e.g., parseInt),
ensure it's a finite positive integer, clamp or reject out-of-range values, and
if invalid fall back to DEFAULT_MAX_CHARS; then call hydrate({ maxChars:
validatedMaxChars }) so hydrate() always receives a safe positive integer.

In `@runtimes/codex/README.md`:
- Line 48: Update the README.md sentence that currently says Paperclip issues
are filtered by `in_progress` and `in_review` to accurately list the statuses
used by the currentWork() filter: `in_progress`, `todo`, and `blocked` (these
are defined by DEFAULT_CURRENT_WORK_STATUSES and used by currentWork()); remove
`in_review` from that description and, if needed, add a short note that
`in_review` is used for hydration filtering rather than current work.

In `@runtimes/codex/setup.sh`:
- Around line 121-134: The current logic removes all SessionStart entries and
inserts only sessionStartLine; change it to upsert only the jarvOS SessionStart
while preserving other user SessionStart hooks: locate the [hooks] block using
the existing start/end detection (variables start, end and array filtered), scan
filtered between start+1 and end for lines matching /^\s*SessionStart\s*=/, if a
SessionStart line already contains the jarvOS command (check for a unique token
from sessionStartLine) replace that line with sessionStartLine; if no jarvOS
SessionStart exists, insert sessionStartLine at the end of the hooks block
(before end) without removing other SessionStart lines. Use the existing
variables filtered, start, end, and sessionStartLine to implement this upsert
behavior.

In `@runtimes/codex/trust-session-start-hook.js`:
- Around line 121-125: The final trust-status check currently treats only
'trusted' as success but earlier logic accepts 'managed' as trusted-enough;
update the condition that calls finish to treat both 'trusted' and 'managed' as
successful by changing the check on hook.trustStatus in the
trust-session-start-hook.js end block (the branch that calls finish) to consider
hook.trustStatus === 'trusted' || hook.trustStatus === 'managed' and call
finish(0) in that case, otherwise call finish(1, hook.trustStatus).

---

Nitpick comments:
In `@runtimes/codex/README.md`:
- Line 46: Replace the imprecise phrase "Default budget is about 12,000
characters" in the README with an exact value and clarify whether it is a
default or a hard-coded constant: update the sentence that currently reads
"Default budget is about 12,000 characters" to either "Default budget: X
characters (configurable via <config_key>)" if it's configurable, or "Budget: X
characters (hard-coded constant)" if not, and ensure the exact numeric value X
matches the implementation where the budget is defined; edit the README line
containing "Default budget is about 12,000 characters. The packet includes:"
accordingly.
🪄 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: 1b3e4fb2-0806-4ad4-865d-5120c915f65d

📥 Commits

Reviewing files that changed from the base of the PR and between d6cb62f and 671b7a6.

📒 Files selected for processing (8)
  • modules/jarvos-agent-context/scripts/jarvos-mcp.js
  • modules/jarvos-agent-context/src/index.js
  • modules/jarvos-agent-context/test/agent-context.test.js
  • runtimes/codex/README.md
  • runtimes/codex/hooks.json
  • runtimes/codex/jarvos-session-start-hook.js
  • runtimes/codex/setup.sh
  • runtimes/codex/trust-session-start-hook.js

Comment thread modules/jarvos-agent-context/src/index.js Outdated
Comment thread runtimes/codex/jarvos-session-start-hook.js Outdated
Comment thread runtimes/codex/README.md
Comment thread runtimes/codex/setup.sh Outdated
Comment thread runtimes/codex/trust-session-start-hook.js Outdated

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

ℹ️ 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 +492 to +493
report.finalChars = markdown.length;
markdown = markdown.replace(/Final size: \d+ chars/, `Final size: ${report.finalChars} chars`);

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 Update finalChars after rewriting the report

Running npm test in modules/jarvos-agent-context fails on the new budget test because report.finalChars is assigned before the Final size: 0 chars placeholder is replaced. When the replacement increases the string length, the returned metadata stays stale (for example, 604 while result.markdown.length is 606), so the hydration report and consumers relying on report.finalChars get an incorrect size.

Useful? React with 👍 / 👎.

@levineam
levineam merged commit 89a99a6 into main May 13, 2026
6 checks passed
@levineam
levineam deleted the feat/codex-app-hydration branch May 13, 2026 10:52
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