Repository navigation
Commit 1b306ea
Add proposal publication, Tier 2 proposals, the engine's self-declaration and the meta-benchmark adapter
Meta-improvement engine P4 (design §9.2, §11.1, §11.2).
improve/publish.py: the engine holds no GitHub token, so a proposal leaves
it as an action file (open / update / close) in an outbox directory that
the maintainer routine's `propose` command picks up and answers with an
ack; the routine also observes each proposal issue (human comments,
`maintainer: hold`, referencing pull requests, closure) into an inbox the
engine reads back. Rule 4: evidence is cited only by record id and blob
hash; every excerpt is drawn verbatim from the redacted blob (<= 20 lines,
long lines cut to a prefix) so a reader can recover it from the hash, and
lint_proposal refuses anything else (unresolvable ids, a Tier 1 proposal
with fewer than three records, a Tier 2 proposal without a stage S1-S9 or
a loss, an excerpt that is not a line of its blob, a credential pattern
left in the body); a refused proposal is recorded and never published.
The issue body follows the fixed template (claim, stage or lint, loss,
evidence, suggested pre-registration with the register command, ledger
link, marker) and carries improve:<workflow> / improve:tier<n> /
improve:<state> labels. plan/publish write each action once (a pending
action waits for its ack for seven days), skip workflows on hold (rule 5:
lints and experiments continue) and record every write. sync applies
acks (issue url, published state; a dry-run ack from a routine still in
shadow publishes nothing) and observations: a human comment is a channel
touch, a hold comment sets a channel hold the next observation without it
releases, a merged referencing pull request lands the proposal, a closure
on GitHub closes it. A landed Tier 1 proposal's issue closes only once a
later cycle shows the lint's defect rate below the rate at opening.
Steps: improve.mode publishes the run mode and item key; improve.sync
(read) reads the outbox back; improve.publish is the cycle's only outward
write, declared risk="push" and gated like pr.post_review — without the
task's post intent it only previews, with it but ALLOW_POST=0 it is a dry
run, with both it writes the outbox (blocked loudly when no outbox is
configured); the executor's shadow refusal stops it before it runs. The
forensics step now opens one Tier 2 proposal per punch-list stage with a
loss (never S0/S10), each with a suggested pre-registration (metric, the
items with gold, the item count the historical sd requires, what the
arm's fingerprint should cover for that stage); descriptive-only
workflows get proxy proposals without a suggestion. Tier 1 proposals
record the rate at opening. Settings: improve_outbox_dir,
improve_proposal_repo, improve_meta_dir.
Self-enrolment (§11.2): improve/workflows/workflow-improve.yaml declares
the engine's own forensics role (`workflow-improve.improve.forensics`,
item `{improve_item}`) with a fingerprint over the forensics, lint,
statistics and adapter sources and the resolved models. With
`--task-param meta_case=<case>` the playbook runs only that step over one
frozen meta case (every cycle step is gated off) and writes a `meta_eval`
outcome: the engine's stage labels beside the human ones, agreement,
Cohen's kappa and the Tier 1 catalogue's recall on the injected lint
samples. adapters/meta_bench.py scores it: hit when the label agrees,
disputed when the families disagreed, unlabeled for S0; no judge is
involved (human_labelled), so the cross-family rule holds by
construction. experiments.run stages a self-experiment item by copying
the case and the lint samples into the shadow directory (nothing
narrative: no doc/, no judgments), runs the copilot child on it through
IMPROVE_META_DIR, needs no judge for a human-labelled adapter and picks
the unit enrolled in the experiment's workflow rather than the child's
last unit. CLI: improve publish [--dry-run], improve sync, improve meta
bench.
Records that forensics writes while attributing keep the caller's unit
item when one is bound (the investigated unit and item are named in the
result), so the engine's own unit over a meta case is keyed by the case.
Review round 1 (gpt-6.1-sol-high) fixes: the self-experiment child names
its repo (`--task-param repo=meta`, the one alias its REPO_PATHS exposes)
so run_playbook accepts it instead of falling back to default_repo, and
shadow_env now writes REPO_PATHS in the JSON form Settings parses (the
`alias=path` form failed every real shadow child at Settings load); a
`maintainer: hold` is remembered per proposal and the workflow's channel
hold is aggregated over its proposals, so observing an unheld proposal
never releases a hold another proposal's issue still carries (an
operator's own hold is never touched by the channel); the Tier 1 rate
check skips cycles whose units were all quarantined, so a cycle that
measured nothing cannot verify a landed proposal.
Review round 2 fixes: a private-key block is redacted whole (header to
END, or to the end of the text when cut), never just its header; a
publication (plan, action files, pending notes) runs under one lock per
outbox, so concurrent publishers cannot emit two actions for one proposal;
an ack is applied only when its action id is the proposal's pending action
— a delayed answer to a superseded action is consumed as stale and may
only add the issue url it created when none is known, never clear the
newer pending action or rewrite the published state.
Review round 3 fix: sync applies acks under the publisher's lock, so the
pending-action check and its clearing cannot interleave with a publisher
retrying that action (a stale ack could otherwise clear the newer pending
id and let a further publish duplicate it).
Tests: test_improve_p4.py — citation excerpts (verbatim, redacted,
recoverable, refused when tampered), the linter's refusals and the
template, the outbox round trip (once per action, acks, dry-run acks,
failures, touches, holds and their release, landing, the Tier 1 rate
check, refuted -> closed), the double-gated publish step and the shadow
refusal, Tier 2 proposals from the punch list, the meta case run and
adapter, a self-experiment adjudicated without a judge, the meta-mode
playbook run as the engine's own unit, the real CLI entry for a shadow
child (repo alias accepted, plan printed), a hold that survives another
proposal's silence, a fully quarantined cycle, a whole-key redaction, four
concurrent publishers, a stale ack after a retry, sync blocked behind a
publisher's lock, the CLI. Full suite green except
test_mcp.py (host mcp 2.x).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>1 parent 834d554 commit 1b306ea
18 files changed
Lines changed: 2023 additions & 52 deletions
File tree
- doc/architecture/SPEC
- eval/dataset/meta
- playbooks
- src/infermatrix_copilot
- engine/steps
- improve
- adapters
- workflows
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
33 | 36 | | |
34 | 37 | | |
35 | 38 | | |
36 | 39 | | |
37 | 40 | | |
38 | | - | |
| 41 | + | |
39 | 42 | | |
40 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
41 | 46 | | |
42 | 47 | | |
43 | | - | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
44 | 51 | | |
45 | 52 | | |
46 | 53 | | |
47 | 54 | | |
48 | | - | |
| 55 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
5 | 11 | | |
6 | | - | |
| 12 | + | |
7 | 13 | | |
8 | 14 | | |
9 | 15 | | |
10 | | - | |
| 16 | + | |
11 | 17 | | |
12 | 18 | | |
13 | 19 | | |
14 | 20 | | |
15 | | - | |
16 | | - | |
17 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
18 | 26 | | |
19 | | - | |
| 27 | + | |
| 28 | + | |
20 | 29 | | |
21 | 30 | | |
22 | | - | |
| 31 | + | |
| 32 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
586 | 586 | | |
587 | 587 | | |
588 | 588 | | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
589 | 599 | | |
590 | 600 | | |
591 | 601 | | |
| |||
0 commit comments