Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions orchestration/spx-v2/LESSONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,55 @@ notes are deliberately not kept here: they go stale, contradict `main`, and
mislead the next reader. Current state lives in [`STATE.md`](STATE.md); history
lives in git.

## RULE 0 — Prime Agent writes the code. You do not. Read this before anything else.

`agent-ops/CLAUDE.md` standing order 1: **Prime Agent is the only development
and coding agent. All code — in any repository, or outside one — is written by
Prime Agent, dispatched through the admission machinery: a GitHub issue as the
complete task specification, and the `auto-dispatch` label admitting it to the
maker fleet. A Claude session never writes, edits, or commits code.**

Standing order 3: Claude sessions are **observers and verifiers only** — write
issue briefs, dispatch, verify a delivered PR against its brief, land what is
green and brief-exact under the operator's merge authority, report, and
maintain Prime Agent continuity.

### What drift looks like, from the session that did it (2026-08-29/30)

It does not announce itself. It looks like being helpful:

- The operator says "the repo is not clean" → **editing files to clean it**,
instead of filing the brief. (`spx#290`, the render deletions.)
- The operator is blocked on a stale doc → **fixing the doc directly**, instead
of filing the brief. (`spx#292`, the IBC plist and INSTALL.md.)
- Neither touched a `.py` file, which is exactly why it felt fine. The order
says **all code, any repository** — and repo files in the product repo are the
fleet's lane whether or not they end in `.py`.

The tell in every case: *"this is small, I can just do it."* That sentence is
the drift. Small is what the fleet is for; the dispatch is cheap and the lane is
auditable.

### The one legitimate exception, and its exact shape

An operator prompt that explicitly re-designates the session — *"You are Prime
Agent, the sole implementing developer for X"* — IS a dispatch, and code written
under it is in-role. That authority covers **the briefs named in that prompt**
and nothing else. When those briefs are delivered, the session reverts to
observer. It does not carry the designation forward into unrelated work.

### What to do instead, every time

1. Write the brief as an issue comment (or a new issue), with acceptance
criteria, anchors verified against current `main`, and out-of-scope stated.
2. Apply `auto-dispatch` + `ready-for-agent`.
3. Verify the PR the fleet returns, against the brief.
4. If it is green and brief-exact, land it under the operator's merge authority.

Writing in the orchestration repo (`STATE.md`, `LESSONS.md`, session records) is
continuity, not code, and stays in-role. Everything in a product repository does
not.

## Method

1. **Settle repo state from GitHub, never from notes — including this repo's.**
Expand Down
2 changes: 1 addition & 1 deletion orchestration/spx-v2/PRIME_AGENT_INPUT_SPX_V2.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ refusal is unexplained.
superpowers, and the rest — into the S0 plan so later slices route through them
deliberately). Fix **#230** (one accessor; display = submission truth; keep the
shipped-default-off pin untouched). Safety action for the operator, documented in the PR:
set the Mac config's `execution.mode: off` explicitly until S4. Exit: operator starts SPX
set the Mac config's `execution.mode: "off"` explicitly until S4 — **quoted**: bare `off` is YAML `False` and the loader refuses it by design (measured 2026-08-30). Exit: operator starts SPX
in `PAPER/OFF`; `/readiness` shows real build identity, honest mode, and the two session
domains failing closed with `session_store_unavailable` (expected until S1).
- **S1 — Hermes→SPX session delivery** (#195, #196, #171; respect #153 provider-owned
Expand Down
51 changes: 46 additions & 5 deletions orchestration/spx-v2/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,62 @@ first slice whose exit criteria require a real broker order.

1. **Start the runtime on the Mac.** No cloud session can: the only Claude Code
environment is `anthropic_cloud` (Linux), with no route to the Mac and no
IB Gateway. Before first start, delete `data_source.vix.allow_cboe_vix3m_fallback`
from the Mac's `config/data.yaml` or the process refuses to start.
Then in `PAPER/OFF`, `/readiness` should show real build identity and honest
IB Gateway. **First attempt made 2026-08-30 — [thomaswillner/spx-0dte-bot-v2#291](https://github.com/thomaswillner/spx-0dte-bot-v2/pull/291), evidence only.** It
did not pass: with IB Gateway down the PAPER runtime fail-closes at adapter
start (`paper_adapter_session_check_failed`) and never binds, so `/readiness`
was never presented. Two measured FAILs (session artifacts absent →
`artifact_missing` both domains; no listener on 7497), three observables
unprovable without a live process.

**Three preconditions, all required — the Gateway alone is not enough:**
1. **IB Gateway running on 7497.** Installed as of 2026-08-30 (operator);
supervision is [thomaswillner/spx-0dte-bot-v2#292](https://github.com/thomaswillner/spx-0dte-bot-v2/pull/292) plus issue
[#249](https://github.com/thomaswillner/spx-0dte-bot-v2/issues/249), not a hand-start.
2. **Hermes publishing the session artifacts.** Observable (c) failed
`artifact_missing` on BOTH domains, and no amount of Gateway uptime fixes
that — the artifacts come from the Hermes→SPX publisher, which is not
deployed (decision D1 territory). Without this, (c) fails again.
3. **`data_source.vix.allow_cboe_vix3m_fallback` deleted from the Mac's
`config/data.yaml`.** It does not block startup (see Corrected claims),
but it does leave `startup: GONE data (paper_data_composition_refused)`
with entries IMPOSSIBLE — so a healthy `/readiness` is unreachable while
it is present. Also set `execution.mode: "off"` **quoted**.

Only with all three does `/readiness` show real build identity and honest
mode, both session domains healthy with real cookie age and verification
time, `open_interest` as `cboe_intraday_authority_removed`, and `vix3m`
measured `DELAYED(900 s)` with its structural label.
2. **Decision D3** — the first PAPER order: structure, scenario, time window.
Gates S4.
3. **Issue #274's open question** — `docs/design/168/round-4/renders/`, 216 PNGs,
31,278,412 bytes, referenced only by their own `index.json`. PR #283
3. **Issue [thomaswillner/spx-0dte-bot-v2#274](https://github.com/thomaswillner/spx-0dte-bot-v2/issues/274)'s open question** — `docs/design/168/round-4/renders/`, 216 PNGs,
31,278,412 bytes, referenced only by their own `index.json`. [thomaswillner/spx-0dte-bot-v2#283](https://github.com/thomaswillner/spx-0dte-bot-v2/pull/283)
recommended removing them and keeping the textual record, but left the call
to the operator, which is why #274 is still open.

Open decisions D1–D8 are listed in the input document §10.

## Corrected claims — measured, after being asserted wrongly

- **A leftover `data_source.vix.allow_cboe_vix3m_fallback` does NOT refuse
startup.** This file said it did. Measured on the Mac ([thomaswillner/spx-0dte-bot-v2#291](https://github.com/thomaswillner/spx-0dte-bot-v2/pull/291)): `extra="forbid"`
fires inside *provider composition* and is converted to
`startup: GONE data (paper_data_composition_refused)` with "entries are
IMPOSSIBLE" — with a live Gateway the process **runs and binds** in that
state. Startup refusals for raw YAML come from `settings_adapter.py`'s named
`STRATEGY_OWNED_PATHS`, which this key is not on.
*Provenance of the error:* [thomaswillner/spx-0dte-bot-v2#270](https://github.com/thomaswillner/spx-0dte-bot-v2/pull/270)'s body and the `production_data.py:89`
comment both assert the refusal; it was copied from them into this file, the
Mac dispatch prompt and several summaries **without ever being run**. The
code comment is still wrong and is worth a fix lane.
*The rule this broke is already in `LESSONS.md` §13* — never publish a claim
you have not run in the form you state it.
**Do not over-correct the other way:** deleting the key is still REQUIRED
before a runtime-proof attempt. Only the reason was wrong. It does not stop
the process binding; it does leave data composition GONE and entries
IMPOSSIBLE, so `/readiness` cannot come up healthy while it is there.
- **`execution.mode` must be quoted.** Bare `off` is YAML `False` and the loader
refuses it by design. Set `execution.mode: "off"`.
Comment thread
thomaswillner marked this conversation as resolved.

## Standing facts that keep getting re-derived

- **MATS, superpowers and Prime's route selection are Mac-harness resident.**
Expand Down
Loading