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

11 KiB
Raw Permalink Blame History

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 lanegenerate/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 lanechat/, 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 starvedextract.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.