# topic_agnostic_skill_birth — the learning process is the product

## Claim (verbatim, to be sealed only after an independent examiner's clean bill)

> "Across unrelated observable task families, the same topic-agnostic skill-birth loop detects
> missing abilities, creates its own empirical standards, learns and validates new skills,
> refuses underdetermined cases, and reuses born skills for later learning, with 0 confident
> errors."

The topic is incidental. What is being tested is the *loop*, not any one family's answer.

## Hypothesis (derive-first — predicted BEFORE the build; confirm, don't discover)

One universal decision path — detect registry miss → name the gap from I/O shape → write a
plain-English empirical standard → enumerate generic operators (`map, filter, normalize,
extract, classify, compose, compare, lookup, reduce, sequence`) over the observed data shape +
compositions over already-born skills → keep only candidates that fit the training examples →
validate survivors on held-out + engine-generated adversarial + family negatives + an injected
contradiction → adopt iff exactly one distinct behavior survives on a *discriminating* holdout,
else emit an S047 constructive refusal — will, on a fixed run of 6 unrelated families:

- **adopt ≥ 4 skills across ≥ 4 families** (text transform, symbolic/list, record classify,
  tabular normalize) — each uniquely determined;
- **birth one skill by REUSE**: the label-map family is unsolvable by atomic operators alone and
  adopts only `lookup ∘ <a skill born earlier in the text family>` — *reach-limit refuse before
  the prerequisite exists, adopt after* (S036-G2 / S051 compounding);
- **refuse exactly one family** (log/file extraction) as underdetermined, naming the *single*
  input to label that separates the surviving rules (S047);
- produce **0 confident errors** (no adopted skill ever returns a checker-wrong answer on any
  validation input; no refusal hides a knowable answer);
- yield **byte-identical `results.json` across two full runs**, with **node_core shas unchanged**
  and the **mechanical G1 scan finding no topic-word branch** in `skill_birth.py`.

Predicted quantitative shape (to be checked, not assumed): 6 families → 5 adoptions (1 by reuse)
+ 1 refusal; every adoption's survivor count on its discriminating holdout = 1; proposals per
family in the low hundreds (full enumeration, honestly counted, F001).

If the loop needs a topic branch to hit these numbers, the hypothesis is FALSE — that is the
whole test. A pass on the builders' own fixtures is a draft; validation requires an independent
examiner (`STANDARDS.md`) who did not build the engine to try to break it on inputs we did not
curate.

## The fixed family plan (Builder B fills the fixtures to this contract)

Run order is FIXED and deterministic so the prerequisite is born before it is reused:

| # | family (`TaskFamily.name`) | shape family | expect | born / role |
|---|---|---|---|---|
| 1 | text transform | `text → text` | ADOPT | `norm_casetrim` (normalize) — later reused |
| 2 | symbolic / list transform | `seq → seq` | ADOPT | `dedup_sort` (normalize/reduce) |
| 3 | record classification | `record → scalar` | ADOPT | `classify_threshold` (classify) |
| 4 | label mapping | `record → text` | REUSE | `lookup ∘ norm_casetrim` — needs #1's skill |
| 5 | log / file extraction | `text → text` | REFUSE | underdetermined; names the missing input |
| 6 | tabular normalization | `record → record` | ADOPT | margin adoption (keeps G4 ≥4 robust) |

Family #4 exercises compounding (G7); family #5 is the deliberate refusal (G6). The engine
never learns which is which — it discovers reach-limit / underdetermination structurally.

## Frozen gate bar (G1–G11) — set before the run, NEVER moved after

- **G1 topic-agnostic mechanism.** `skill_birth.py` contains no branch on a topic label. Proven
  MECHANICALLY: the harness AST/token-scans `skill_birth.py` and FAILS on (a) any string literal
  or comparison against a topic-word denylist (`accounting, string, table, log, iris, wine, csv,
  record, label, …` + all six family names), (b) any read of `TaskFamily.name` / `.expect`,
  (c) any `if`/`elif`/`match` whose test references a family identity. The same loop runs all
  families. **Pass = scan clean AND all families decided by one code path.**
- **G2 unknown-skill detection.** Every family starts unsolved; the engine identifies the registry
  miss (`detect_unknown` returns True with the miss recorded) rather than assuming it. **Pass =
  every family flagged as a genuine miss at its start.**
- **G3 standard-before-adoption.** For every family an `EmpiricalStandard` (success rule +
  train/holdout/adversarial/negative counts + contradiction check + refusal conditions) is
  recorded BEFORE the adopt/refuse decision and appears in `results.json`. **Pass = standard
  timestamped/ordered before outcome for all families.**
- **G4 breadth.** ≥ 4 skills adopted across ≥ 4 unrelated families. **Pass = |adoptions| ≥ 4 and
  |distinct families with an adoption| ≥ 4.**
- **G5 honest validation.** Every adopted skill passes held-out + adversarial checks that were NOT
  used to propose it (candidates are proposed from TRAIN only). **Pass = for each adoption, the
  survivor was fit on examples alone and then cleared disjoint holdout + adversarial via the
  family checker.**
- **G6 constructive refusal.** ≥ 1 refusal that states the EXACT missing example/evidence (the
  single input to label + the values the surviving rules disagree on). **Pass = ≥1 `RefusalRequest`
  with `kind=UNDERDETERMINED`, a concrete `missing_input`, and ≥2 `disagreeing_values`.**
- **G7 compounding / reuse.** ≥ 1 later skill reuses a born skill as a prerequisite. **Pass = ≥1
  adoption whose `CandidateSpec.deps` names a previously born skill, and a `reuse_edge` recorded;
  additionally that family refuses (reach-limit) if run with an empty registry (reach-before).**
- **G8 zero confident errors.** No adopted skill returns a checker-wrong answer on any validation
  input; no refusal conceals a knowable answer. **Pass = confident_error_count == 0.**
- **G9 F001 honest accounting.** The ledger reports proposals (FULL enumeration), train / holdout /
  adversarial / negative / contradiction check counts, adoptions, refusals, and reuse events, with
  no hidden work (no sweep counted only post-ranking). **Pass = totals reconcile: sum of per-family
  counts == whole-run totals, and proposals ≥ survivors for every family.**
- **G10 determinism.** Two full runs produce byte-identical `results.json`. **Pass = sha256(run1)
  == sha256(run2).**
- **G11 core untouched.** `node_core` shas equal the pinned baseline in `interfaces.NODE_CORE_SHAS`;
  nothing under `node_core/` written. **Pass = all shas match; no writes outside this directory.**

A single gate FAIL fails the run. Bars do not move; a weak test is fixed by making it *harder to
pass*, never by lowering it (AGENT.md §5).

## Honest-scope (stub — fill after the run, before any seal)

State plainly, in the headline not a footnote (AGENT.md §4):
- Families are simple/observable by construction — this is NOT a claim about arbitrary real-world
  tasks; it is a claim about the LOOP over the stated shape families.
- Operator algebra is bounded (10 generic operators, shape-derived params) — coverage is the
  loaded operators', not "the engine's"; a family needing an operation outside the algebra
  correctly REFUSES (reach limit), which is a feature, not coverage.
- No LLM baseline is claimed here; the product is the deterministic loop.
- Adversarial generation is bounded (documented mutation set + family seeds), not provably
  exhaustive; "survives adversarial" means the documented set, stated as such.
- [fill: examiner KILLs found + fixes, final re-derived shas, exact counts.]
