Skip to content

RSI Phase 2 + redesign Phase 1 (JIT context, budget/scheduling, model routing) - #56

Merged
ronshapiro merged 5 commits into
basefrom
worktree-bridge-cse_01EXbnB1D7iWkMuu4FEEXjvC
Aug 12, 2026
Merged

RSI Phase 2 + redesign Phase 1 (JIT context, budget/scheduling, model routing)#56
ronshapiro merged 5 commits into
basefrom
worktree-bridge-cse_01EXbnB1D7iWkMuu4FEEXjvC

Conversation

@ronshapiro

Copy link
Copy Markdown
Owner

Summary

PR #55 was merged with only the plan doc (RSIAgentRedesignPlan.md) before this branch's
implementation commits landed — this PR carries everything else that accumulated on the same
branch afterward:

  • PR RSI Phase 2: agentic Rashi/Tosafot translation task type #54's Phase 2 (still unmerged before this): rashi_tosafot_translation.ts,
    headless_claude.ts's model-pinning/rate-limit/cost-capture work, and
    RSIAgentDesignRetrospective.md — the real-run findings that motivated the redesign plan.
  • Redesign Phase 1, built on top of that:
    • JIT context: context_fetch.ts/context_fetch_cli.ts replace raw Read/Grep/Glob
      access to the full cached page file with a narrow, ref-addressed, size-capped tool;
      page_skeleton.ts gives the prompt a compact page structure instead of the raw 400KB+ JSON;
      worked examples are now inlined in the generation prompt.
    • Dependency tracking: generation records' dependsOn is now auto-populated from what
      context_fetch actually served (extractRequestedRefs), not always [] — this is what lets
      a Tier 3 staleness hit cascade to dependent artifacts.
    • Model routing: model_routing_config.json (read via model_routing.ts) replaces the
      hardcoded model constant.
    • Budget/scheduling: budget_config.json (hand-edited, ships fully disabled) +
      schedule_runner.ts (bounded per-tick runner) + status_cli.ts (call-count/cost visibility)
      — a human-driven schedule rather than a blind cron or a dollar cap that may not mean anything
      under subscription billing.

Not yet implemented: the in-page review UI (Phase 3) and the segmentation-boundary audit task
type (Phase 2) — see RSIAgentRedesignPlan.md for phasing.

Test plan

  • npx jest — all 85 suites / 823 tests pass
  • npx tsc (project's pre-commit check) — clean
  • npx eslint on all changed files — no errors (only pre-existing no-console warnings on
    CLI scripts, matching existing convention)
  • Smoke-tested context_fetch_cli.ts, status_cli.ts, and schedule_runner.ts via ts-node
    against real local state

🤖 Generated with Claude Code

ronshapiro and others added 4 commits August 11, 2026 23:28
Brings in PR #54's work (staleness enum, headless_claude model
pinning/rate-limit handling/tool-use capture, the translation task
type, and the design retrospective from real runs) that was still
unmerged upstream.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces raw Read/Grep/Glob access to the full cached page file with
a narrow context_fetch_cli tool (get-refs/get-neighbors/get-prior-sugyot)
plus a compact page skeleton and worked examples inlined in the prompt.
Auto-populates generation records' dependsOn from what was actually
fetched, instead of always [].

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces the hardcoded MODEL constant with model_routing_config.json,
read via model_routing.ts, so a future routing tuner can propose
changes from logged outcomes instead of a hand-edited constant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds budget_config.json (hand-edited enable/caps/pause per task
type, ships disabled by default), status_cli.ts for call-count/cost
visibility against those caps, and schedule_runner.ts as the bounded
per-tick cron/launchd entrypoint that honors the config. Folds
per-call cost/model logging into context_usage_log.jsonl (added a
`model` field) instead of a separate spend ledger, since the two
would otherwise track nearly identical data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ronshapiro
ronshapiro force-pushed the worktree-bridge-cse_01EXbnB1D7iWkMuu4FEEXjvC branch from 7aaafed to 37ce45d Compare August 11, 2026 20:29
Comment thread rsi_orchestrator/context_fetch.ts Outdated
const baseRef = onIndex === -1 ? ref : ref.slice(onIndex + 4);
let match: Book | undefined;
for (const book of books.allBooks) {
if (baseRef.startsWith(`${book.canonicalName} `)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Use books.parse() instead

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Done — parseRefLocation now calls books.parse() instead of the manual loop (same commit, b7630f0).

Comment thread rsi_orchestrator/context_fetch.ts Outdated
*/
export function parseRefLocation(ref: string): RefLocation | undefined {
const onIndex = ref.lastIndexOf(" on ");
const baseRef = onIndex === -1 ? ref : ref.slice(onIndex + 4);

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

This looks brittle. "On" is not an api contract. Can we use the pages tree structure to deduce the base ref instead?

Otherwise, maybe the mapping should be precomputed somewhere

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Replaced the manual book-name loop + " on " split with a scan over successive token suffixes through books.parse() — no hardcoded string convention, just structural matching against the real book/alias registry. See parseRefLocation in b7630f0.

// Falls back to this only if precomputed/rsi_state/model_routing.json has no entry for this task
// type. The routing tuner (Phase 4 — not built yet) is meant to propose changes to that file from
// logged outcomes; this constant is just the safety-net default, not the source of truth.
const DEFAULT_MODEL_CONFIG = {generateModel: "claude-sonnet-5", critiqueModel: "claude-sonnet-5"};

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Remove this - if no defaults are set an error should be thrown

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Removed DEFAULT_MODEL_CONFIG; getTaskModelConfig now throws if a task type has no entry in model_routing_config.json instead of falling back.

const value = Number(args[index + 1]);
return Number.isFinite(value) ? value : fallback;
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Is there a flags library to handle this?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Switched to yargs (.command() per subcommand), matching rashi_tosafot_translation_cli.ts's pattern, instead of hand-rolled argv parsing.

formatWorkedExamples(workedExamples),
"",
"This page's segments and commentary, for orientation (not full text):",
skeleton ? formatPageSkeleton(skeleton) : "(page not cached)",

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Error if it's not cached

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

generationPrompt now throws if the page isn't cached (or the book is unrecognized) instead of degrading to "(page not cached)" in the prompt text — a candidate can only exist if the page was cached at listing time, so this indicates a real inconsistency, not an expected case.

- parseRefLocation: replace the "on"-string heuristic and manual
  book-prefix loop with books.parse() over successive token suffixes
  — structural, not a hardcoded string convention.
- getTaskModelConfig: throw when a task type has no config entry
  instead of silently falling back to a hardcoded default.
- generationPrompt: throw if the page isn't cached instead of
  degrading to "(page not cached)" in the prompt text.
- context_fetch_cli.ts: use yargs (consistent with the sibling CLI)
  instead of hand-rolled argv parsing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ronshapiro
ronshapiro merged commit 533c9b7 into base Aug 12, 2026
1 check passed
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