Skip to content

Add programmatic memory harness - #61

Merged
yourconscience merged 6 commits into
masterfrom
feature/programmatic-memory
Aug 18, 2026
Merged

Add programmatic memory harness#61
yourconscience merged 6 commits into
masterfrom
feature/programmatic-memory

Conversation

@yourconscience

@yourconscience yourconscience commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • add an append-only full-fidelity trajectory with bounded deterministic history reads and searches
  • add the experimental programmatic_memory harness, prompt, registry wiring, and pilot benchmark matrix
  • document the unbenchmarked experimental contract and add unit, persistence, and deterministic quest coverage

Verification

  • uv run pytest llm_quest_benchmark/tests/harnesses/test_trajectory.py llm_quest_benchmark/tests/harnesses/test_harnesses.py llm_quest_benchmark/tests/harnesses/test_factory.py llm_quest_benchmark/tests/integration/test_mode_agents_e2e.py llm_quest_benchmark/tests/test_database.py (96 passed, 3 skipped)
  • broader builder sweep: 147 passed, 3 skipped
  • uv run ruff format ... (7 files unchanged)
  • uv run ruff check ... (pass)
  • deterministic Boat.qm fake-provider smoke: 18 steps, persisted history_search, terminal FAILURE without runtime error

The live-provider pilot is intentionally not run in this PR.

Summary by Sourcery

Introduce an experimental programmatic-memory harness with deterministic trajectory retrieval, bounded quest execution, and end-to-end benchmark integration.

New Features:

  • Add the experimental programmatic_memory harness with deterministic full-trajectory history reads and searches, calculator and scratchpad tools, prompt wiring, and benchmark registration.

Bug Fixes:

  • Prevent non-terminating quests from running indefinitely by supporting an optional validated maximum step limit and recording capped runs as failures.
  • Ensure each executed decision produces one canonical agent state shared by the harness, callbacks, and persisted logger output.
  • Keep benchmark summaries and reports separate when the same model is evaluated with different harnesses.

Enhancements:

  • Add an append-only in-memory trajectory that preserves canonical executed states while enforcing bounded, deterministic retrieval output.
  • Extend benchmark configuration and execution paths to propagate per-quest maximum step limits while preserving unbounded behavior by default.

Documentation:

  • Document the experimental harness contract, architecture, evaluation design, limitations, and intentionally unbenchmarked pilot.

Tests:

  • Add unit, lifecycle, runner, persistence, configuration, integration, and benchmark-report coverage for trajectory retrieval, harness behavior, step caps, canonical state delivery, and harness-aware grouping.

@sourcery-ai

sourcery-ai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces an experimental programmatic_memory harness backed by a new append-only in-memory trajectory with bounded deterministic history read/search tools, wires it into the harness registry and benchmark configs, and adds focused tests and documentation for its contract and persistence behavior.

Sequence diagram for programmatic_memory decision and bounded retrieval

sequenceDiagram
    actor QP as QuestPlayer
    participant PMH as ProgrammaticMemoryHarness
    participant TCH as ToolCompactHarness
    participant M as Model
    participant TRAJ as Trajectory

    QP->>PMH: get_action(observation, choices)
    PMH->>TCH: get_action(observation, choices)
    TCH->>M: tool-select prompt (DefaultMemory)
    M-->>TCH: JSON response
    TCH->>PMH: parsed LLMResponse

    PMH->>PMH: _extract_tool_calls(response)
    PMH->>PMH: _execute_tool_calls(tool_calls[:1])
    alt history_read
        PMH->>PMH: history_read(start_step, count)
        PMH->>TRAJ: read(start_step, count)
        TRAJ-->>PMH: bounded range text
    else history_search
        PMH->>PMH: history_search(query, limit)
        PMH->>TRAJ: search(query, limit)
        TRAJ-->>PMH: bounded search text
    else calculator/scratchpad
        PMH->>PMH: calculator()/scratchpad()
    end

    PMH-->>TCH: tool_results
    TCH->>M: final action prompt
    M-->>TCH: final JSON with result
    TCH-->>PMH: selected action

    PMH->>TRAJ: append(observation, choices, selected_action, selected_choice)
    PMH-->>QP: action index
Loading

File-Level Changes

Change Details Files
Add append-only Trajectory component with bounded deterministic read/search APIs and strict output/parameter contracts.
  • Implemented immutable TrajectoryStep dataclass and Trajectory class storing full-fidelity observations, choices, and selected actions per step.
  • Implemented bounded history_read and history_search methods with MAX_READ_COUNT, MAX_SEARCH_RESULTS, and MAX_OUTPUT_CHARS limits, including deterministic ranking and explicit error messages for invalid inputs.
  • Ensured read/search formatting never mutates stored entries, enforces hard output length bounds, and uses explicit truncation/omission markers instead of silent slicing.
llm_quest_benchmark/harnesses/trajectory.py
llm_quest_benchmark/tests/harnesses/test_trajectory.py
Introduce ProgrammaticMemoryHarness that reuses the tool-select-then-act loop but replaces compaction memory and quest_history with full-fidelity trajectory tools.
  • Subclassed ToolCompactHarness as ProgrammaticMemoryHarness, but bypassed its initializer/reset to inject DefaultMemory, Trajectory, calculator, and scratchpad tools via BaseHarness.
  • Overrode get_action to append exactly one trajectory step per call, covering normal, retry, safety-override, error-default, and skip_single paths without changing shared control flow.
  • Defined prompt-level tool descriptions, recent-context behavior (no additional trajectory recent block), tool-call extraction/normalization, execution for history_read/history_search/calculator/scratchpad, and disabled the legacy step log via a no-op _log_step and custom reset.
llm_quest_benchmark/harnesses/tool_harness.py
llm_quest_benchmark/prompt_templates/programmatic_memory.jinja
llm_quest_benchmark/tests/harnesses/test_harnesses.py
Wire programmatic_memory harness into factory, benchmark executor, and add a pilot benchmark matrix and deterministic integration smoke test.
  • Registered ProgrammaticMemoryHarness in HARNESS_REGISTRY and harness_templates so it can be instantiated via create_harness and used in benchmark runs.
  • Extended integration tests with a FakeLLM mode that triggers history_search during a Boat.qm run and verifies tool_calls/tool_results persistence into run_summary.json.
  • Added a programmatic_memory_pilot benchmark YAML that compares reasoning_recent, reasoning_full, memo_compact, tool_compact, and programmatic_memory on a shared quest set under fixed model/temperature/timeouts.
llm_quest_benchmark/harnesses/factory.py
llm_quest_benchmark/executors/benchmark.py
llm_quest_benchmark/tests/integration/test_mode_agents_e2e.py
configs/benchmarks/programmatic_memory_pilot.yaml
Document the programmatic_memory design, contracts, and experimental status in architecture and spec docs.
  • Updated ARCHITECTURE.md to describe the Trajectory component, the new programmatic_memory.jinja template, and how programmatic_memory differs from tool_compact in memory and retrieval behavior.
  • Extended SPEC.md with an Experimental Harnesses section explaining programmatic_memory’s goals, retrieval tools, and benchmark expectations.
  • Added PROGRAMMATIC_MEMORY_PROPOSAL.md detailing the motivation, design, invariants, verification plan, and current implementation status of programmatic_memory and the trajectory subsystem.
docs/ARCHITECTURE.md
docs/SPEC.md
docs/PROGRAMMATIC_MEMORY_PROPOSAL.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0c79e6ed-c35c-42a5-affc-463713283201


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.

@sourcery-ai sourcery-ai 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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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

ℹ️ 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 thread configs/benchmarks/programmatic_memory_pilot.yaml Outdated
Comment thread configs/benchmarks/programmatic_memory_pilot.yaml

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

ℹ️ 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 thread configs/benchmarks/programmatic_memory_pilot.yaml

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

ℹ️ 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 thread llm_quest_benchmark/harnesses/trajectory.py 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: 17c37725c5

ℹ️ 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 271 to +273
grouped: dict[str, list[RunInsight]] = defaultdict(list)
for insight in insights:
grouped[insight.model].append(insight)
grouped[_group_label(insight.model, insight.harness, harnesses_by_model)].append(insight)

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 Report results per quest and harness

When the new three-quest pilot is run, this grouping assigns every run solely to its model/harness row, and calculate_summary_stats() does the same, so neither standard report exposes per-quest success rates. This directly prevents the required per-quest analysis in docs/PROGRAMMATIC_MEMORY_PROPOSAL.md:224; an aggregate improvement driven only by an easy quest will appear as a harness-wide gain. Add a quest-by-harness breakdown (or nest quest statistics beneath each harness) before interpreting the pilot.

Useful? React with 👍 / 👎.

@yourconscience
yourconscience merged commit ee4c448 into master Aug 18, 2026
4 checks 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