diff --git a/docs/development/STRUCTURE.md b/docs/development/STRUCTURE.md index e3ed153e6a..519b14a233 100644 --- a/docs/development/STRUCTURE.md +++ b/docs/development/STRUCTURE.md @@ -137,6 +137,7 @@ orchestrator/ ├── sse.py # Server-Sent Events streaming for pipeline visualization ├── startup_reconciliation.py # Startup reconciliation for orphaned containers ├── commit_authorship_store.py # Durable {sha → role} registry sharded by pipeline on the pipeline-state branch; backing store for the commit-authorship registry +├── session_state_store.py # Redis-backed cross-pod session-state store for BRC warm-resume: persists (session_id + window_occupancy + transcript) keyed (pipeline, slice, role) with 6-hour TTL; 32 MiB transcript cap degrades to pointer-only on overflow (#3278) ├── state_store.py # Git-backed pipeline state ├── state_store_probe.py # Background state-store self-heal probe; decouples curative git ops from kubelet probe traffic (#2191) ├── status_reporter.py # Real-time status reporter for collaborators @@ -180,6 +181,7 @@ orchestrator/ │ ├── phases.py # Phase management endpoints │ ├── pipelines.py # Pipeline CRUD and visualization endpoints │ ├── progress.py # Structured progress event endpoints (emit, query) +│ ├── session_state.py # Cross-pod warm-resume session-state endpoints (push/pull per (pipeline,slice,role); #3278) │ └── signals.py # Signal handling endpoints (incl. readiness for concurrent mode) ├── Dockerfile # Orchestrator container image ├── entrypoint.sh # Container entry point @@ -264,6 +266,8 @@ sandbox/ │ ├── contract_cli.py # SDLC contract CLI implementation │ ├── orchestration.py # Multi-agent orchestration support │ ├── orch_cli.py # Orchestrator CLI implementation +│ ├── cli_session_state.py # `egg-orch session-state pull|push` — cross-pod warm-resume sync CLI (thin layer over session_state_sync; resolves identity from env, calls orchestrator /session-state route; #3278) +│ ├── session_state_sync.py # Filesystem helpers for cross-pod session sync: slug math, transcript path resolution, write_pulled_state(), read_state_for_push() (#3278) │ ├── orch_client.py # Orchestrator API client │ ├── sdlc_cli.py # SDLC pipeline CLI │ ├── sdlc_hitl.py # SDLC human-in-the-loop support diff --git a/docs/reference/orchestrator-cli.md b/docs/reference/orchestrator-cli.md index 5617e4123d..489874df3c 100644 --- a/docs/reference/orchestrator-cli.md +++ b/docs/reference/orchestrator-cli.md @@ -61,6 +61,8 @@ Run `egg-orch --help` for full usage. All commands support `--json` for machine- | `egg-orch anchor show [--agent ] [--team]` | Show own anchor, another agent's, or team anchor | | `egg-orch anchor validate` | Validate anchor schema and size limits | | `egg-orch anchor cleanup` | Remove orphaned anchor files | +| `egg-orch session-state pull` | **Event-pump wrapper only** — fetch the prior session for this `(pipeline, slice, role)` from the orchestrator's Redis store and re-materialise the transcript into this pod so `--resume` finds it. Gated on `EGG_SESSION_STATE_FILE`. Best-effort: a miss or failure exits 0 and cold-starts. (#3278) | +| `egg-orch session-state push` | **Event-pump wrapper only** — ship this pod's updated session (pointer + transcript JSONL) back to the orchestrator after the agent exits. Gated on `EGG_SESSION_STATE_FILE`. Best-effort: a failure exits 0 and the next event reseeds. (#3278) | Pipeline ID can be omitted when `EGG_PIPELINE_ID` is set (auto-set in orchestrated mode). Agent role can be omitted when `EGG_AGENT_ROLE` is set. @@ -81,6 +83,7 @@ Agent role can be omitted when `EGG_AGENT_ROLE` is set. | `EGG_BRC_MEMORY` | BRC memory writer mode for reviewers. `full` (default) — handlers write and the event-pump reads the file on re-entry; `write-only` — handlers populate the per-role memory file but the reader stays inert; `off` — writes are no-ops (one-release rollback escape hatch). See [BRC Memory Artifact](../architecture/brc-memory.md). | | `EGG_MESSAGE_POLL_INTERVAL` | Suggested message polling interval in seconds (default: 30) | | `EGG_MESSAGE_POLL_MAX_WAIT` | Server-side cap (seconds) on `message wait --timeout`. Default `60`, minimum `1`. Values `> 90` trigger a startup `warnings.warn` + WARNING log because the gateway's baked-in Squid `read_timeout` / `request_timeout` directives cap backend long-polls at ~60s — raising the cap above that requires a gateway image rebuild, not a ConfigMap edit. See [Agent Wait Patterns §6](agent-wait-patterns.md#6-egg_message_poll_max_wait--long-poll-cap-coupling). | +| `EGG_SESSION_STATE_FILE` | Pod-local path to the session pointer file (`/tmp/egg-session-state.json` by default). Set by the concurrent executor only when warm resume is enabled (`EGG_SESSION_RESUME` / `EGG_CONTEXT_DISCIPLINE`). Its presence in the environment gates `egg-orch session-state pull|push` in the event-pump wrapper. (#3278) | | `EGG_SLICE_ID` | Set by `kubernetes_spawner` for every slice-scoped agent. When set, `message wait` / `message wait-loop` only match messages whose `metadata.slice_id` equals this value OR is null (pipeline-level passthrough — OVERSEER_ALERT and global phase signals continue to wake every waiter). Override with `--slice`. See [Agent Wait Patterns — Auto-scoping](agent-wait-patterns.md#auto-scoping-by-slice-and-producer-allowlist-2725). | | `EGG_WAIT_PRODUCER_ALLOWLIST` | Set by `kubernetes_spawner` for agents that participate in the BRC review graph. Comma-separated list of sender roles; when set, `message wait` / `message wait-loop` only match messages from the listed senders. Spawner derives the set from the review-graph neighbors plus system senders `overseer` and `orchestrator`. Override with `--from-producer`. See [Agent Wait Patterns — Auto-scoping](agent-wait-patterns.md#auto-scoping-by-slice-and-producer-allowlist-2725). | | `EGG_ORCH_STATE_STORE_PROBE_INTERVAL` | Cadence (seconds) of the background state-store self-heal probe. Default `15`. Lowering tightens wedge-detection at the cost of more frequent `git` calls; raising it does the inverse. The staleness watchdog flips `/api/v1/ready` to 503 when cache age exceeds `interval × 2`, so this setting also controls the readiness-flap window. Values above ~30s can exceed the readinessProbe's boot tolerance (`initialDelaySeconds + periodSeconds × failureThreshold = 35s`). |