diff --git a/CHALLENGE.md b/CHALLENGE.md
index 62a4e5b..878a0a0 100644
--- a/CHALLENGE.md
+++ b/CHALLENGE.md
@@ -75,9 +75,9 @@ Registration occurs in the top-level document. If `document.modelContext` is una
| `trace_causal_path` | Read-only | Finds and highlights a bounded path through the seven-node conceptual evidence graph without collapsing its branches or evidence classes |
| `open_evidence` | Read-only | Opens a registered artifact, source result, assumption, uncertainty item, or missing-evidence boundary at a chosen semantic depth |
| `compare_policies` | Read-only | Compares up to three registered policies; by default it uses `observable_adaptive` and the calibration-frozen `periodic_local` comparator |
-| `stage_conclusion` | Staging write | Places a supported, qualified, or abstain claim plus one to eight evidence IDs in the pending tray; it cannot approve or commit the claim |
+| `stage_conclusion` | Staging write | Places the artifact's typed `abstain_without_policy_claim` conclusion plus one to eight evidence IDs in the pending tray; free-form agent claims are rejected and it cannot approve or commit the conclusion |
-The first seven tools are annotated read-only. `stage_conclusion` affects only local pending-review state, never the source experiment JSON. No WebMCP tool can approve, reject, or undo a conclusion: those actions are page-only human controls. The agent can explore broadly and prepare a coherent evidence bundle, but it must stop at the judgment boundary.
+The first seven tools are annotated read-only. `stage_conclusion` requires the current state version, refuses to overwrite an existing pending review, and affects only local pending-review state—never the source experiment JSON. No WebMCP tool can approve, reject, edit, or undo a conclusion: those actions are page-only human controls. The agent can explore broadly and prepare a coherent evidence bundle, but it must stop at the judgment boundary.
## Testing
diff --git a/docs/observatory.html b/docs/observatory.html
index 7b7a9ad..0216331 100644
--- a/docs/observatory.html
+++ b/docs/observatory.html
@@ -15,10 +15,10 @@
-
-
-
-
+
+
+
+
Skip to experiment
@@ -97,7 +97,7 @@ WebMCP causal mission con
- Tour
+ Local tour
Reset
diff --git a/docs/webmcp-mission.js b/docs/webmcp-mission.js
index 96d687b..5c0fcb3 100644
--- a/docs/webmcp-mission.js
+++ b/docs/webmcp-mission.js
@@ -6,11 +6,20 @@
const PROJECTION_URL = "data/webmcp-run-projection-v1.json.gz";
const STORAGE_KEY = "gpustack.webmcp.mission.v1";
const MAX_RECEIPTS = 40;
+ const CANONICAL_CONCLUSIONS = Object.freeze({
+ abstain_without_policy_claim: "The observable adaptive controller does not earn a transferable winner claim: it abstained under out-of-distribution stress, and every frozen aggregate gate failed.",
+ });
+ const RECEIPT_ORIGIN_LABELS = Object.freeze({
+ webmcp: "WEBMCP",
+ local_tour: "LOCAL TOUR",
+ human: "HUMAN",
+ });
const REGISTERED_METRICS = Object.freeze([
"final_held_out_nll",
"modeled_completion_seconds",
"inter_site_payload_bytes",
- "abstention_count",
+ "controller_abstentions",
+ "support_envelope_flag_count",
"replayed_tokens",
"divergence_count",
]);
@@ -274,12 +283,15 @@
artifact: {
experiment_id: semantic.experiment_id,
sha256: semantic.artifact_sha256,
- raw_sha256: semantic.full_trace.raw_trace_artifact.artifact_sha256,
families: families.length,
runs: runLedger(semantic).length,
epochs: semantic.full_trace.raw_trace_artifact.epoch_count || 12981,
},
- evidence_boundary: "Measured learning + exact accounting; modeled infrastructure; frontier transfer unresolved.",
+ evidence_boundary: {
+ measured: "learning + exact accounting",
+ modeled: "virtual infrastructure",
+ unresolved: "frontier/facility transfer",
+ },
frozen_result: {
conclusion: semantic.status.conclusion,
all_falsifiers_pass: semantic.status.all_falsifiers_pass,
@@ -288,9 +300,9 @@
},
registered_ids: {
families: families.map((family) => family.family_id),
- policies: [...new Set(runLedger(semantic).map((run) => run.policy_id))],
+ policies: ["observable_adaptive", semantic.comparison.selected_fixed_policy_id],
causal_nodes: screening.causal_graph.nodes.map((node) => node.node_id),
- effect_ids: effects.map((effect) => effect.effect_id),
+ failed_gates: effects.filter((effect) => effect.passed === false).map((effect) => effect.effect_id),
},
pending_proposal: missionState.pending ? missionState.pending.proposalId : null,
suggested_next: "compare_stress_families",
@@ -426,8 +438,8 @@
split: run.split,
seed: run.seed,
epoch_count: run.epoch_count,
- abstention_count: run.abstention_count,
- ood_epoch_count: run.out_of_distribution_epoch_count,
+ controller_abstentions: run.policy_id === "observable_adaptive" ? run.abstention_count : null,
+ support_envelope_flag_count: run.out_of_distribution_epoch_count,
final_held_out_nll: run.final_held_out_nll,
completion_seconds: run.modeled_infrastructure?.completion_seconds,
inter_site_payload_bytes: run.modeled_infrastructure?.inter_site_payload_bytes,
@@ -512,7 +524,7 @@
}
if (rawAliases.has(evidenceId)) {
if (navigate) {
- await bridge.selectView({ experiment: "E001-SC1", depth: "researcher" });
+ await bridge.selectView({ experiment: "E001-SC1", depth: "full_trace" });
scrollToId("semantic-consistency-raw-details");
}
return {
@@ -562,7 +574,8 @@
policy_id: run.policy_id,
final_held_out_nll: run.final_held_out_nll,
completion_seconds: run.modeled_infrastructure?.completion_seconds,
- abstentions: run.abstention_count,
+ controller_abstentions: run.policy_id === "observable_adaptive" ? run.abstention_count : null,
+ support_envelope_flag_count: run.out_of_distribution_epoch_count,
work_contract_violations: run.exact_accounting?.work_contract_violations || [],
};
}
@@ -602,7 +615,7 @@
const ledgerEntry = ledgers.find((entry) => [entry.assumption_id, entry.evidence_id, entry.id].includes(evidenceId));
if (ledgerEntry) {
if (navigate) {
- await bridge.selectView({ experiment: "E001-SC1", depth: "researcher" });
+ await bridge.selectView({ experiment: "E001-SC1", depth: "full_trace" });
scrollToId("semantic-consistency-assumptions");
}
return { evidence_id: evidenceId, kind: "evidence_boundary", entry: ledgerEntry };
@@ -634,7 +647,8 @@
final_held_out_nll: run.final_held_out_nll,
modeled_completion_seconds: run.modeled_infrastructure?.completion_seconds,
inter_site_payload_bytes: run.modeled_infrastructure?.inter_site_payload_bytes,
- abstention_count: run.abstention_count,
+ controller_abstentions: run.policy_id === "observable_adaptive" ? run.abstention_count : null,
+ support_envelope_flag_count: run.out_of_distribution_epoch_count,
replayed_tokens: run.exact_accounting?.replayed_tokens,
divergence_count: run.diverged ? 1 : 0,
};
@@ -646,7 +660,7 @@
const ledger = runLedger(semantic);
const availablePolicies = [...new Set(ledger.map((run) => run.policy_id))];
const policyIds = args.policy_ids || ["observable_adaptive", semantic.comparison.selected_fixed_policy_id];
- const metricIds = args.metric_ids || REGISTERED_METRICS.slice(0, 5);
+ const metricIds = args.metric_ids || REGISTERED_METRICS.slice(0, 6);
const unknownPolicy = policyIds.find((id) => !availablePolicies.includes(id));
const unknownMetric = metricIds.find((id) => !REGISTERED_METRICS.includes(id));
if (unknownPolicy) throw new MissionError("UNKNOWN_POLICY", `No registered policy named ${unknownPolicy}.`, { available_ids: availablePolicies });
@@ -655,10 +669,18 @@
const runs = ledger.filter((run) => run.split === "evaluation" && run.policy_id === policyId);
const metrics = {};
metricIds.forEach((metricId) => {
- const values = runs.map((run) => Number(metricValue(run, metricId))).filter(Number.isFinite);
- metrics[metricId] = ["abstention_count", "divergence_count", "replayed_tokens"].includes(metricId)
- ? values.reduce((sum, value) => sum + value, 0)
- : median(values);
+ const values = runs
+ .map((run) => metricValue(run, metricId))
+ .filter((value) => value !== null && value !== undefined)
+ .map(Number)
+ .filter(Number.isFinite);
+ if (!values.length) {
+ metrics[metricId] = null;
+ } else {
+ metrics[metricId] = ["controller_abstentions", "support_envelope_flag_count", "divergence_count", "replayed_tokens"].includes(metricId)
+ ? values.reduce((sum, value) => sum + value, 0)
+ : median(values);
+ }
});
return { policy_id: policyId, evaluation_runs: runs.length, metrics };
});
@@ -685,27 +707,33 @@
async function stageConclusion(args, context) {
const semantic = await semanticArtifact(context.signal);
- if (args.expected_state_version !== undefined && args.expected_state_version !== missionState.stateVersion) {
+ if (args.expected_state_version !== missionState.stateVersion) {
throw new MissionError("STALE_STATE", `Expected state version ${args.expected_state_version}, but current version is ${missionState.stateVersion}.`, {
current_state_version: missionState.stateVersion,
});
}
- if (args.confidence === "supported" && semantic.status.all_falsifiers_pass !== true) {
- throw new MissionError("EVIDENCE_CONFLICT", "A supported conclusion is not admissible: all four frozen aggregate gates failed. Use qualified or abstain and cite the failed gates.", {
+ if (missionState.pending) {
+ throw new MissionError("PENDING_REVIEW_EXISTS", `Human review is already pending for ${missionState.pending.proposalId}. Approve or reject it before staging another conclusion.`, {
+ pending_proposal: missionState.pending.proposalId,
+ });
+ }
+ if (args.conclusion_code !== semantic.status.conclusion || !CANONICAL_CONCLUSIONS[args.conclusion_code]) {
+ throw new MissionError("EVIDENCE_CONFLICT", `The immutable artifact serializes ${semantic.status.conclusion}; a different conclusion cannot be staged.`, {
frozen_conclusion: semantic.status.conclusion,
- recommended_confidence: "abstain",
});
}
const resolved = [];
for (const evidenceId of args.evidence_ids) {
resolved.push(await resolveEvidence(evidenceId, "researcher", false, context.signal));
}
+ abortIfNeeded(context.signal);
const proposal = {
proposalId: `proposal-${String(missionState.nextProposal).padStart(3, "0")}`,
- claim: args.claim,
+ claim: CANONICAL_CONCLUSIONS[args.conclusion_code],
+ conclusionCode: args.conclusion_code,
evidenceIds: [...args.evidence_ids],
evidenceKinds: resolved.map((entry) => entry.kind),
- confidence: args.confidence,
+ confidence: "abstain",
frozenConclusion: semantic.status.conclusion,
createdAt: new Date().toISOString(),
};
@@ -725,6 +753,7 @@
ok: true,
proposal_id: proposal.proposalId,
status: "pending_human_review",
+ conclusion_code: proposal.conclusionCode,
confidence: proposal.confidence,
evidence_ids: proposal.evidenceIds,
frozen_conclusion: proposal.frozenConclusion,
@@ -751,7 +780,7 @@
try {
abortIfNeeded(context.signal);
const result = await handler(args, context);
- abortIfNeeded(context.signal);
+ if (toolName !== "stage_conclusion") abortIfNeeded(context.signal);
refreshRegistrationStatus();
return result;
} catch (error) {
@@ -827,7 +856,8 @@
item.className = "webmcp-receipt";
item.dataset.status = receipt.status;
const heading = document.createElement("strong");
- heading.textContent = `${receipt.tool.replaceAll("_", " ")} · ${receipt.status}`;
+ const originLabel = RECEIPT_ORIGIN_LABELS[receipt.origin] || String(receipt.origin || "webmcp").toUpperCase();
+ heading.textContent = `${originLabel} · ${receipt.tool.replaceAll("_", " ")} · ${receipt.status}`;
const summary = document.createElement("p");
summary.textContent = receipt.summary;
const metadata = document.createElement("p");
@@ -958,14 +988,13 @@
await invoke("open_evidence", { evidence_id: "adaptive_minus_best_fixed_final_nll", semantic_depth: "researcher" }, { origin: "local_tour" });
await pause(220);
await invoke("stage_conclusion", {
- claim: "The observable adaptive controller does not earn a transferable winner claim: it abstained under out-of-distribution stress, and every frozen aggregate gate failed.",
+ conclusion_code: "abstain_without_policy_claim",
evidence_ids: [
"E6-repeated-membership-loss",
"adaptive_minus_best_fixed_final_nll",
"adaptive_to_best_fixed_inter_site_payload_ratio",
"adaptive_to_best_fixed_modeled_completion_time_ratio",
],
- confidence: "abstain",
expected_state_version: missionState.stateVersion,
}, { origin: "local_tour" });
setStatus("Audit staged · waiting for human approval", "waiting");
@@ -990,6 +1019,10 @@
}
function refreshRegistrationStatus(forcedState) {
+ if (!forcedState && missionState.pending) {
+ setStatus("Audit staged · waiting for human approval", "waiting");
+ return;
+ }
const webmcp = window.GPUStackWebMCP;
if (webmcp?.supported) {
webmcp.ready.then((status) => {
diff --git a/docs/webmcp-tools.js b/docs/webmcp-tools.js
index 179fc15..c31fb78 100644
--- a/docs/webmcp-tools.js
+++ b/docs/webmcp-tools.js
@@ -19,7 +19,7 @@
const MAX_RESULT_CHARS = 1500;
const ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,179}$/;
const SEMANTIC_DEPTHS = ["freshman", "researcher", "full_trace"];
- const CONFIDENCE_LEVELS = ["supported", "qualified", "abstain"];
+ const CONCLUSION_CODES = ["abstain_without_policy_claim"];
class ArgumentError extends Error {
constructor(field, message, expected) {
@@ -137,28 +137,22 @@
stage_conclusion: objectSchema(
{
- claim: {
+ conclusion_code: {
type: "string",
- minLength: 1,
- maxLength: 600,
- description: "Concise proposed conclusion grounded only in the cited evidence IDs.",
+ enum: CONCLUSION_CODES,
+ description: "Typed conclusion serialized by the immutable artifact. Free-form agent claims are not accepted.",
},
evidence_ids: idArraySchema(
- "One to eight evidence IDs that directly support or qualify the proposed claim.",
+ "One to eight evidence IDs that directly support the typed artifact conclusion.",
8,
),
- confidence: {
- type: "string",
- enum: CONFIDENCE_LEVELS,
- description: "Supported, qualified, or abstain. This is evidence confidence, not approval.",
- },
expected_state_version: {
type: "integer",
minimum: 0,
- description: "Optional optimistic-concurrency version returned by a prior tool call.",
+ description: "Required optimistic-concurrency version returned by get_observatory_state.",
},
},
- ["claim", "evidence_ids", "confidence"],
+ ["conclusion_code", "evidence_ids", "expected_state_version"],
),
});
@@ -313,16 +307,12 @@
},
stage_conclusion(args) {
- checkObject(args, ["claim", "evidence_ids", "confidence", "expected_state_version"]);
- const result = {
- claim: cleanString(args.claim, "claim", { required: true, min: 1, max: 600 }),
+ checkObject(args, ["conclusion_code", "evidence_ids", "expected_state_version"]);
+ return {
+ conclusion_code: cleanEnum(args.conclusion_code, "conclusion_code", CONCLUSION_CODES),
evidence_ids: cleanIdArray(args.evidence_ids, "evidence_ids", 8),
- confidence: cleanEnum(args.confidence, "confidence", CONFIDENCE_LEVELS),
+ expected_state_version: cleanInteger(args.expected_state_version, "expected_state_version", 0),
};
- if (args.expected_state_version !== undefined) {
- result.expected_state_version = cleanInteger(args.expected_state_version, "expected_state_version", 0);
- }
- return result;
},
});
@@ -354,7 +344,7 @@
{
name: "inspect_run",
title: "Inspect experiment run",
- description: "Inspect one exact E001-SC1 run and a bounded page of scalar-projected optimizer-commit epochs. Returns mode choice, OOD and abstention state, completion, and event markers while preserving the authoritative raw-trace hash.",
+ description: "Inspect one exact E001-SC1 run and a bounded page of scalar-projected optimizer-commit epochs. Separates support-envelope flags from controller-only abstentions while preserving the authoritative raw-trace hash.",
inputSchema: SCHEMAS.inspect_run,
annotations: READ_ONLY,
},
@@ -375,14 +365,14 @@
{
name: "compare_policies",
title: "Compare registered policies",
- description: "Compare up to three policies from the immutable experiment artifact. Omit IDs for observable_adaptive versus the calibration-frozen periodic_local comparator across registered metrics.",
+ description: "Compare up to three policies from the immutable artifact. Separates controller-only abstentions from cross-policy support-envelope flags; defaults to observable_adaptive versus frozen periodic_local.",
inputSchema: SCHEMAS.compare_policies,
annotations: READ_ONLY,
},
{
name: "stage_conclusion",
title: "Stage evidence conclusion",
- description: "Stage a supported, qualified, or abstain conclusion with explicit evidence IDs in the visible pending tray. This never approves or commits it; only the human can approve or reject it in the page.",
+ description: "Stage the artifact's typed abstain conclusion with explicit evidence IDs and a current state version. Free-form agent claims are rejected. Only the human can approve, edit, or reject it.",
inputSchema: SCHEMAS.stage_conclusion,
annotations: STAGING_WRITE,
},
@@ -485,7 +475,7 @@
try {
const result = await bridge.invoke(toolName, validated, { signal });
- abortIfNeeded(signal);
+ if (toolName !== "stage_conclusion") abortIfNeeded(signal);
return compactResult(toolName, result);
} catch (error) {
abortIfNeeded(signal);
diff --git a/evals/webmcp-evals.json b/evals/webmcp-evals.json
index 511b8b5..059af6b 100644
--- a/evals/webmcp-evals.json
+++ b/evals/webmcp-evals.json
@@ -64,8 +64,8 @@
"functionName": "inspect_run",
"arguments": {
"run_id": "e001-sc1:evaluation:E6-repeated-membership-loss:observable_adaptive",
- "epoch_offset": 0,
- "epoch_limit": 8
+ "epoch_offset": 158,
+ "epoch_limit": 6
}
}
]
@@ -136,14 +136,14 @@
{
"role": "user",
"type": "message",
- "content": "Stage the scientifically warranted conclusion that no transferable winner claim follows for observable_adaptive over periodic_local across the held-out stress families. Cite the decisive E6 family, both E6 policy runs, the failed learning effect, and the compact and raw semantic-consistency artifacts. Mark confidence as abstain. Do not approve or commit it."
+ "content": "Stage the artifact's typed abstain_without_policy_claim conclusion for observable_adaptive versus periodic_local. Cite the decisive E6 family, both E6 policy runs, the failed learning effect, and the compact and raw semantic-consistency artifacts. Use the current observatory state version. Do not approve or commit it."
}
],
"expectedCall": [
{
"functionName": "stage_conclusion",
"arguments": {
- "claim": "No transferable winner claim follows for observable_adaptive over periodic_local across the held-out stress families.",
+ "conclusion_code": "abstain_without_policy_claim",
"evidence_ids": [
"adaptive_minus_best_fixed_final_nll",
"E6-repeated-membership-loss",
@@ -152,9 +152,83 @@
"369bc4e9b32d6e1fcdd8dadc98c830e5ac5179f4a7204a9f5194e22913fdefdf",
"d6321d6fc4c0f71c4f14c2f799eff252348073b3fe5508783f9f078e7f5e9d76"
],
- "confidence": "abstain"
+ "expected_state_version": 1
}
}
]
+ },
+ {
+ "name": "Flagship evidence-court journey",
+ "messages": [
+ {
+ "role": "user",
+ "type": "message",
+ "content": "Audit whether the observable adaptive controller deserves a transferable win over periodic_local. Discover the current IDs, compare every held-out family, inspect the decisive E6 transition, open the failed learning gate, and stage only the artifact's warranted conclusion. Do not approve anything."
+ }
+ ],
+ "expectedCall": [
+ {
+ "functionName": "get_observatory_state",
+ "arguments": {}
+ },
+ {
+ "functionName": "compare_stress_families",
+ "arguments": {}
+ },
+ {
+ "functionName": "inspect_stress_family",
+ "arguments": {
+ "family_id": "E6-repeated-membership-loss",
+ "include_regions": true
+ }
+ },
+ {
+ "functionName": "inspect_run",
+ "arguments": {
+ "run_id": "e001-sc1:evaluation:E6-repeated-membership-loss:observable_adaptive",
+ "epoch_offset": 158,
+ "epoch_limit": 6
+ }
+ },
+ {
+ "functionName": "open_evidence",
+ "arguments": {
+ "evidence_id": "adaptive_minus_best_fixed_final_nll",
+ "semantic_depth": "researcher"
+ }
+ },
+ {
+ "functionName": "stage_conclusion",
+ "arguments": {
+ "conclusion_code": "abstain_without_policy_claim",
+ "evidence_ids": [
+ "E6-repeated-membership-loss",
+ "e001-sc1:evaluation:E6-repeated-membership-loss:observable_adaptive",
+ "adaptive_minus_best_fixed_final_nll"
+ ],
+ "expected_state_version": 1
+ }
+ }
+ ]
+ },
+ {
+ "name": "Resolve an ambiguous win question from evidence",
+ "messages": [
+ {
+ "role": "user",
+ "type": "message",
+ "content": "So, does adaptive actually win here? Check the published experiment before answering; don't infer from the dashboard headline."
+ }
+ ],
+ "expectedCall": [
+ {
+ "functionName": "get_observatory_state",
+ "arguments": {}
+ },
+ {
+ "functionName": "compare_stress_families",
+ "arguments": {}
+ }
+ ]
}
]
diff --git a/tests/test_webmcp_contract.py b/tests/test_webmcp_contract.py
index d513d07..7dc44ac 100644
--- a/tests/test_webmcp_contract.py
+++ b/tests/test_webmcp_contract.py
@@ -46,12 +46,11 @@
"policy_ids": ["observable_adaptive", "periodic_local"],
},
"stage_conclusion": {
- "claim": "The transferable-win claim is not supported across every held-out family; abstain pending stronger evidence.",
+ "conclusion_code": "abstain_without_policy_claim",
"evidence_ids": [
"369bc4e9b32d6e1fcdd8dadc98c830e5ac5179f4a7204a9f5194e22913fdefdf",
"d6321d6fc4c0f71c4f14c2f799eff252348073b3fe5508783f9f078e7f5e9d76",
],
- "confidence": "abstain",
"expected_state_version": 4,
},
}
@@ -73,9 +72,9 @@
"open_evidence": {"evidence_id": "contains a space"},
"compare_policies": {"policy_ids": ["same", "same"]},
"stage_conclusion": {
- "claim": "Unsupported certainty",
- "evidence_ids": [],
- "confidence": "certain",
+ "conclusion_code": "transferable_winner",
+ "evidence_ids": ["E6-repeated-membership-loss"],
+ "expected_state_version": 4,
},
}
@@ -261,9 +260,9 @@ def test_exact_tools_schemas_and_annotations() -> None:
)
assert tools["get_observatory_state"]["inputSchema"]["properties"] == {}
assert tools["stage_conclusion"]["inputSchema"]["required"] == [
- "claim",
+ "conclusion_code",
"evidence_ids",
- "confidence",
+ "expected_state_version",
]
@@ -284,11 +283,11 @@ def test_schema_limits_match_the_grounded_artifact_contract() -> None:
assert schemas["compare_policies"]["properties"]["policy_ids"]["maxItems"] == 3
assert schemas["compare_policies"]["properties"]["metric_ids"]["maxItems"] == 6
assert schemas["stage_conclusion"]["properties"]["evidence_ids"]["maxItems"] == 8
- assert schemas["stage_conclusion"]["properties"]["confidence"]["enum"] == [
- "supported",
- "qualified",
- "abstain",
+ assert schemas["stage_conclusion"]["properties"]["conclusion_code"]["enum"] == [
+ "abstain_without_policy_claim",
]
+ assert "claim" not in schemas["stage_conclusion"]["properties"]
+ assert "confidence" not in schemas["stage_conclusion"]["properties"]
def test_valid_calls_are_normalized_forwarded_and_compact() -> None:
@@ -371,15 +370,16 @@ def test_adapter_documents_late_bound_bridge_and_human_only_approval() -> None:
source = ADAPTER.read_text(encoding="utf-8")
assert "window.GPUStackMission.invoke(toolName, validatedArgs, { signal })" in source
assert "approval remains an explicit page-only human act" in source
- assert "This never approves or commits it" in source
+ assert "Only the human can approve, edit, or reject it" in source
+ assert "Free-form agent claims are rejected" in source
def test_observatory_load_order_and_cache_keys_include_the_bridge_release() -> None:
html = OBSERVATORY_HTML.read_text(encoding="utf-8")
scripts = [
- 'observatory.js?v=20260903.1',
- 'webmcp-tools.js?v=20260903.1',
- 'webmcp-mission.js?v=20260903.1',
+ 'observatory.js?v=20260903.2',
+ 'webmcp-tools.js?v=20260903.2',
+ 'webmcp-mission.js?v=20260903.2',
]
assert all(script in html for script in scripts)
diff --git a/tests/test_webmcp_mission_runtime.mjs b/tests/test_webmcp_mission_runtime.mjs
index f460559..e0557de 100644
--- a/tests/test_webmcp_mission_runtime.mjs
+++ b/tests/test_webmcp_mission_runtime.mjs
@@ -40,7 +40,12 @@ async function makeRuntime() {
version: "test",
async whenReady() {},
getState() {
- return { experiment: "E001-SC1", depth: "freshman", semanticFamily: "", semanticRun: "" };
+ return {
+ experiment: "E001-SC1",
+ depth: "freshman",
+ semanticFamily: "E1-bursty-wan",
+ semanticRun: "e001-sc1:evaluation:E1-bursty-wan:observable_adaptive",
+ };
},
async selectView(patch) {
selections.push(patch);
@@ -118,6 +123,12 @@ test("all eight WebMCP registrations execute against immutable evidence", async
assert.equal(state.artifact.epochs, 12981);
assert.equal(state.frozen_result.abstentions, 104);
assert.equal(state.frozen_result.all_falsifiers_pass, false);
+ assert.deepEqual(Array.from(state.registered_ids.policies), ["observable_adaptive", "periodic_local"]);
+ assert.equal(state.registered_ids.families.length, 6);
+ assert.equal(state.registered_ids.causal_nodes.length, 7);
+ assert.equal(state.registered_ids.failed_gates.length, 4);
+ assert.equal(state.evidence_boundary.unresolved, "frontier/facility transfer");
+ assert.ok(JSON.stringify(state).length <= 1500, `state result exceeded budget: ${JSON.stringify(state).length}`);
assert.equal(state.truncated, undefined);
const families = await execute("compare_stress_families", {});
@@ -136,11 +147,13 @@ test("all eight WebMCP registrations execute against immutable evidence", async
assert.equal(family.truncated, undefined);
const runId = "e001-sc1:evaluation:E6-repeated-membership-loss:observable_adaptive";
- const run = await execute("inspect_run", { run_id: runId, epoch_offset: 0, epoch_limit: 8 });
+ const run = await execute("inspect_run", { run_id: runId, epoch_offset: 158, epoch_limit: 6 });
assert.equal(run.ok, true);
assert.equal(run.run.final_held_out_nll, 1.063824194483459);
+ assert.equal(run.run.controller_abstentions, 24);
+ assert.equal(run.run.support_envelope_flag_count, 24);
assert.equal(run.epoch_page.rows.length, 6);
- assert.equal(run.epoch_page.context_limit_applied, true);
+ assert.equal(run.epoch_page.context_limit_applied, false);
assert.equal(run.source_raw_sha256, "d6321d6fc4c0f71c4f14c2f799eff252348073b3fe5508783f9f078e7f5e9d76");
assert.equal(run.truncated, undefined);
@@ -176,19 +189,22 @@ test("all eight WebMCP registrations execute against immutable evidence", async
assert.equal(policies.ok, true);
assert.equal(policies.policies.length, 2);
assert.equal(policies.comparator_frozen_before_evaluation, true);
+ assert.equal(policies.policies[0].metrics.controller_abstentions, 104);
+ assert.equal(policies.policies[1].metrics.controller_abstentions, null);
+ assert.equal(policies.policies[0].metrics.support_envelope_flag_count, 104);
+ assert.equal(policies.policies[1].metrics.support_envelope_flag_count, 104);
assert.equal(policies.truncated, undefined);
const rejectedOverclaim = await execute("stage_conclusion", {
- claim: "The adaptive policy is a transferable winner.",
+ conclusion_code: "transferable_winner",
evidence_ids: ["E6-repeated-membership-loss"],
- confidence: "supported",
expected_state_version: state.state_version,
});
assert.equal(rejectedOverclaim.ok, false);
- assert.equal(rejectedOverclaim.code, "EVIDENCE_CONFLICT");
+ assert.equal(rejectedOverclaim.code, "INVALID_ARGUMENT");
const staged = await execute("stage_conclusion", {
- claim: "The artifact supports abstaining from any transferable winner claim.",
+ conclusion_code: "abstain_without_policy_claim",
evidence_ids: [
"adaptive_minus_best_fixed_final_nll",
"E6-repeated-membership-loss",
@@ -197,11 +213,11 @@ test("all eight WebMCP registrations execute against immutable evidence", async
"369bc4e9b32d6e1fcdd8dadc98c830e5ac5179f4a7204a9f5194e22913fdefdf",
"d6321d6fc4c0f71c4f14c2f799eff252348073b3fe5508783f9f078e7f5e9d76",
],
- confidence: "abstain",
expected_state_version: state.state_version,
});
assert.equal(staged.ok, true);
assert.equal(staged.status, "pending_human_review");
+ assert.equal(staged.conclusion_code, "abstain_without_policy_claim");
assert.equal(staged.truncated, undefined);
assert.equal(runtime.window.GPUStackMission.getState().pending.proposalId, staged.proposal_id);
assert.ok(runtime.selections.length >= 5);
@@ -222,17 +238,23 @@ test("adapter rejects invalid and stale calls without mutating approval state",
assert.equal(unknown.code, "UNKNOWN_FAMILY");
const staged = await execute("stage_conclusion", {
- claim: "Abstain from a transferable claim.",
+ conclusion_code: "abstain_without_policy_claim",
evidence_ids: ["adaptive_minus_best_fixed_final_nll"],
- confidence: "abstain",
expected_state_version: 1,
});
assert.equal(staged.ok, true);
+ const occupied = await execute("stage_conclusion", {
+ conclusion_code: "abstain_without_policy_claim",
+ evidence_ids: ["adaptive_minus_best_fixed_final_nll"],
+ expected_state_version: 2,
+ });
+ assert.equal(occupied.ok, false);
+ assert.equal(occupied.code, "PENDING_REVIEW_EXISTS");
+
const stale = await execute("stage_conclusion", {
- claim: "A second proposal based on stale state.",
+ conclusion_code: "abstain_without_policy_claim",
evidence_ids: ["adaptive_minus_best_fixed_final_nll"],
- confidence: "abstain",
expected_state_version: 1,
});
assert.equal(stale.ok, false);