feat(viz): kind-specific choreography and a finished mission you can read
ci / gates (push) Failing after 6s
ci / rust (push) Skipped
ci / frontend (push) Skipped
ci / e2e (push) Skipped
ci / publish (push) Skipped

Security: the pawns already orbited their destination, so homing them at
the security station gave circling for free. This adds the radial
press-and-retreat — an agent closing on the target and backing off reads
as probing it, where a fixed radius reads as waiting — and holds the
stochastic target release while probing, or the circling breaks up into
stray trips that look like distraction rather than a scan.

Findings are `mission_tasks` rows, one orb each, popped once. There is
deliberately no severity anywhere in the path: the scanner keeps
severity, file and line as substrings inside `title`, so a severity
parsed out of prose and rendered as an orb's RADIUS would be the picture
asserting a measurement the data never contained. Count only.

Benchmarks annotate the station, as text. `delta` has no schema —
compute_delta emits `{kind:"opaque"}` whenever the before/after metrics
were not structurally comparable, which is most drivers. The server
formats the shape it can parse and COUNTS the rest; an unparseable driver
reports "3 sample(s)" rather than an invented improvement, and an opaque
delta says nothing at all.

The finished map: the live label rule gates service/event nodes on
`heat > 0.12`, which is exactly backwards once everything has cooled — a
static map would be unlabelled dots. Frozen, the 25 most-touched nodes
label regardless of heat, phase stations carry a second line counting
what they produced, and the camera is released ONCE so it frames the
result even if the user panned during the run.

Every count in a caption is read off the drawn scene rather than a
parallel tally, so the words and the picture cannot disagree.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-08-11 09:22:16 -07:00
co-authored by Claude Opus 5
parent 9e61e3ba35
commit f8438c32ea
4 changed files with 433 additions and 8 deletions
+214
View File
@@ -283,6 +283,137 @@ async fn world_acts(pool: &PgPool, ws: WorkspaceId, only: Option<Uuid>, after: i
.collect()
}
/// One security finding, as the scanner recorded it.
struct FindingRow {
mission_id: String,
phase_id: String,
task_id: String,
title: String,
}
/// Findings raised by a security phase.
///
/// They are `mission_tasks` rows — the scanner's own store — not a new table.
/// There is deliberately NO severity field here: severity, file and line are
/// substrings inside `title` (see `security_scan.rs`), and a severity parsed
/// out of prose and then encoded as an orb's RADIUS would be an invented fact
/// rendered as a measurement. The title is shown as written.
async fn world_findings(pool: &PgPool, ws: WorkspaceId, only: Option<Uuid>) -> Vec<FindingRow> {
let rows = sqlx::query(
"SELECT t.mission_id::text AS mission_id,
t.phase_id::text AS phase_id,
t.id::text AS task_id,
t.title
FROM mission_tasks t
JOIN mission_phases p ON p.id = t.phase_id
JOIN missions m ON m.id = t.mission_id
WHERE m.workspace_id = $1
AND p.kind = 'security_scan'
AND ( m.status = 'running'
OR ( m.status IN ('completed', 'failed')
AND m.completed_at > now() - interval '24 hours' ) )
AND ($2::uuid IS NULL OR m.id = $2)
LIMIT 300",
)
.bind(ws.as_uuid())
.bind(only)
.fetch_all(pool)
.await
.unwrap_or_default();
rows.into_iter()
.map(|r| FindingRow {
mission_id: r.get::<String, _>("mission_id"),
phase_id: r.get::<String, _>("phase_id"),
task_id: r.get::<String, _>("task_id"),
title: r.get::<String, _>("title"),
})
.collect()
}
/// A benchmark phase's result, summarised.
struct BenchRow {
mission_id: String,
phase_id: String,
note: String,
}
/// Benchmark deltas, as an annotation on the phase — not as nodes.
///
/// `delta` is a `Record<string, unknown>` with no schema: `compute_delta`
/// produces `{kind:"bencher_diff", samples:[…]}` when the before/after shapes
/// are structurally comparable, and `{kind:"opaque"}` when they are not. Only
/// the shape that can be parsed is formatted; the rest is COUNTED, never
/// guessed at, so a driver whose output we do not understand reports "3
/// samples" rather than an invented improvement.
async fn world_benchmarks(pool: &PgPool, ws: WorkspaceId, only: Option<Uuid>) -> Vec<BenchRow> {
let rows = sqlx::query(
"SELECT DISTINCT ON (b.phase_id)
b.mission_id::text AS mission_id,
b.phase_id::text AS phase_id,
b.delta
FROM benchmark_snapshots b
JOIN missions m ON m.id = b.mission_id
WHERE m.workspace_id = $1
AND b.delta IS NOT NULL
AND ( m.status = 'running'
OR ( m.status IN ('completed', 'failed')
AND m.completed_at > now() - interval '24 hours' ) )
AND ($2::uuid IS NULL OR m.id = $2)
ORDER BY b.phase_id, b.iteration DESC",
)
.bind(ws.as_uuid())
.bind(only)
.fetch_all(pool)
.await
.unwrap_or_default();
rows.into_iter()
.filter_map(|r| {
let note = benchmark_note(&r.get::<serde_json::Value, _>("delta"))?;
Some(BenchRow {
mission_id: r.get::<String, _>("mission_id"),
phase_id: r.get::<String, _>("phase_id"),
note,
})
})
.collect()
}
/// One line describing a benchmark delta, or `None` if there is nothing
/// truthful to say about it.
fn benchmark_note(delta: &serde_json::Value) -> Option<String> {
let samples = delta.get("samples").and_then(|s| s.as_array())?;
if samples.is_empty() {
return None;
}
let mut improved = 0usize;
let mut regressed = 0usize;
// Best (most negative) percent change, since that is the one claim the
// shape actually supports.
let mut best: Option<f64> = None;
for s in samples {
match s.get("direction").and_then(|d| d.as_str()) {
Some("improved") => improved += 1,
Some("regressed") => regressed += 1,
// Counted in the total but claimed for neither side.
_ => {}
}
if let Some(pct) = s.get("delta_pct").and_then(serde_json::Value::as_f64) {
best = Some(best.map_or(pct, |b: f64| b.min(pct)));
}
}
let mut parts = vec![format!("{} sample(s)", samples.len())];
if improved > 0 {
parts.push(format!("{improved} faster"));
}
if regressed > 0 {
parts.push(format!("{regressed} slower"));
}
if let Some(b) = best.filter(|b| *b < 0.0) {
parts.push(format!("best {:.1}%", b));
}
Some(parts.join(", "))
}
/// Agents that execute a phase of this kind, via the purposes the phase runner
/// itself uses. Returns empty for a teamless (microVM) mission.
async fn phase_agents(
@@ -612,6 +743,11 @@ pub async fn world_live(
// opening a finished mission would replay an hour of tool calls as a
// burst storm and read as a mission that just did all of it at once.
let mut event_cursor: i64 = -1;
// Findings already announced. A finding is raised once.
let mut last_finding: HashSet<String> = HashSet::new();
// Last benchmark summary per phase; a looping phase produces a new one.
let mut last_bench: std::collections::HashMap<String, String> =
std::collections::HashMap::new();
// Audit-log cursor for edge-initiated inter-agent events (delegation,
// A2A) that bypass the run loop. -1 until seeded on the first pass.
let mut audit_cursor: i64 = -1;
@@ -792,6 +928,42 @@ pub async fn world_live(
);
}
// Benchmark results, as an annotation on the station. Re-emitted
// only when the summary changes: a phase that loops produces a new
// snapshot per iteration, and that IS news.
for b in world_benchmarks(&pool, ws, only_mission).await {
if last_bench.get(&b.phase_id).map(|n| n == &b.note).unwrap_or(false) {
continue;
}
last_bench.insert(b.phase_id.clone(), b.note.clone());
yield sse(
"mission.benchmark",
json!({
"missionId": b.mission_id,
"phaseId": b.phase_id,
"note": b.note,
}),
);
}
// Findings, once each, hanging off the security station. Same rule
// as files: a finding is a fact that was raised once, and
// re-sending it would pop the orb again on every poll.
for f in world_findings(&pool, ws, only_mission).await {
if !last_finding.insert(f.task_id.clone()) {
continue;
}
yield sse(
"mission.finding",
json!({
"missionId": f.mission_id,
"phaseId": f.phase_id,
"findingId": f.task_id,
"title": f.title,
}),
);
}
// Structured activity — the motion channel. Tool calls and file
// touches recorded at the source by the container tap and the
// microVM `PostToolUse` hook. Never parsed from prose: a tool name
@@ -1110,6 +1282,48 @@ mod mission_feed_tests {
);
}
/// A benchmark delta is described only as far as its shape allows.
///
/// `compute_delta` emits `{kind:"opaque"}` whenever the before/after
/// metrics were not structurally comparable — which is most drivers. The
/// temptation is to say something anyway; the result would be a performance
/// claim the picture makes and the data does not support.
#[test]
fn a_benchmark_is_described_only_as_far_as_its_shape_allows() {
use serde_json::json;
assert_eq!(
super::benchmark_note(&json!({
"kind": "bencher_diff",
"samples": [
{"name": "a", "delta_pct": -12.5, "direction": "improved"},
{"name": "b", "delta_pct": 3.0, "direction": "regressed"},
// No direction and no percentage: counted, claimed for
// neither side.
{"name": "c"},
],
}))
.as_deref(),
Some("3 sample(s), 1 faster, 1 slower, best -12.5%")
);
// Nothing comparable happened, so nothing is said.
assert_eq!(
super::benchmark_note(&json!({ "kind": "opaque", "note": "not comparable" })),
None
);
assert_eq!(
super::benchmark_note(&json!({ "kind": "bencher_diff", "samples": [] })),
None
);
// Everything got slower: no "best" claim at all.
assert_eq!(
super::benchmark_note(&json!({
"samples": [{"name": "a", "delta_pct": 8.0, "direction": "regressed"}],
}))
.as_deref(),
Some("1 sample(s), 1 slower")
);
}
/// Agent→phase attribution must come from the runner's own mapping.
#[test]
fn phase_attribution_reuses_the_runners_mapping() {