Skip to content

/landscape-loop-promote skill — contract

Project-local Claude Code skill at .claude/skills/landscape-loop-promote/SKILL.md. Invoked with /landscape-loop-promote [run-dir-or-slug ...] to harvest the adaptation logs from completed landscape-loop-gt / landscape-loop-explore runs, decide which per-landscape adaptations generalise into the class-neutral backend, and launch a new session that lands them as a draft PR behind the cross-deck regression gate.

Why this exists

The two loop skills each emit an adaptations log — every derivation-axis edit made during a run, recorded (in their own words) as "proposals to be accepted or reverted by a human later." Nothing consumes those proposals. The generalisable ones — edits a future landscape would inherit too — accumulate stranded in per-run archived_data/<slug>_explore/adaptations-log.md files while the backend stays behind.

This skill closes that loop. It reads the adaptation logs across runs, separates generalises-into-the-backend from class-specific-by-design (and from already-reverted), and hands off a focused session that promotes the winners into ogur/engine/discovery_modality/. It is the promotion pipeline the configure_class_vocab() seam went through by hand (proposed in Polygon, reverted, committed in GNS561) — now a repeatable step.

It runs no loop. No discovery, no seed, no scorer. Input = loop outputs; output = a promotion proposal + a spawned draft-PR session.

The one judgment it makes

The architecture drew the promotion line already (commit 842e274): ogur/engine/discovery_modality/ holds the class-neutral core (types, concept_queries, refine, cache, sources, matching, aliases); scripts/eval/<class>_discovery/ holds the class-specific siblings (scope_fit vocab, decompose, bio_targets, assemble, runner). An adaptation generalises iff its mechanism (not its vocab values) belongs on the class-neutral side. The tell: would a future 4th class inherit this without re-editing it?

The canonical promoted shape is sources.configure_class_vocab() — an additive injection seam that preserves the siRNA + Monitor behaviour byte-for-byte (reset_class_vocab() restores the defaults; every existing test passes). Every promotion this skill proposes must match that shape.

The five-point generalise test (hard go/no-go)

An adaptation is PROMOTE only if all five hold; miss one and it drops to a lesser bucket, not to the engine:

  1. Recurrence or self-annotated graduation — seen in ≥2 runs across ≥2 classes, or the log/code explicitly flags it landscape-agnostic ("can graduate into the shared matcher later"; "the answer to run X's unsolved Y").
  2. Class-neutral mechanism — the mechanism lives in discovery_modality/ (or the shared matcher/scorer), even if a value it consumes is class-specific. Promote the seam; leave the vocab.
  3. Additive + defaults-preserving — a seam / optional param / opt-in path that leaves siRNA + Monitor byte-for-byte unchanged.
  4. Cross-deck-regression-safe — can survive the archived_data/landscape_loop_benchmarks.md replay (re-score every prior deck; regress one ⇒ revert).
  5. Evidence-backed, kept — the loop kept it (not a reverted lever); every bind is retrieval-first + two-factor.

Honesty rule: a single run of only class-vocab edits yields "nothing to promote yet — needs a second class to corroborate." No manufactured generalisations.

The four buckets

Bucket Meaning Fate
PROMOTE passes all five in the proposal + the spawned PR
KEEP-SIBLING class content (a modality/target/off vocab, a class matcher) never promoted — "never fork the matcher"
DEFER plausibly neutral but seen in one run only held for a second corroborating class
REVERTED / REJECTED the loop backed it out never promoted; recorded so it isn't re-proposed

The KEEP-SIBLING / DEFER / REVERTED rows are the honesty surface — a reviewer must see what was consciously not promoted, or the proposal reads as cherry-picking.

I/O expectations

Input one or more loop-run outputs — -explore: archived_data/<slug>_explore/adaptations-log.md (+ RUN_SUMMARY.md); -gt: no adaptations log — its report doc's recall-by-pass trajectory + the benchmark-registry row. No args ⇒ harvest every *_explore/adaptations-log.md. (The loop contracts name loop-workspace/…; the real on-disk home is archived_data/.)
Output a promotion plan doc (docs/development/<theme>_promotion_plan.md, the /new-source plan-doc skeleton — review surface and self-contained handoff) + a spawned implementation session that opens the draft PR.
Never mutates ogur/engine/ (own run is read-only), the loop outputs, the production ogur.db, the gold decks, the benchmark registry.

The three-phase shape

  • Phase 0 (read + classify, read-only): gather the logs → parse each pass (Symptom/Change/Effect + the "graduate later" annotations) → cross-reference recurrences → apply the five-point test → sort into four buckets → resolve the class-neutral target file + additive-seam shape for each PROMOTE. Empty PROMOTE set ⇒ stop, report "nothing to promote yet".
  • Phase 1 (proposal): write the promotion proposal — per PROMOTE item: source refs, target file + seam, byte-for-byte default to preserve, cross-deck decks that must stay green, acceptance test, before→after deltas; plus the KEEP-SIBLING / DEFER / REVERTED ledger.
  • Phase 2 (handoff): spawn_task a new session pointed at the plan doc, on feat/promote-<theme> off main (no promote/ prefix convention yet; commit type refactor(engine):, per 842e274), whose contract is: implement each item as an additive seam in discovery_modality/, re-point the siblings at the promoted core via a re-export shim (one canonical copy under ogur/, never a fork), make check + re-score every benchmark deck (regress one ⇒ revert that item), open a draft PR. This skill stops at surfacing the plan + chip; it does not edit the engine or open the PR.

Relationship to the loop skills

-gt -explore -promote (this)
Input gold deck + thesis lead asset / thesis the loops' adaptation logs
Runs discovery? yes yes no — reads outputs
Output recall scorecard + reports discovered landscape + adaptations log promotion proposal + draft-PR session
Mutates engine? via proposed levers via proposed adaptations never in its own run (spawns a gated session)

-gt/-explore produce the adaptation proposals; -promote reviews and lands the generalisable subset. It is the third leg of the toolchain, not a third loop.

Reference corpus

The first harvest input is the two completed -explore runs: Polygon PLG-101 (antibody / immunology, archived_data/polygon_plg101_explore/) and GNS561 (small-molecule autophagy, archived_data/gns561_explore/). Together they already exhibit the promote signals the skill keys on — the configure_class_vocab seam (recurs across both), the company-grade evidence gate (GNS561's answer to Polygon's unsolved OpenAlex-org gate), the international research-org supplement (both flag it "graduate later"), and the --patents-by-target auto cost gate.

Honesty note

Like -explore, this skill has not yet been run. It is the intended procedure, extracted from the loops' "proposals for later review" contract + the class-neutral/class-specific architecture split (842e274) + the configure_class_vocab promotion precedent. The five-point test and the bucket mapping are a starting hypothesis; the first real harvest will refine which adaptations are genuinely neutral versus class-shaped.