Skip to content

julien-m/session-brief

v0.1.0MIT

Incremental Luna session briefs for Codex with the exact initial request and a local evidence journal.

Session Brief

A durable, incremental session brief for Codex, rewritten by GPT-6 Luna after each main-thread stop. Keep the original request, what changed, decisions, constraints, verified work, failures, and what remains to do close at hand.

Session Brief follows the update principle of recap-plus, originally named session-brief: previous summary + original request + new turn → updated summary. It is an independent implementation for Codex, not a Claude plugin or a UI mod.

Requirements

  • macOS or Linux; Python 3.11+, with no third-party Python dependencies.
  • A Codex client with command lifecycle hooks, asynchronous hooks, and plugin support. Packaging was checked with Codex CLI 0.160.1. Other client versions must be checked separately; this is not a promise about every Desktop build.
  • codex available on the hook process's PATH, signed in with an account that can use gpt-6-luna. The summarizer uses that existing Codex login.
  • Hooks enabled and the plugin's hook definitions reviewed and trusted by you. Installing a plugin does not automatically trust its hooks.

Install

Add this repository as a marketplace, then install the plugin:

codex plugin marketplace add julien-m/session-brief
codex plugin add session-brief@session-brief

Open /hooks in the Codex CLI, review the Session Brief commands, and trust them. Open or resume a session using a client that loads these hooks. Trust is tied to the hook definitions; updates can require another review. Do not bypass hook trust.

For a local checkout, replace the first command with codex plugin marketplace add /absolute/path/to/session-brief. For clients with a graphical plugin manager, use its supported local/Git marketplace installation flow; these CLI commands do not prove that an already-open Desktop session has reloaded the plugin.

What happens

flowchart LR
    A[Human prompt and observed events] --> B[Private local journal]
    B --> C[Previous brief plus exact original request plus delta]
    C --> D[GPT-6 Luna]
    D --> E[Validated session snapshot]
    E --> F[Context on prompt, resume, or compaction]
  • Before a prompt: preserve the original request exactly, then load this session's last brief as historical context. The initial request is never overwritten by a later request or a model paraphrase.
  • During work: journal observed tool results and subagent results. Merely receiving a subagent result does not call Luna.
  • At a main-thread Stop: run an asynchronous update with Luna, effort low, and a 30-second model-process deadline. Session Brief never blocks a stop to continue the task, sends messages, runs /clear, or opens a successor chat.
  • On resume/after compaction: load the matching saved brief. An asynchronous refresh catches up on completed work that was not summarized successfully.
  • On interruption/exit: capture the event without starting a model call.

Stop is the runtime's stop event. Another installed hook can continue a turn; in that case later events update the brief again. Concurrent updates are serialized; a newer snapshot cannot be overwritten by an older worker. Duplicate identified hook invocations do not spend another model call. Legacy events without native identifiers are kept independently rather than deduplicated by message text.

When a transcript path is provided, a best-effort adapter reads only that session's transcript after validating its session metadata. It incrementally imports visible user/assistant messages and tool records, including hosted tool records that may not have a local hook. This adapter is intentionally limited to recognized Codex JSONL records; the transcript format is not a stable public interface. Partial final lines are left for a later read. It never scans other conversations.

The brief and its evidence

The generated brief has initial_request, purpose, status, constraints, done, changes, decisions, pending, failures, and next. The first field is Luna's clean restatement; the exact initial request remains a separate source. There is no five-item truncation. Model summaries are fallible: they are context, not proof that a command succeeded, a change shipped, or a person granted permission.

Each session gets a private directory keyed by a SHA-256 of its native session ID:

FileMeaning
original-request.txtExact first captured human request
state.sqlite3Transactional event journal and authoritative snapshot
brief.jsonAtomic JSON export with coverage cursor and integrity checksum
brief.mdReadable export with references to the original request and journal

Payloads are kept without silent clipping in the local journal. A compact summary cannot contain every byte of a transcript; detailed results and changes remain available through event:<sequence> references. Coverage is limited to the events actually observed or recognized by the transcript adapter.

The data root is chosen in this order:

  1. SESSION_BRIEF_DATA, if explicitly set.
  2. The plugin's PLUGIN_DATA directory, under session-brief (the compatibility variable CLAUDE_PLUGIN_DATA is accepted as a data path only).
  3. $XDG_STATE_HOME/session-brief, or ~/.local/state/session-brief.

Runtime state is outside this source repository. Newly created session directories and files are private to the current user. Symlinked data paths are rejected. There is no automatic retention deletion in this release.

To inspect a session, run these commands from a checkout and pass its actual native session ID. If a plugin data root is used, add --data /path/to/data-root:

python3 -B src/session_brief.py show --session SESSION_ID
python3 -B src/session_brief.py journal --session SESSION_ID

show reports coverage, staleness, errors and exact data paths. journal prints the complete observed payloads; use it locally and avoid posting it publicly. A new, unrelated chat has a different ID and does not automatically inherit an old brief. To continue elsewhere, explicitly give the new chat the saved brief's path and original evidence references. No automatic new-chat handoff is implemented.

Cost, privacy, and failure behavior

Every successful update uses the existing Codex account's quota/credit arrangements. This is not an API-price estimate or free inference. There is no API-key extraction, account rotation, model upgrade fallback, or automatic paid retry loop. Several quickly arriving events can be covered by one update. Inspect the saved usage counters for what the subprocess actually reported.

The summarizer starts an ephemeral, standalone codex exec in a temporary directory, ignores user configuration, disables hooks/plugins/apps/shell/multi-agent/browser features, uses a read-only sandbox and never requests tool approval. It receives the prompt over stdin and writes a schema-constrained JSON answer. Tool activity in the returned event stream is rejected. This is a restricted agent invocation, not a claim that Codex exposes a universally tool-free inference mode.

The original request, previous brief and new event payloads are sent to Luna through the Codex provider. They can include private project information or quoted secrets. No redactor can guarantee removal of all secrets; use the plugin only where that transfer is appropriate. No telemetry or separate service is added by this plugin. The journal is local and may contain sensitive text. The source and test fixtures contain no real conversations, credentials, runtime journals or machine-specific paths.

  • Invalid response, timeout, denied execution, unavailable Luna or process failure: preserve the last good brief and evidence, mark the update stale, and warn. There is no fallback that promotes the assistant's first sentence into verified work.
  • A later stop or session-start refresh can retry the pending delta. No hidden repeated-call loop runs inside one update.
  • The input budget is 96,000 UTF-8 bytes, including the previous brief and exact original request. The JSON summary budget is 32,000 UTF-8 bytes. Over-budget data is preserved and the update pauses rather than silently deleting constraints. This release does not automatically split an oversized delta; later turns can remain stale until a deliberate recovery is performed. The journal remains readable for manual continuation.
  • Background hooks can be cancelled when the client closes. Saved events survive; future refresh can recover them. A hard process/machine crash can still lose an event that had not reached the plugin. Missing exported files are repaired from the authoritative database on a later successful refresh.

Session Brief does not disable or replace native compaction. It cannot guarantee lossless model memory, faithful completion, or equal latency across machines/accounts. This release has no AbovePrompt band, custom Desktop pane or permission override.

Development and validation

Run the complete deterministic suite; it does not contact a model:

python3 -B -m unittest discover -s tests -v

Tests cover incremental updates, original-request retention, complete observed payloads, repeated prompts, deduplication, session isolation, malformed/oversized responses, failed publication recovery, transcript identity and incremental reads, partial lines, concurrent workers, integrity checks, child-hook recursion guards, backend invocation and hook manifests. Fixtures are synthetic.

Validation performed for this release: deterministic tests; native local marketplace registration and plugin installation under an isolated CODEX_HOME with CLI 0.160.1. This packaging test makes no inference call and does not establish that a live Desktop session loaded its hooks. Live account access, latency, and long-session summary quality need verification in the target environment.

Read the official Codex hooks documentation, plugin packaging guide, and model availability for current runtime requirements. Hook behavior and available models can change between client releases.

Attribution and license

MIT. Read LICENSE. The incremental summary design and summary instructions are adapted from skanehira's MIT-licensed recap-plus. Session Brief preserves that attribution and adds a Codex-specific runtime, exact request retention, an evidence journal, expanded brief fields, and resume context injection.