Skip to content

Allow memory (comment-memory / cache-memory / repo-memory) to be consumed by a deterministic job that runs before the agent, for work-planning #43924

Description

@jeffhandley

Feature request — expose persisted memory to deterministic steps:/jobs: (and ideally a pre-agent job) so the "what work is there to do?" decision can be computed without an LLM turn.

Summary

Today all three memory stores — cache-memory, repo-memory, and comment-memory — are agent-facing tools: they're restored/downloaded into the agent job and consumed by the AI via the prompt. There is no supported way for deterministic code (a frontmatter steps: block, a custom jobs:, or an on.steps: pre-activation filter) to read the current memory state.

That's a real gap for any workflow where memory determines the work list. The natural design is: a cheap, deterministic step reads prior state ("what have I already processed?"), diffs it against reality, and produces the units of work — then the agent (or dispatched workers) execute. Because memory is agent-only, you're forced into one of two bad options:

  1. Spend an LLM turn just to read memory and decide — nondeterministic, token cost, and slower, for what is pure set arithmetic.
  2. Abandon the memory abstraction and hand-roll a parallel state store with cache: / actions/cache, duplicating the very thing cache-memory already provides (and losing its key scheme, branch-scoping, 7-day retention, comment round-trip, and the DIFC integrity model).

In practice option 2 is currently mandatory: even a frontmatter steps: block can't see cache-memory, because the cache-memory restore step is injected into the agent job after the user's steps: run — so a pre-agent steps: block reads empty state. I hit exactly this building an orchestrator/worker pair and had to add my own actions/cache beside the agent's memory.

Concrete scenario (OrchestratorOps + memory)

A scheduled orchestrator polls open PRs every 10 minutes and dispatches a worker per PR that is new or has new commits. The dedup key is "last-reviewed head SHA per PR" — ideal memory state. The ideal shape:

on:
  schedule: [{ cron: "*/10 * * * *" }]
tools:
  cache-memory:            # holds { "<pr>": "<last-reviewed-sha>" }
    key: code-review-state
safe-outputs:
  dispatch-workflow:
    workflows: [code-review-worker]
steps:
  # DeterministicOps: read memory, compute the dispatch list — NO agent needed
  - run: |
      gh pr list --json number,headRefOid > prs.json
      jq ... (diff current SHAs against cache-memory state) > /tmp/gh-aw/agent/dispatch_list.json

Here the entire "decide what to dispatch" step is deterministic and cheap — if the step could read cache-memory. Today it can't, so the orchestrator must either burn an agent turn to read memory or keep a second cache.

Overlap with the documented patterns

This sits squarely in the seam between four existing patterns that almost compose but don't:

  • OrchestratorOps — "The orchestrator decides what to do and in what order." That decision is very often a function of memory (already-processed set, checkpoints). The pattern implicitly assumes the agent decides; there's no deterministic path from memory → dispatch list.
  • DispatchOps / dispatch-workflow — fan-out is already deterministic-friendly (a precomputed list of inputs), but the input to the fan-out (the work list) can't be derived from memory without the agent.
  • DeterministicOps — explicitly promotes "reliably collect and prepare data, then the AI agent reads the results," and even documents a Data Caching section and Deterministic Trigger Filtering (on.steps:). But its caching uses the separate low-level cache: frontmatter — not the memory abstraction. So the prep phase is blind to everything the workflow has stored in cache-memory/comment-memory.
  • MemoryOps — Pattern 1 (Exhaustive Processing) and Pattern 2 (State Persistence) keep todo/done/checkpoint state precisely so a run can "resume" and "mark each item done." Deciding which items remain from that state is textbook deterministic work — yet only the agent can read the state that drives it.

In short: DeterministicOps says "precompute deterministically, then let the agent reason," and MemoryOps says "persist state across runs," but you can't do both at once — precompute deterministically from persisted memory.

Proposed capability

Any one of these would close the gap (roughly increasing order of scope):

  1. Restore memory before frontmatter steps:. Guarantee cache-memory/comment-memory/repo-memory are materialized at their documented paths (/tmp/gh-aw/cache-memory/, /tmp/gh-aw/comment-memory/, /tmp/gh-aw/repo-memory/) before the user's steps: run, so deterministic code in the agent job can read them. (Fixes the ordering; smallest change.)
  2. Expose memory to on.steps: (pre-activation) so a deterministic filter can decide whether to run — and what to run — from memory.
  3. A first-class "memory read" in a custom jobs: (e.g., a generated restore-memory job other jobs can needs:), so an orchestrator's compute-and-dispatch can be an ordinary deterministic job rather than an agent.

A read-only surface is enough for the work-planning use case; writes can remain agent/safe-output-mediated to preserve the integrity model.

Why it matters

  • Removes an unnecessary LLM turn (cost, latency, nondeterminism) from the most mechanical part of OrchestratorOps.
  • Stops pushing authors off the memory abstraction onto hand-rolled actions/cache, which fragments state and forfeits branch-scoping/retention/integrity guarantees.
  • Makes OrchestratorOps + MemoryOps + DeterministicOps genuinely composable — a cheap deterministic planner over durable memory, with the agent reserved for the actual reasoning/work.

Related

Note

This issue was drafted with the help of GitHub Copilot.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions