fix(curation): kill dev-artefact leak + rename agent honestly

Oracle remediation batch 1 — closing gaps #1 (agent overclaim), #4
(demo-data leak), #5 (raw-ID exposure):

- src/lib/flowCuration.ts: shared isDevArtefact + curatedPublishedFlows
  filter for the whole codebase. Patterns drop rv_/orphan/Atlas F1/MCP
  SDX/Codex Test/sidekick/process_<ts>/backfill/smoke/probe/fixture and
  the EA2_* internal source_contexts.
- src/scenes/Hub.tsx: loadPublishedFlows uses the shared curator
- src/lib/agentTools.ts: list_processes and start_process both use the
  shared curator; raw transaction_id no longer in start reply
- src/state/store.ts: snapshot + live merges curated; resolveDefaultStepId
  guards against scenarios whose defaultStepId references a stale step
- src/scenes/Wizard.tsx: 'Process definition <hex>' confirmation replaced
  with the user-facing process name
- src/scenes/Hub.tsx: start toast no longer shows transaction_id prefix
- src/scenes/Agent.tsx + App.tsx + Landing.tsx: rename Pi -> FlowMaster
  Command Assistant. Welcome message says explicitly that this is a
  deterministic router and the LLM agent + tenant memory are on the
  roadmap. Tab label, hub chip, turn author all rebranded.
- src/scenes/GeoAttendance.tsx: scene re-titled to 'Attendance map ·
  preview' with honest copy explaining the dataset is illustrative until
  the EA2 attendance feed is wired in.
- src/data/synthetic.ts: orphaned from runtime (kept in tree for tests).
  Snapshot now sources only the live-cached EA2 read (scenarios.json),
  filtered through the same curator.

29/29 tests green. No more 'rv test flow 0' / 'orphan' / 'Atlas F1' / raw
32-char hex IDs visible to a buyer.
This commit is contained in:
2026-06-14 13:11:54 +04:00
parent 7ceb5c05bb
commit 8933148719
9 changed files with 109 additions and 48 deletions
+19 -6
View File
@@ -1,7 +1,19 @@
// Global UI state for Mission Control.
import { create } from "zustand";
import { liveScenarios as snapshotLive } from "../data/live";
import { syntheticScenarios } from "../data/synthetic";
import { isDevArtefact } from "../lib/flowCuration";
const syntheticScenarios: any[] = [];
function curateScenarios(rows: ProcessScenario[]): ProcessScenario[] {
return rows.filter((s) => !isDevArtefact({ _key: s.defKey, display_name: s.defName, name: s.defKey }));
}
function resolveDefaultStepId(scenario: ProcessScenario | undefined): string | null {
if (!scenario) return null;
const ids = new Set(scenario.steps.map((s) => s.id));
if (scenario.defaultStepId && ids.has(scenario.defaultStepId)) return scenario.defaultStepId;
return scenario.steps[0]?.id ?? null;
}
import { buildLiveScenariosFromApi } from "../lib/buildScenarios";
import { api, type ApiCall, type Actor } from "../lib/api";
import type { ProcessScenario } from "../data/types";
@@ -110,7 +122,7 @@ interface AppState {
startInstance: (defKey: string, businessSubject?: string) => Promise<string | null>;
}
const SNAPSHOT_SCENARIOS: ProcessScenario[] = [...snapshotLive, ...syntheticScenarios];
const SNAPSHOT_SCENARIOS: ProcessScenario[] = curateScenarios([...snapshotLive, ...syntheticScenarios]);
const initialScenario = SNAPSHOT_SCENARIOS[0];
let toastSeq = 0;
@@ -132,7 +144,8 @@ async function runLiveFetch(
});
}
const { scenarios, workItems, distinctDefs } = await buildLiveScenariosFromApi();
const merged = [...scenarios, ...syntheticScenarios];
const curatedLive = curateScenarios([...scenarios, ...syntheticScenarios]);
const merged = curatedLive.length > 0 ? curatedLive : SNAPSHOT_SCENARIOS;
const first = merged[0];
const currentId = get().scenarioId;
const currentStepId = get().selectedStepId;
@@ -145,13 +158,13 @@ async function runLiveFetch(
liveFetchedAt: Date.now(),
liveLoading: false,
scenarioId: nextScenario?.id ?? currentId,
selectedStepId: stepStillThere ? currentStepId : nextScenario?.defaultStepId ?? null,
selectedStepId: stepStillThere ? currentStepId : resolveDefaultStepId(nextScenario),
});
get().pushToast(
"ok",
prevMode === "live"
? `Refreshed · ${scenarios.length} live + ${syntheticScenarios.length} blueprint scenarios`
: `Live mode · ${scenarios.length} live + ${syntheticScenarios.length} blueprint scenarios`,
? `Refreshed · ${scenarios.length} live processes`
: `Live mode · ${scenarios.length} live processes`,
);
} catch (e) {
set({ liveLoading: false, liveError: (e as Error).message, mode: "snapshot", scenarios: SNAPSHOT_SCENARIOS });