Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8c024dc
feat(proof): RLM-autonomous topics — no hardcoded topic, no operator …
echobt Sep 15, 2026
7b05a29
fix(proof): four Greptile findings — runtime admission, install-bound…
echobt Sep 15, 2026
f81a1ff
fix(proof): refuse a topic whose rule vector in force is an operator's
echobt Sep 15, 2026
ec13bb4
fix(proof): the hardcode guard counts braces in code, not in text
echobt Sep 15, 2026
e36d340
test(proof): run the structural strip over every product module
echobt Sep 15, 2026
3ce29c8
refactor(guest): the adaptor names no topic in its contract constant
echobt Sep 15, 2026
bf40ca1
test(proof): guard every product module in the challenge stack
echobt Sep 15, 2026
9b55fe7
docs: correct two stale claims about the RLM authorship path
echobt Sep 15, 2026
724ff5b
fix(proof): a hyphenated topic id can name a table
echobt Sep 15, 2026
4977db8
test(proof): a hyphenated topic id installs its migrations end to end
echobt Sep 15, 2026
6b89187
fix(proof): a quoted hyphenated identifier is one name to the guard
echobt Sep 15, 2026
0c1cf1d
feat(proof-admin): topic lifecycle makes a long drive legible
echobt Sep 15, 2026
b2c8fe9
fix(guest): an unresolved task_slice fails closed, always
echobt Sep 15, 2026
858bae2
test(guest): the slice-less pack case, at the shell layer too
echobt Sep 15, 2026
0c7a721
feat(deploy): prove a topic's task selection resolves before the run
echobt Sep 15, 2026
6712e7b
fix(proof-admin): `open` is not published, and the advice now says so
echobt Sep 15, 2026
fa8e78b
fix(proof): refuse a bar nobody can clear; forward every selector
echobt Sep 15, 2026
81b4f8f
docs(proof): disable / enable / seal are implemented, not stubs
echobt Sep 15, 2026
033794d
fix(proof): a stale baseline cannot be sealed, and the advice says so
echobt Sep 15, 2026
f339992
docs(proof): name the disable status code and the unspent nonce
echobt Sep 15, 2026
c5ce127
feat(proof-admin): warn about a degenerate bar before the document is…
echobt Sep 15, 2026
26cb6b1
fix(proof): a leftover topic VM no longer takes Gate 3 off the air
echobt Sep 15, 2026
0c20762
fix(proof): roll back a half-built TAP, and never attach a mismatched vm
echobt Sep 15, 2026
e48bcda
test(proof): drive the tap allocator against a host that changes unde…
echobt Sep 15, 2026
f080035
fix(proof): admit vm boots against host memory, not just a count
echobt Sep 15, 2026
d809e02
fix(proof): size the memory budget by the host's sold RAM, not MemTotal
echobt Sep 15, 2026
3767fe1
docs(proof): the memory guard is not a residency model
echobt Sep 15, 2026
7095d5a
fix(proof): name free memory in the refusal, and pin the tipped retry…
echobt Sep 16, 2026
dbd26cd
fix(proof): a refusal must not advise what cannot work
echobt Sep 16, 2026
81db11a
docs(proof): the RLM authors rules, not migrations or apis
echobt Sep 16, 2026
612bdbd
test(proof): hold the authorship boundary with an allow-list, not a d…
echobt Sep 16, 2026
e204b42
docs(evidence): RLM-authorship evidence pack
echobt Sep 16, 2026
cb14a9f
docs(evidence): pack v2 — live staging evidence, provenance table, be…
echobt Sep 16, 2026
c842598
fix(proof): close the cross-topic SQL namespace collision
echobt Sep 16, 2026
945e143
feat(proof): the RLM authors the whole topic, not just its rules
echobt Sep 16, 2026
1f47297
docs(evidence): pack v3 — the RLM authors the whole topic, and the Ow…
echobt Sep 16, 2026
ef9c35f
fix(proof): close the two cross-topic gaps Greptile found in the SQL …
echobt Sep 16, 2026
11090a9
fix(proof): hand a re-authoring run the set it wrote last time
echobt Sep 16, 2026
4a0444e
fix(proof): reconcile a topic's routes, and make a pin policy restate…
echobt Sep 16, 2026
9bc5590
fix(proof): land the rules and the authored set in one write
echobt Sep 16, 2026
dc6ca1a
fix(proof): write the rule digest in the paired authoring insert
echobt Sep 16, 2026
80bc2cd
docs(evidence): pack v3 final — Greptile green, every finding to its fix
echobt Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,12 @@ jobs:

- name: compose matrix assertions
run: bash deploy/scripts/assert-compose-matrix.sh

- name: harbor runner results gate
run: bash deploy/scripts/assert-harbor-runner-results-emit.sh

- name: proof task-selection gates
run: |
python3 -m unittest discover -s deploy/guest/runners/rlm_fc_in_guest_harbor/tests -q
bash deploy/guest/runners/rlm_fc_in_guest_harbor/tests/test_adaptor.sh
bash deploy/scripts/test_proof_slice_preflight.sh
62 changes: 62 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions bins/proof-admin/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@ async fn run_real(
rlm_raw: bundle.rlm.raw(),
registered_custom: registered,
skip_baseline: args.skip_baseline,
// The RLM's own set, when the drive produced one: it is the
// topic's behavior, and the install applies it instead of the
// bundle's section. Absent means the RLM has not authored yet
// (or authored only rules), and the install applies the
// operator's section with its honest `topic_document`
// provenance — which the publish gate will refuse to open a
// topic on.
authored: driven.as_ref().and_then(|o| o.authored.as_deref()),
},
setup,
)
Expand Down Expand Up @@ -594,6 +602,7 @@ fn install_failure(err: &InstallError, topic_id: &str) -> String {
InstallError::MigrationFailed { .. } => "a migration failed in the database",
InstallError::TooManyMigrations { .. } => "the bundle declares too many migrations",
InstallError::HandlerNotAllowed(_) => "the handler allow-list refused the run backend",
InstallError::Authoring(_) => "the set the topic's own RLM authored was refused",
InstallError::CustomIdNotRegistered { .. } => {
"the topic's custom id is not registered on this host"
}
Expand All @@ -602,6 +611,9 @@ fn install_failure(err: &InstallError, topic_id: &str) -> String {
InstallError::Store(_) => "the rule store refused",
InstallError::Db(_) => "the database refused",
InstallError::Binding(_) => "the signed document's runner binding is malformed",
InstallError::CrossTopicClaim { .. } => {
"a migration names an object another registered topic also claims"
}
};
format!(
"the install stopped: {step}\n {err}\n\n Rollback notes — what is and is not changed:\n \
Expand Down
81 changes: 77 additions & 4 deletions bins/proof-admin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ const EXIT_USAGE: u8 = 2;
long_about = "proof-admin wraps the existing Proof topic publish path (dynamic-topics P0).

Validate a bundle — runs the same acceptance checks POST /v1/admin/proof/topics runs:
proof-admin topic validate --bundle tb4.json --pin config/proof-pin.toml
proof-admin topic validate --bundle topic.json --pin config/proof-pin.toml

Resolve the publish call and host env without touching anything:
proof-admin topic install --bundle tb4.json --env metal --dry-run
proof-admin topic install --bundle topic.json --env metal --dry-run

List the installed topics (a read-only view of proof_topic_version):
proof-admin topic list
Expand Down Expand Up @@ -179,6 +179,18 @@ enum TopicCmd {
},
/// List installed topics: a read-only view of `proof_topic_version`.
List,
/// Where a topic is in its RLM lifecycle, and what it is waiting on.
///
/// Read-only. `topic install --drive-rlm` prints one line and then nothing
/// until the whole run returns — provisioning a VM, the RLM's
/// `propose_rules` job, and a paid baseline can take hours, so this is the
/// read that tells a working run from a stopped one. The durable progress
/// is `proof_lifecycle_event`; a run that died left its last transition
/// here.
Lifecycle {
/// Topic slug, or an alias of one.
topic_id: String,
},
/// Show one topic's newest install: the `proof_topic_install` journal.
InstallLog {
/// Topic slug.
Expand Down Expand Up @@ -273,9 +285,9 @@ enum TopicCmd {
enum AliasCmd {
/// Point an alias at a topic. The topic must be published already.
Set {
/// The alias slug (e.g. `tbench`).
/// The alias slug (a temporary compatibility spelling of the topic).
alias: String,
/// The canonical topic slug it resolves to (e.g. `tb4`).
/// The canonical topic slug it resolves to.
#[arg(long, value_name = "TOPIC_ID")]
topic: String,
},
Expand Down Expand Up @@ -382,6 +394,7 @@ async fn run_topic(opts: &Options, cmd: &TopicCmd) -> Result<(), Failure> {
}
TopicCmd::List => cmd_list(opts).await,
TopicCmd::InstallLog { topic } => cmd_install_log(opts, topic).await,
TopicCmd::Lifecycle { topic_id } => cmd_lifecycle(opts, topic_id).await,
TopicCmd::Show { topic_id } => cmd_show(opts, topic_id).await,
TopicCmd::Alias { cmd } => run_alias(opts, cmd).await,
TopicCmd::Disable {
Expand Down Expand Up @@ -616,6 +629,53 @@ async fn cmd_install_log(opts: &Options, topic_id: &str) -> Result<(), Failure>
install::install_log(opts, topic_id).await
}

/// `topic lifecycle`: read the journal and the provenance, and say what is next.
async fn cmd_lifecycle(opts: &Options, topic_id: &str) -> Result<(), Failure> {
let pool = open_pool(opts).await?;
let report = proof_topic_ops::lifecycle(&pool, topic_id)
.await
.map_err(ops_to_failure)?;
if opts.json {
return print_json(&serde_json::json!({
"topic_id": report.topic_id,
"state": report.state,
"rules_version": report.rules_version,
"rules_source": report.rules_source,
"baseline_rules_version": report.baseline_rules_version,
"history": report.history,
"next": report.next_steps(),
}));
}
println!("topic {} — lifecycle", report.topic_id);
println!(" state {}", report.state);
println!(
" rules_version {}",
report
.rules_version
.map_or_else(|| "-".to_owned(), |v| v.to_string())
);
println!(
" rules_source {}",
dash_if_empty(report.rules_source.as_deref().unwrap_or_default())
);
println!(
" baseline {}",
report.baseline_rules_version.map_or_else(
|| "not measured".to_owned(),
|v| format!("measured (rules v{v})")
)
);
if !report.history.is_empty() {
println!(" history (oldest first)");
for line in &report.history {
println!(" {line}");
}
}
println!();
println!("{}", report.next_steps());
Ok(())
}

/// `topic baseline`: read the measurement and print what to seal.
///
/// The procedure is [`proof_topic_ops::baseline`]; this is the printing.
Expand All @@ -635,6 +695,7 @@ async fn cmd_baseline(opts: &Options, topic_id: &str, pin_path: &Path) -> Result
"holdout_commitment": report.holdout_commitment,
"metrics_commitment": report.metrics_commitment,
"document_status": report.document_status,
"degenerate_bar": report.degenerate_bar,
"next": report.next_steps(),
}));
}
Expand All @@ -648,6 +709,18 @@ async fn cmd_baseline(opts: &Options, topic_id: &str, pin_path: &Path) -> Result
" document_status {}",
status_word(report.document_status)
);
if report.degenerate_bar {
// Printed **before** the commitment, because signing this number
// would only produce a document the seal refuses.
println!();
println!(
"⚠ degenerate bar: {} is zero, and this family scores a relative win",
report.metric_primary
);
println!(" (`challenger >= bar * (1 + epsilon_rel)`), so no miner could ever pass.");
println!(" Sealing this measurement will be refused. Re-run the reference against");
println!(" something that scores, or fix the task selection, then measure again.");
}
println!();
println!("An `open` document must seal this measurement. Its baseline block needs:");
println!(" metrics_commitment {}", report.metrics_commitment);
Expand Down
5 changes: 3 additions & 2 deletions bins/proof-admin/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ pub(crate) async fn cmd_list(opts: &Options) -> Result<(), Failure> {
pub(crate) async fn cmd_show(opts: &Options, topic_id: &str) -> Result<(), Failure> {
let pool = open_pool(opts).await?;
let store = PgRlmStore::new(pool.clone());
// An alias resolves to its canonical slug first, so `show tbench` finds
// `tb4`. Resolution is fail-closed in the store: an alias whose topic has
// An alias resolves to its canonical slug first, so `show <alias>` finds
// the topic it points at. Resolution is fail-closed in the store: an alias
// whose topic has
// no published version resolves to nothing rather than to an empty row.
let resolved = store
.resolve_alias(topic_id)
Expand Down
Loading