SPEC-199 — Skill-First Architecture
Current ownership boundary: substrate stores durable facts; agents own judgment, policy, and authoring loops.
SPEC-199 — Skill-First Architecture: Substrate as Store, Agents as Skills
Status: adopted 2026-05-22. Owner: platform.
Related: SPEC-001 (polymorphic substrate), SPEC-013 (skills as artifacts),
SPEC-046 (scheduled workers), SPEC-052 (gap detection), skills/MAINTENANCE.md.
1. Principle
Substrate is the data/metadata store and the transactional mechanism. Agents do the thinking, expressed as versioned Skills.
Content manipulation, recurring maintenance, and economic/governance policy belong in skills (SPEC-013 artifacts), run by agents — not hardcoded in substrate Python. Substrate keeps the schemas, APIs, hooks, and atomic guarantees those skills call. This is the norm for all new code.
2. The decision rule (where does X go?)
For any capability, ask: does this require atomicity, data integrity, or a constraint the DB must enforce?
-
YES → STAYS in substrate as a verb/worker/hook. Ledger postings, balance math, idempotent state transitions, vote tallying, gate-evaluation writes, link stamping, content-hash versioning, embeddings/search indexes, partition/matview maintenance, auth, schema validation. You cannot make a double-entry ledger a “skill.”
-
NO, it’s judgment / content / policy → SKILL. What to write and how (authoring, summarizing, classifying, extracting), when/whether to act (funding, betting, promoting, moderating, flagging), and the rationale behind thresholds and weights.
-
Mixed → HYBRID. Keep the deterministic/transactional pass + execution harness in substrate; move the judgment/prompt to a skill the worker loads. Reference implementation:
scheduled_workers/linking_maintenance(Pass 0/1 deterministic in substrate; Pass 2 loadsskills/entity-linking/SKILL.md).
3. The three migration patterns
3.1 LLM worker → load policy from a versioned SKILL.md
An LLM-driven worker/verb must NOT hardcode its system/user prompt. It loads the
prompt body from a SKILL.md (a SPEC-013 artifact: versioned, signal-rated,
improvable) and degrades to a minimal inline fallback when the skill or the LLM
runtime is absent. Pattern: _load_skill("<name>") → prepend to cached_system
(see linking_maintenance/runner.py). The deterministic selection/audit/budget
scaffolding (scheduled_workers/_runner.py, _policy.py, _llm.py) stays.
3.2 Policy constant → config authored by a policy skill
Magic thresholds/weights/decay constants baked into mechanism verbs are policy.
Externalize them the way senate.gate_define already does: policy lives as
data (a config row / gate row), the mechanism verb just reads and applies it,
and a policy skill authors/justifies the values. New mechanism verbs must read
tunables from config, never hardcode them.
3.3 Content/persona/seed corpus → lives in scidex-agents
Canned scientific/editorial content, persona prompts/contexts, the mimeo/template
seed corpus, and the agent outer-loop driver are agent material, not store
material. Their canonical home is the scidex-agents repo. Relocation is gated
on that corpus being reliably deployed in the substrate runtime (see §6).
4. Classified catalog (2026-05-22 inventory)
4.1 Scheduled workers / watchdogs
-
STAYS (~50+ workers + 4 watchdogs): all
gap_detector_*,wiki_parse_on_write,wiki_section_miner, dividend/deadline/budget/ calibration ticks, embed/dedup/evidence-ledger/matview/partition maintenance, federation I/O, trust/score/popularity/portfolio recompute,senate_gate_evaluator,corpus_quality_sweep, all watchdogs. Plus detector workers:spec_drift_auditor(iter-11 #2096),schema_registry_auditor(iter-170/172/174 #2196/#2200/#2201, operationally complete with 12 tests),parity_inventory_auditor(iter-179/180/181 #2204/#2205/#2206/#2207/#2208, 16 tests; sister resolver agents #99 iter-178),demo_flow_health_auditor(iter-210/211 #2218/#2219, 8 unit tests; sister resolver agents #101 iter-209; SPEC-113 §3.7 status observer). Deterministic; no judgment. -
HYBRID:
linking_maintenance(done — the template); ✓persona_drift_dailynarration →persona-drift-narrationskill (this iter);visual_artifact_generator(selection stays; prompt templates → skill — not yet done). -
SKILL (LLM, hardcoded prompts — migrate): progress table (✓ = wired via
_skill.load_skill_body+ inline fallback; PR refs):-
✓
proposal_from_*×6 +proposal_feed_from_unreplicatednow queueagent_work_packetartifacts; proposal authorship runs inscidex-agents -
✓
brief_writer_daily+daily_digest→digest-authoring(#2091) -
✓
falsification_scorer→falsification-scoring(#2092) -
✓
scrutiny_worker→scrutiny-scoring(#2092) -
✓
comment_classifier→comment-classification(#2094) -
✓
debate_outcome_synth→debate-outcome-synthesis(#2094) -
✓
cross_disease_analogy→cross-disease-analogy(#2094) -
✓
prediction_miner→prediction-mining(iter-99 #2099). -
✓
open_question_from_falsified→residual-question-from-falsification(iter-99 #2099; consolidated 1-prompt shape). -
✓
claim_extractor→claim-extraction(iter-99 #2099; 3-prompt unified consolidation per the iter-34 N-modes pattern). -
✓
persona_drift_daily→persona-drift-narration(iter-100 #2107 HYBRID; narration text from skill, statistical selection stays).
Wave-2 SKILL tier 100% complete at iter-100; all ☐ above closed.
-
4.2 Economics / governance — mechanism STAYS, policy EXTRACTS
-
STAYS (mechanism): LMSR/CLR/Brier math, all ledger postings,
wallet.*,budget.reserve/settle,agent_budgets.spend, market/proposal/gate state transitions, vote tally,dividend_ticktransactional core, recusal/self-deal guards. Do NOT move these out of the DB. -
POLICY (extract to config + policy skill): progress table after the iter-40 audit revealed the catalog overstated remaining work — several constants are ALREADY env-driven via
scheduled_workers._policy.f_env.-
✓
scrutinydeviation_threshold (env:SCIDEX_SCHED_SCRUTINY_WORKER_DEVIATION_THRESHOLD). -
✓ 7 scheduled workers’ usd_cap / limit / lookback / max_tokens (env: per-worker
SCIDEX_SCHED_<NAME>_*). -
✓ Per-worker LLM model selection (env).
-
✓
senate_proposal_resolveMIN_QUORUM (env:SCIDEX_SENATE_MIN_QUORUM, #2119). -
✓
pantheon_debate_resolve_INCONCLUSIVE_MARGIN (env:SCIDEX_PANTHEON_INCONCLUSIVE_MARGIN, this PR). -
✓
score.pyDEFAULT_WEIGHTS(env: per-kindSCIDEX_SUBSTRATE_SCORE_WEIGHT_<KIND>; PR 104 era, pre-Wave-3-session). iter-46 audit caught this — was incorrectly listed as ☐ in the catalog. Score decay also has env overrides. -
✓
agent_trust_score4-weight group (W_CALIBRATION / W_DIVIDENDS / W_SIGNAL_VOLUME / W_AGE) → env vars (SCIDEX_TRUST_W_*) +trust-score-weight-policyskill (this PR). 2nd full-shape Wave-3 entry; includes a sum-to-1.0 invariant check that warns at startup if violated. -
✓
trust_propagate4-constant group (_DAMPING / _DECAY_HALFLIFE_DAYS / _SIGNAL_THRESHOLD / _INTRINSIC_DEFAULT) → env vars (SCIDEX_TRUST_*) +trust-propagation-policypolicy skill (this PR). First constant-GROUP externalization combining the lightweight env-var pattern with a documented policy skill per the SPEC-199 §4.2 "config-
policy skill" model — full Wave-3 shape on a single subsystem.
-
-
🔶
dividend_backpropPython constants — iter-99 env-var externalization ofPHASE1_BASE_DIVIDEND(1.0),DECAY_BASE(0.5), and the 3_CALIB_MULTIPLIER_*decile multipliers (1.5/1.0/0.5). Envs:SCIDEX_DIVIDEND_PHASE1_BASE,SCIDEX_DIVIDEND_DECAY_BASE,SCIDEX_DIVIDEND_CALIB_{TOP,MID,BOT}. Smoke-verified safe: 33 dividend_backprop tests + 21 cross-repo CI tests at iter-99 (cross-repo CI grew to 35 tests across 13 guards by iter-126); all pass; defaults unchanged. The remaining ☐ piece is thedividend_tickSQL-embeddeddamping=0.85/ recency1.0literals — those live in raw SQL queries and need a different parameterization shape; deferred per the user’s ledger-touching risk flag. -
✓
tier_promotefalsification cutoffs — iter-96 extracted 0.7/0.5 from inline literals to module-level constants (FALSIFICATION_HARD_BLOCK_THRESHOLD,FALSIFICATION_CAVEAT_THRESHOLD); iter-97 wrapped them in_env_floatfor operator override (envs:SCIDEX_TIER_FALSIFICATION_HARD_BLOCK_THRESHOLD,SCIDEX_TIER_FALSIFICATION_CAVEAT_THRESHOLD). Full Wave-3 done. -
✓
calibration_recompute_DECILE_WINDOW_DAYS / _DECILE_MIN_EVENTS (envs:SCIDEX_CALIBRATION_DECILE_*, this PR). -
✓
market_DEFAULT_LMSR_B is the FALLBACK for markets without an explicitlmsr_bDB column value; per-market liquidity is already data-driven (row["lmsr_b"]from the markets table). iter-46 audit finding — was incorrectly listed as ☐. The hardcoded fallback constant is acceptable since real markets carry per-row policy. -
✓
managed_runtimeMIN_CITATION_COUNT (env:SCIDEX_MANAGED_RUNTIME_MIN_CITATION_COUNT, this PR). -
✓
squad_fork_FORK_SEED_FRACTION (env:SCIDEX_SQUAD_FORK_SEED_FRACTION, this PR). -
✓
atlas/agent_personality_content_driftDEFAULT_THETA (env:SCIDEX_PERSONALITY_DRIFT_THETA, iter-117 #2174 — SPEC-177 §7.2 personality.md drift threshold; 9th explicit externalization). -
✓
watchdogs/link_checker/policyMAX_PAGES_PER_RUN / WARN_BROKEN_LINKS / CRIT_BROKEN_LINKS (envs:SCIDEX_LINK_CHECKER_*, iter-118 #2175; 10th externalization). -
✓ 10×
gap_detector_*_DEFAULT_PRIORITY constants (envs:SCIDEX_GAP_PRIORITY_<DETECTOR>, iter-119 #2176 via new sharedscheduled_workers/_env.pyhelper module — 11th-20th batch externalizations: UNOWNED_ARTIFACTS=0.3, FAILED_QUALITY_GATES=0.8, UNSCORED_HYPOTHESES=0.6, STALE_MARKETS=0.4, MISSING_PREDICTIONS=0.5, MISSING_EVIDENCE=0.5, UNSCORED_GAPS=0.6, ZERO_VOLUME_MARKETS=0.4, UNTRIAGED_PROPOSALS=0.7, MISSING_REPRODUCE_ATTESTATIONS=0.5). Wave-3 now has 28+ explicit externalizations (iter-314 added the 9th full-shape entry —domain-prioritization-policy, a 4-for-1 lift covering the Biomni-parity quartet). -
✓
hypothesis_score_update4-weight group (W_PAPER_QUALITY / W_DEBATE / W_CALIBRATION / W_PAPER_COUNT) +_CALIBRATION_TEMPERATURE→ env vars (SCIDEX_HYPOTHESIS_W_*+SCIDEX_HYPOTHESIS_CALIBRATION_TEMPERATURE) +hypothesis-score-weight-policyskill (PR #2231, iter-217). 3rd full-shape Wave-3 entry (afteragent_trust_score+trust_propagate); includes a sum-to-1.0 invariant check that warns at startup if violated, and the policy skill documents the adaptive low-evidence redistribution branch + maturity floor that operators must NOT try to replicate via env-var math. 22nd explicit Wave-3 externalization. -
✓
gap_advance_status3-threshold intermediate ladder group (_OPEN_TO_INVESTIGATING / _INV_TO_PARTIAL / _PARTIAL_TO_SUBSTANTIAL) → env vars (SCIDEX_GAP_*_THRESHOLD) +gap-status-ladder-policyskill (PR #2232, iter-218). The terminal rung_SUBSTANTIAL_TO_RESOLVEDwas already env-overridable viaSCIDEX_RESOLVED_COMPOSITE_THRESHOLDpre-Wave-3; that PR completed the ladder. 4th full-shape Wave-3 entry; includes a strict-monotonicity invariant warning at startup when env-var drift makes higher rungs unreachable (rungs evaluated top-down in_choose_new_state). 23rd explicit Wave-3 externalization. -
✓
gap_roi_aggregator4-tunable reallocation policy (_BOOST_TOP_N / _REDUCE_BOTTOM_N / _BOOST_FACTOR / _REDUCE_FACTOR) → env vars (SCIDEX_GAP_ROI_*) +gap-roi-realloc-policyskill (this PR). 5th full-shape Wave-3 entry; the policy skill documents the boost > reduce asymmetry (intentional design, not a typo: yield is noisy at low mission counts, reducing compounds badly, boosting is self-correcting) and the shadow-vs-apply split. 24th explicit Wave-3 externalization. -
✓ Skill taxonomy (this PR, iter-221) — every skill in
skills/is now classified bycategory+permission_level-
write_access+owner_role_aliasesinscidex_agents.agent_driver.skill_taxonomyin/home/ubuntu/scidex-agents. The taxonomy is the controlled vocabulary the persona-skill runtime filter will read in iter-222; CI guard #18 (test_skill_taxonomy.py, 75 tests across 67 skills) keeps it 1-to-1 with the on-disk catalogue and pins the count. Not a Wave-3 externalization itself (no constants moved), but the foundation step for §5 (“execution-wiring track”). Seedocs/architecture/skill-taxonomy.mdfor the controlled vocabulary, the Allen-Institute scientist default profile, and the iter-222/223 follow-up roadmap.
-
-
✓
falsifier_accountability4-tunable reputation policy (threshold_strong / delta_successful / delta_rebutted / delta_fabricated) → env vars (SCIDEX_SCHED_FALSIFIER_ACCOUNTABILITY_*, already in place pre-Wave-3) +falsifier-accountability-policyskill (this PR, iter-221b). 6th full-shape Wave-3 entry. Documents the honest-error / bad-faith asymmetry (|delta_fabricated| ≥ 5 × |delta_rebutted|), the positive-expected-value-at-50% invariant (delta_successful > |delta_rebutted|), and the pool-ban-as-the-real-fabrication-penalty design. Signals are not directly ledger-bearing (no apply-flag), but they feedtrust-score-weight-policyrollup. 25th explicit Wave-3 externalization. -
✓ Participant-trio shared risk-envelope + per-participant defaults (
max_position_size/max_drawdown/concentration_capshared;FUND_FLOOR+ top-N for value-funder;sigma_threshold/STAKE_SIZE/model_decayfor contrarian;SCIDEX_DIVERSITY_MIN/RECOVERY_THRESHOLD/ALLOCATION_UNIT/EXPLORATION_GRANT/diversity_bonuscap for diversifier) →participant-policyskill, now owned byscidex-agents(iter-305, PR #2245; moved out of the substrate prompt catalog on 2026-05-24). 7th full-shape Wave-3 entry; single doctrine drags 3participant_*skills off the iter-220 “no-hardcoded-constants” backlog because the tunables are cross-coupled (changing the diversifier’sSCIDEX_DIVERSITY_MINwithout looking at the contrarian’ssigma_thresholdleaves two participants chasing the same noise). Documents 6 load-bearing invariants (descendingmax_position_size, inverse-orderedconcentration_cap,RECOVERY_THRESHOLD > SCIDEX_DIVERSITY_MINhysteresis,diversity_bonus_cap ≤ 2.0, …). 26th explicit Wave-3 externalization. -
✓ Proposal-authoring 5-dimension weighted feasibility rubric (Technical 0.30 / Resources 0.25 / Regulatory 0.20 / Timeline 0.15 / Risk 0.10) + decision thresholds (≥0.7 ship / 0.4-0.7 conditional / <0.4 drop) + tripwire constants (timeline buffer ≥25%, budget overage ≥30%) + hard-blocker → abstract → mitigation pattern →
proposal-feasibility-policyskill (this PR, iter-311). 8th full-shape Wave-3 entry. Documents 6 load-bearing invariants (weights sum to 1.00; monotonically non-increasing weight ordering; two distinct cutoffs not collapsed; buffer/overage are caps not boosts; hard-blocker without concrete mitigation = drop). This originally lifted the proposal authorship surface from 2.6 → ~4.8 on the iter-220 “no-hardcoded-constants” axis. The later work-packet split moves qualitative proposal judgement fully toscidex-agents; substrate proposal-trigger workers no longer load the authoring skill directly. The numerics remain documented here for agent policy reuse. 27th explicit Wave-3 externalization. -
✓ Biomni-parity quartet weighted-aggregation constants (causal_gene_prioritization: DisGeNET 0.25 / KG-causal 0.25 / G2P 0.20 / Monarch 0.20 / druggability 0.10; drug_repurposing: Broad 0.40 / reversal 0.30 / sensitivity 0.20 / literature 0.10; rare_disease_diagnosis: Phenodigm 0.45 / Monarch 0.30 / G2P 0.15 / age-onset 0.10; microbiome_analysis: |log2 FC| ≥ 1.5 + FDR < 0.05 + n_taxa ≥ 3 + n_samples ≥ 10 conjunction) + shared cross-domain constants (emit threshold 0.7, evidence floor 0.3, top-3 hypothesis cardinality) →
domain-prioritization-policyskill (this PR, iter-314). 9th full-shape Wave-3 entry; single doctrine drags FOUR skills off the iter-220 “no-hardcoded-constants” backlog at once — the largest cross-coupled cluster after participant-policy. The quartet shares the same workflow shape (forge-evidence → per-class scoring → weighted aggregation → conditional emit) and the same emit/floor constants; bundling here keeps them coherent. Documents 6 load-bearing invariants (weights sum to 1.00; non-increasing weight ordering within each domain; emit threshold > evidence floor; microbiome 4-way conjunction; druggability ≤ 0.10 modifier cap; rare-disease top-1 conditional vs other 3 quartet members’ top-3 unconditional). The four quartet skills go v0.1 → v0.2 in the same PR; the qualitative judgement stays in the source skills and the numerics live in this policy doc. Lifts the four sources from 3.0 / 2.2 / 2.0 / 2.4 → ~4.8 on the iter-220 “no-hardcoded- constants” axis — a 4-for-1 design-quality lift. 28th explicit Wave-3 externalization.
Pragmatic Wave-3 shape: lightweight env-var override with graceful default-on-typo (the iter-40 / iter-41 pattern). Heavier “config row + policy skill” model per SPEC-199 reserved for groups that see enough operator tuning to warrant the authoring effort.
-
4.3a On-demand verbs with hardcoded LLM prompts (re-sweep addition)
Beyond §4.1’s scheduled-worker catalog, nine skill/verbs/*.py files embed a
"You are …" system prompt + LLMCaller/cached_system. Verbs are
agent-callable through the API, so their embedded policy is even more visible
than worker cron prompts — same pattern, higher leverage.
-
✓
gap_decompose→gap-decomposition(#2093, iter-9). First verb-layer migration. -
✓
gap_elo_round+open_question_elo_round→elo-pairwise-importance(#2127, iter-52). Consolidated; both share the pairwise-importance scoring model. iter-52 also caught a latent-bug fix during migration. -
✓
percolation_classify→ routed to existingcomment-classificationskill (#2131, iter-55). Shared rubric; no new skill needed. -
✓
hypothesis_design_experiment+hypothesis_evidence_synthesis+hypothesis_prioritize_experiments→ 3 hypothesis-* skills batch (#2125, iter-51). One-batch consolidation per shape. -
✓
hypothesis_literature_scout→literature-search-query-generation(#2132, iter-56). FINAL verb migration; closed verb tier 9-of-9. -
✓
hypothesis_cross_species_inference→cross-species-inference(#2131, iter-55).
Verb tier 9-of-9 CLOSED at iter-56 #2132. All 9 verbs now route through skills. Catalog last refreshed iter-164.
4.3b Non-worker, non-verb modules with hardcoded prompts (re-sweep addition)
Modules outside scheduled_workers/ and skill/verbs/ that hardcode system
prompts; same migration pattern applies. Progress:
-
✓
atlas/causal_extractor.py→causal-triple-extraction(#2100). -
✓
atlas/semantic_extractor.py→semantic-belief-extraction(#2101). First use of the{{PLACEHOLDER}}substitution pattern (multi-line predicate vocab +MAX_TRIPLESint). -
Retired:
persona_runner/llm_decide.pypreviously mapped topersona-runtime-decision(#2102), but substrate no longer executes provider-backed persona decisions. Agent runtimes inscidex-agentsnow own prompt assembly and adaptive decision loops. -
Superseded:
ingest/pubmed_update/classifier.pypreviously usedevidence-direction-classification(#2103), but substrate now keeps only the deterministic query-bucket heuristic. Abstract-level evidence-direction judgment is agent-owned. -
✓
shredder/extractors.py→paper-shredding(#2123, iter-43). Same structured-message-with-cache_controlshape as pubmed/classifier; shared system policy across the 3 tool_use extractors (claims, datasets, open_questions) — atomicity, faithfulness, one-kind-per-turn discipline. 3rd Wave-2 layer closed at iter-43. -
WITHDRAWN
skill/tool_runtimes/causal_llm.py— NOT a migration target. Itssystem_promptis config-driven (config.get("system_prompt", "…1-line default…")); the policy lives in the CALLER’s config, not the module. The one-line fallback (“expert causal reasoning system; respond with valid JSON only”) is intentionally minimal — extracting it as a skill would not improve governance and would mislead readers about where the policy lives.
4.3c Additional policy constants in mechanism verbs (re-sweep addition) — DONE except 1
Beyond §4.2, hardcoded judgment constants worth externalising as data. Most landed iter-44-46 + iter-117-119 (see §4.2 catalog above for env-vars
-
PR# provenance):
-
✓
agent_trust_score.pyW_CALIBRATION/W_DIVIDENDS/W_SIGNAL_VOLUME/W_AGE weights (iter-46; full Wave-3 shape withtrust-score-weight-policyskill). -
✓
trust_propagate.pyPageRank constants (iter-44 #2118; full Wave-3 shape withtrust-propagation-policyskill). -
✓
market_trade.py_DEFAULT_LMSR_B=144.27(iter-46 audit: already data-driven via per-rowlmsr_bcolumn; fallback constant acceptable). -
✓
pantheon_debate_resolve.py_INCONCLUSIVE_MARGIN=0.10(iter-45). -
✓
managed_runtime_review_gate.pyMIN_CITATION_COUNT=3(iter-46). -
✓
squad_fork.py_FORK_SEED_FRACTION=0.10(iter-46). -
☐ Domain evidence-weight vectors in
hypothesis_chromatin_tf_binding_synthesis.pyandhypothesis_rna_modification_mechanism.py(deferred — domain-specific, lower leverage than verb-tier constants).
See §4.2 catalog for full env-var + iter#/PR# provenance details.
4.3d v1-personas corpus (re-sweep addition)
data/v1-personas.yaml (33KB, 939 lines, persona content) + its loader
skill/seed_v1_personas.py — same relocation class as seeds/ but outside
the named tree. Move with §4.3 in Wave 4.
4.3 Content / seeds / agent-driver — MOVE to scidex-agents (gated)
-
seeds/mimeos/(55 bundles),seeds/templates/(md/yaml/prompt text),seeds/agent_configs/,seeds/labs/→scidex-agents/seeds/.... Caveat:seeds/templates/*/policies/*.pyare imported (mechanism), not just data — they need an import contract before the in-repo tree is deleted. -
agent_driver/(driver +prompts/+contexts+kris_bootstrap) →scidex-agents(this is the literal agent runtime living in the store). -
debate/personas._BUILTIN_PROMPTS,seed_personas.INITIAL_PERSONAS[*].instructions→ source from the agents corpus; keep the seeding mechanism. -
STAYS:
seeds/schema_registry/(validation schema),bundle_loader.py, seeding mechanism,skill/persona_decision_skills.pyresolver,system_policies.py.
5. Migration waves
-
Wave 0 (done): cross-linking —
linking_maintenanceHYBRID worker +entity-linking/artifact-editing/… skills. The reference pattern. -
Wave 1 (done, #2089; superseded by work-packet split): A shared proposal authorship skill consolidated the original 7 duplicate prompts. The proposal-trigger workers now queue
agent_work_packetartifacts instead of loading that skill in substrate. -
Wave 1.5 (done, #2091):
digest-authoringconsolidatesbrief_writer_daily-
daily_digestshared editorial policy.
-
-
Wave 2 (DONE — 100% across complete substrate, verified iter-115): skill-ified all LLM workers (§4.1) + on-demand verbs (§4.3a) + non-worker modules (§4.3b) + ingest extractors. iter-37 declared Wave-2 complete for
scheduled_workers/; iter-113/114 broadened SPEC-198 audit toingest/+skills/directories and closed 2 final gaps (experiment_extraction + kg_extractor). iter-115 #2173 codified as 8th cross-repo CI guard (test_skill_body_loaded_when_inline_prompt_used). Notable workers/verbs migrated since the iter-37 milestone:causal_triple_extraction(#2117),semantic_belief_extraction(#2118),persona-runtime-decision(#2120),paper-shredding(#2123 final 3rd-layer),gap_decompose,falsification_scorer,scrutiny_worker,prediction_miner,claim_extractor,persona_drift_daily, all 9 verbs from §4.3a — 28+ total skills in the user-facing/authoring/operational catalog. -
Wave 2 enrichment (DONE, agents #68 + iter-26 + iter-41 + iter-55-57 cross-refs): all 22 agents-side operational skills carry verified “Substrate verbs you call” sections; rubric skills got cross-refs to peer rubrics (iter-55/56/57); meta-discipline applied to authoring skills (iter-84).
-
Wave 3 (SUBSTANTIVELY DONE — 21+ explicit externalizations): §4.2 + §4.3c constants externalized via lightweight env-var pattern. Per §4.2 catalog (above), 21+ externalizations through iter-119 batch (atlas DEFAULT_THETA / link_checker / 10× gap_detector). Only ☐ remaining:
dividend_tickSQL-embedded literals (different parameterization shape; deferred per ledger-touching risk per user flag). -
Wave 4 (gated; 0 of 4 preconditions met as of iter-70 #80): relocate seed/persona/agent-driver corpus (§4.3, §4.3d, §6) to scidex-agents. Operator-facing gate status at
scidex-agents/docs/wave-4-seed-corpus-gate-status.md.
Execution-wiring track (orthogonal to migration waves) — done:
-
Mechanism:
_select_runtime_skillsforce-includesdiscovery.seed_skill_refs(agents #65) — pinned skills run every cycle. -
Coverage matrix: all 16 personas (6 governance + 10 mission scientists) have
seed_skill_refspopulated; every core maintenance task has ≥1 guaranteed owner; Allen-Institute scientists get broad access with economics permission-gated (agents #66,skills/MAINTENANCE-COVERAGE.md).
6. Seed-corpus relocation gate (PR #2088 carry-forward)
Operator-facing gate-status tracker:
scidex-agents/docs/wave-4-seed-corpus-gate-status.md(iter-70 #80) — current state of each of the 4 preconditions below.
PR #2088 made substrate prefer /home/ubuntu/scidex-agents/seeds with a
fallback to the in-repo seeds/. As of 2026-05-22 that path does not exist;
substrate runs entirely on the in-repo fallback. The “true delete” of
seeds/mimeos + seeds/templates + dropping the fallback must NOT land until:
-
scidex-agents/seeds/{mimeos,templates}/is populated with the corpus. -
That path is deployed + readable in every substrate runtime that seeds (the
scidex.seed.mimeosverb host,scheduler/memory_compactor_registration, and the test suite), orSCIDEX_SEED_CORPUS_DIRis set there. -
The importable
seeds/templates/*/policies/*.pymodules have a stable import home (onlytemplate-kg-extractorhas asrc/mirror today). -
Tests resolve bundles via
SCIDEX_SEED_CORPUS_DIR, not the in-repo path.
Until all four hold, keep the fallback. Deleting early creates a fragile hard dependency and breaks seeding/tests.
7. The norm for new code
-
New agent-performable work is authored as a SKILL.md first; the substrate side is only the minimal verb/hook it calls.
-
New LLM workers/verbs load their prompt from a skill; never hardcode.
-
New tunable thresholds/weights are config a policy skill authors; never module constants.
-
New canned content/personas live in scidex-agents, not substrate.
-
Reviewers should push back on PRs that add hardcoded prompts, magic policy constants, or canned content to substrate.