core/docs/handoff/CHATGPT-REMOTE-BRIEF.md

214 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CHATGPT REMOTE BRIEF — work to do while Shay is away from the library
**Audience:** ChatGPT, acting through its GitHub connector (read repo + open PRs).
**Reviewer:** Claude Code (Opus), at the library. Claude ratifies and fixes minor issues.
**Date scoped:** 2026-05-28. **Status:** active.
> **You (ChatGPT) read this file directly from the repo.** Shay will send a short
> dispatch line from a phone (see §8). Each line points you back here. Do **only**
> the task named, open **one PR**, and **stop**. Do not merge. Claude verifies with
> the CLI (which you cannot run) and merges.
---
## 1. The one rule that overrides everything: `wrong=0`
CORE is a deterministic engine that **refuses rather than guesses**. The serving
math lane is frozen at exactly **3 solved / 47 refused / 0 wrong** (`3/47/0`). A
single wrong answer is a worse outcome than a thousand refusals. Your job never
makes the engine answer *more confidently*; it makes the engine *read more of the
text* so the existing gate has better inputs to either verify or refuse.
You **cannot run the test suite or the `core` CLI** from the connector. That is
fine, because every task in this brief is scoped to a lane where **the worst case
of a mistake is "more refusals," never "a wrong answer."** Claude runs the
invariant gate before anything merges.
---
## 2. The safety boundary (why these tasks are safe to hand you)
There are two lanes in this codebase:
- **Sealed practice lane** — `generate/derivation/*`. Experimental composition.
`chat/` (serving) does **not** import it. Changes here **cannot** move the
`3/47/0` serving number. **All your build work lives here.**
- **Serving lane** — `chat/`, and the shared grounding helper
`generate/math_roundtrip.py::_value_grounds`. wrong=0-sensitive. **Off-limits
to you** (see §6).
`generate/derivation/extract.py` is in the sealed lane (confirmed: `extract_quantities`
is imported only within `generate/derivation/*`). Over-extraction there is caught
downstream by the self-verification gate, which is **refuse-preferring**. That is
the property that makes this delegable.
---
## 3. State of play (what just shipped — context for your audit)
- **ADR-0176** (merged): multi-step chain model, question-targeting, comparatives
pack, self-verification gate (`generate/derivation/verify.py`).
- **ADR-0178 / Gap B** (active, multi-phase): comprehension-guided sequential
composer. **GB-1** = `generate/derivation/clauses.py` (clause segmentation).
**GB-2** = `generate/derivation/compose.py` (sequential combination). Both
**just merged as a 2-PR stack**. GB-3 (lookback), GB-4 (held hypotheses), GB-5
(DAG), GB-6 (measurement) are **not yet built**.
- **ADR-0179** (proposed, doc-only, open PR #446): diagnoses that the structure
machinery is **built but starved**`extract.py`'s `digit + single word` regex
loses word-numbers, multi-word units, currency/decimals, sentence-final numbers,
and mis-attributes units. Sub-phases EX-1…EX-6. **This is your build work.**
Read these before starting:
- `docs/decisions/ADR-0178-compositional-structure.md` (esp. §"wrong=0 obligations", §"Sub-phases")
- `docs/decisions/ADR-0179-extraction-richness.md` (the full extraction plan)
- `generate/derivation/extract.py` (~40 lines — the file you mostly edit)
- `generate/derivation/clauses.py`, `generate/derivation/compose.py` (GB-1/GB-2)
- `tests/test_adr_0178_gb1_clauses.py`, `tests/test_adr_0178_gb2_compose.py` (test style to mirror)
- Gold cases: `evals/gsm8k_math/train_sample/v1/cases.jsonl` (grep ids `0003 0019 0021 0024 0033 0041`)
---
## 4. STREAM A — the double-check (do this FIRST, it's read-only)
CLAUDE.md mandates a **lookback review** before the next phase of a multi-phase
ADR. GB-1 and GB-2 are a 2-PR stack on `generate/derivation/` and GB-3 is next, so
this is owed. You are well-suited to the **read-only** half: you read, you report,
you cannot break anything.
**Task:** audit GB-1 (`clauses.py`) + GB-2 (`compose.py`) against the ADR-0178
claims and produce a findings report. **Do not change any code in this stream.**
Check, and write down findings for, each of:
1. **Doc-vs-impl drift.** Does `clauses.py` / `compose.py` actually do what
ADR-0178 §"Sub-phases" GB-1/GB-2 says? Note any signature/scope differences,
anything the ADR promised that isn't there, anything present that the ADR
didn't scope.
2. **wrong=0 obligation coverage** (ADR-0178 §"wrong=0 obligations", items 15).
For each obligation, find the test in `tests/test_adr_0178_gb*` that would
**fail if the obligation were violated**. If you can construct an input where a
*spurious / unlicensed structure* (obligation #4) or an *irreducible hold*
(#2) might be admitted/resolved, write it down as a candidate hazard — **do not
fix it**, just flag it with the exact input string and why.
3. **Refuse-preferring on ambiguity.** Trace: when a clause's local op is
ambiguous, does `clause_local_results` (GB-1) and `compose_sequential` (GB-2)
resolve to a hold (`None` / refuse) rather than guess? Cite the line.
4. **Determinism.** Any iteration over a `set`/`dict` without ordering, any
reliance on insertion order that isn't guaranteed, any nondeterministic tie-break?
5. **Cross-PR consistency.** GB-2 builds on GB-1's `ClauseResult`. Do the dataclass
shapes, `None`/hold conventions, and unit handling compose cleanly?
**Output:** create a branch `audit/adr-0178-gb1-gb2-lookback`, add **one** markdown
file `docs/handoff/AUDIT-ADR-0178-GB1-GB2.md`, and open a PR titled
`audit: ADR-0178 GB-1/GB-2 lookback (findings only — no code change)`. Categorise
findings as **solid / gaps (no risk) / drift (need amendment) / hazards (live
wrong=0 risk)**. Every hazard must quote the exact triggering input. **No code edits
in this PR.**
---
## 5. STREAM B — the build (ADR-0179 extraction, sealed lane only)
The composer is starved by `extract.py`. Enrich it. **One sub-phase = one PR.**
Each sub-phase only touches `generate/derivation/extract.py` and its test file
`tests/test_adr_0179_extract.py` (create it; mirror the style of
`tests/test_adr_0178_gb2_compose.py` — plain input-string → `assert`). Stay
**lexeme-level / orthographic** (ADR-0165): patterns for "what a number-piece looks
like," **never** grammar templates for "how words combine to mean X" (combining is
the search's job, not the extractor's).
Do these four, in this order. Each is independent; each can ship alone:
- **EX-1 — word-numbers.** `"three"`, `"twelve"`, `"twenty-four"` should extract as
values. Reuse the existing `WORD_NUMBERS` mapping / `en_numerics_v1` if present
(grep for `WORD_NUMBERS`); do **not** hand-roll a new number table if one exists.
Tests: `"three apples"` → value `3.0`; a sentence mixing digit and word numbers
extracts both, left-to-right.
- **EX-3 — multi-word units.** `"12 jumping jacks"` should attach unit
`"jumping jacks"`, not just `"jumping"`. Lexeme-level: a number followed by one
or more lowercase word tokens. Be conservative — over-greedy units cause
*refusals* (safe) not wrong answers, but keep it tight. Tests: `"12 jumping jacks"`
→ unit `"jumping jacks"`; single-word units still work (don't regress GB-1/GB-2 tests).
- **EX-4 — list-unit inheritance** *(highest payoff — unblocks gold case 0024).*
In a same-unit list like `"20, 36, 40 and 50 push-ups"`, the trailing unit
attaches to **every** number in the list, so GB-2's same-unit list-sum can fire.
Tests: that list extracts four quantities all with unit `"push-ups"`. Verify
against case `0024` in `cases.jsonl`.
- **EX-5 — sentence-final numbers.** A number with no following unit word (end of
sentence, or followed by punctuation) should still extract, with an empty/None
unit. Tests: `"She had 5."` extracts value `5.0`.
For each PR: branch `feat/adr-0179-exN-<slug>`, title
`ADR-0179 EX-N: <what> (sealed lane, do-not-merge until Claude verifies)`. In the
PR body, state: which gold case(s) it targets, that it touches only `extract.py` +
its test, and that **serving is untouched** (you did not edit `chat/` or
`math_roundtrip.py`).
---
## 6. HARD RULES — forbidden, non-negotiable
- **Never merge a PR.** Leave every PR open. Claude merges after CLI verification.
- **Never touch** any of: `chat/**`, `generate/math_roundtrip.py` (esp.
`_value_grounds`), `algebra/**`, `field/**`, `vault/**`, `generate/stream.py`,
`ingest/gate.py`, `language_packs/compiler.py`, identity/safety/ethics packs, CI
workflow files, or any test that currently passes (don't "fix" green tests).
- **Do EX-1, EX-3, EX-4, EX-5 only.** **Do NOT do EX-2** (currency/decimal) — it is
entangled with a wrong=0-sensitive grounding change in `_value_grounds` that
**only Claude does**. **Do NOT do EX-6** (measurement — needs the CLI). If you
think EX-2 is needed, write a note in the PR body; don't touch the grounding.
- **No new dependencies, no network calls, no config/threshold changes.** Do not
weaken any numeric threshold (e.g. `1e-6`) to make something pass.
- **No grammar templates, no ML, no fuzzy/approximate matching.** Lexeme/orthographic
patterns only.
- **Determinism:** left-to-right order, no unordered-set iteration affecting output,
no randomness, no timestamps in output.
- **One sub-phase per PR. Small diffs.** If a change grows beyond `extract.py` + its
test, stop and leave a note instead.
- **If unsure, refuse the change and write a note** in the PR body. A note Claude
reads is worth more than a guess Claude has to revert.
---
## 7. What Claude does when back at the library (so you know the handoff)
For each open PR, Claude will: read the diff → run `core test --suite full -q`
and the relevant `tests/test_adr_0179_extract.py` → run the **lane-SHA gate** to
prove serving stays `3/47/0` byte-identical → run `core eval` on the gold cases to
see if any extraction-blocked case (0003/0024) now flips under self-verification →
fix minor issues (naming, a missed edge token, a test assertion) → merge or leave
review comments. Your audit report (Stream A) feeds Claude's GB-3 lookback.
---
## 8. MOBILE DISPATCH LINES (copy-paste one at a time from the phone)
Send these to ChatGPT one at a time. Each is self-contained; ChatGPT pulls the full
brief from the repo itself.
```
Read docs/handoff/CHATGPT-REMOTE-BRIEF.md in the AssetOverflow/core repo, then do STREAM A exactly as written. Read-only audit, one findings PR, do not change code, do not merge.
```
```
Read docs/handoff/CHATGPT-REMOTE-BRIEF.md, then do STREAM B EX-4 (list-unit inheritance) exactly as written. Only edit generate/derivation/extract.py and its test. One PR. Do not merge.
```
```
Read docs/handoff/CHATGPT-REMOTE-BRIEF.md, then do STREAM B EX-1 (word-numbers). Reuse WORD_NUMBERS if it exists. Only extract.py + its test. One PR. Do not merge.
```
```
Read docs/handoff/CHATGPT-REMOTE-BRIEF.md, then do STREAM B EX-3 (multi-word units). Only extract.py + its test. Keep units tight. One PR. Do not merge.
```
```
Read docs/handoff/CHATGPT-REMOTE-BRIEF.md, then do STREAM B EX-5 (sentence-final numbers). Only extract.py + its test. One PR. Do not merge.
```
**Suggested order:** Stream A first (it's owed and risk-free), then EX-4 (best
payoff), then EX-1 / EX-3 / EX-5 in any order. They don't depend on each other.
---
## 9. If ChatGPT gets confused or asks to do more
Tell it: *"Stop. Do only the one task. Leave a note in the PR body for anything
else. Do not merge, do not touch serving, do not touch `_value_grounds`."* Then
move to the next dispatch line, or save it for Claude.