A skill that gets better with use is the claim. Without a gate it is just a skill
that changes with use, which is the same mechanism pointed at a worse outcome.
skill_outcomes — what happened when a version actually ranskill_candidates — proposed edits and their fatepromotion_decisions — the arithmetic behind every promote and rejectpropose() publishes a candidate as a pre-release version. gate_promotion()
decides. degradation_check() closes the loop from production telemetry.
A candidate inherits its parent's eval suite. It does not carry its own. An
optimizer that could ship its own tests could weaken them and pass.
The eval suite travels onto the promoted version too. Without this a skill
improves exactly once, because the next candidate proposed from it has nothing to
be gated against. This was a real defect: 131 tests passed while it was broken,
because every test proposed from a freshly published 1.0.0 and none exercised a
second generation. Covered now by test_skill_can_compound_more_than_once.
A pre-release sorts BELOW its release in _version_key, so resolve() cannot
hand a client an unpromoted candidate even while one is pending.
A tie is rejected. Equal evidence is not evidence of improvement, and churning
the live version for nothing costs the audit trail its meaning. No evals at all
raises rather than defaulting to allow.
Yanking is the whole rollback. Because resolve() returns the highest
non-yanked version, yanking a regression restores its predecessor. There is no
second rollback path to keep correct or to let drift out of sync.
baseline resolve: 1.0.0
1.0.0 rate: (1.0, 40)
resolve while pending: 1.0.0
gate better: promoted
resolve after promote: 1.1.0
gate worse: rejected
worse candidate yanked: True
resolve unchanged: 1.1.0
promoted rate: (0.0, 40)
degradation_check: True
resolve after rollback: 1.0.0
This half is model-free. The arithmetic, the gate, the versioning and the rollback
need no LLM. Only generating candidate edits does, and that is not built here.
Tenant isolation stays strict: one client's usage does not alter another client's
skill.