mod support;
use serde_json::Value;
use support::git_repo::GitRepo;
use support::inspect::{Inspector, capture, representative_store, urlencode};
use support::shore_env;
fn captured_event_id(repo: &std::path::Path) -> String {
pointbreak::session::read_events(repo)
.unwrap()
.iter()
.find(|e| e.event_type == pointbreak::session::event::EventType::WorkObjectProposed)
.expect("a captured review unit")
.event_id
.as_str()
.to_owned()
}
fn occurred_instant(entry: &Value) -> i64 {
let raw = entry["occurredAt"]
.as_str()
.expect("occurredAt is a string");
pointbreak::session::parse_event_instant(raw)
.unwrap_or_else(|| panic!("occurredAt is not a legal instant: {raw}"))
}
fn entries_of_type<'a>(history: &'a Value, event_type: &str) -> Vec<&'a Value> {
history["entries"]
.as_array()
.expect("entries is an array")
.iter()
.filter(|e| e["eventType"] == event_type)
.collect()
}
fn served_asset_inspector() -> (GitRepo, Inspector) {
let repo = GitRepo::new();
let inspector = Inspector::spawn(repo.path());
(repo, inspector)
}
#[test]
fn inspector_harness_serves_history_for_minimal_store() {
let repo = GitRepo::new();
repo.write("src/lib.rs", "pub fn value() -> u32 { 1 }\n");
repo.commit_all("base");
repo.write("src/lib.rs", "pub fn value() -> u32 { 2 }\n");
capture(repo.path());
let inspector = Inspector::spawn(repo.path());
let history = inspector.get_json("/api/history");
assert_eq!(history["schema"], "pointbreak.inspect-history");
let entries = history["entries"].as_array().unwrap();
assert_eq!(entries.len(), 2);
let event_types: Vec<&str> = entries
.iter()
.filter_map(|entry| entry["eventType"].as_str())
.collect();
assert!(
event_types.contains(&"work_object_proposed"),
"{event_types:?}"
);
assert!(
event_types.contains(&"revision_ref_associated"),
"{event_types:?}"
);
}
#[test]
fn api_attention_serves_projection() {
let store = representative_store();
let added = support::shore([
"assessment",
"add",
"--repo",
store.repo.path().to_str().unwrap(),
"--track",
"agent:second",
"--assessment",
"needs-changes",
"--summary",
"second opinion",
]);
assert!(
added.status.success(),
"stderr:\n{}",
String::from_utf8_lossy(&added.stderr)
);
let inspector = Inspector::spawn(store.repo.path());
let attention = inspector.get_json("/api/attention");
assert_eq!(attention["schema"], "pointbreak.inspect-attention");
assert!(
attention["eventSetHash"]
.as_str()
.unwrap()
.starts_with("sha256:")
);
let items = attention["items"].as_array().unwrap();
let kinds: Vec<&str> = items
.iter()
.map(|item| item["kind"].as_str().unwrap())
.collect();
assert!(kinds.contains(&"open_input_request"), "kinds: {kinds:?}");
assert!(kinds.contains(&"failed_validation"), "kinds: {kinds:?}");
assert!(kinds.contains(&"ambiguous_assessment"), "kinds: {kinds:?}");
for item in items {
let obj = item.as_object().unwrap();
assert!(
!obj.contains_key("stage"),
"item carries a stage key: {item}"
);
for (key, value) in obj {
if let Some(text) = value.as_str() {
assert!(
!matches!(text, "reviewing" | "deciding" | "done"),
"item field {key} carries a lifecycle-stage value: {item}"
);
}
}
}
let failed = items
.iter()
.find(|item| item["kind"] == "failed_validation")
.expect("a failed_validation item");
let status = failed["status"].as_str().unwrap();
assert!(
status == "failed" || status == "errored",
"failed_validation status must be failed/errored, got {status}"
);
}
#[test]
fn api_history_returns_chronological_typed_summaries() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let history = inspector.get_json("/api/history");
assert_eq!(history["schema"], "pointbreak.inspect-history");
assert!(
history["eventSetHash"]
.as_str()
.unwrap()
.starts_with("sha256:")
);
let entries = history["entries"].as_array().unwrap();
assert_eq!(history["eventCount"], 8);
assert_eq!(history["historyCount"], 8);
assert_eq!(entries.len(), 8, "one entry per recorded event");
let stamps: Vec<i64> = entries.iter().map(occurred_instant).collect();
assert!(
stamps.windows(2).all(|w| w[0] <= w[1]),
"entries must be sorted by occurredAt asc: {stamps:?}"
);
for entry in entries {
assert!(entry["eventId"].as_str().unwrap().starts_with("evt:"));
assert!(
entry["payloadHash"]
.as_str()
.unwrap()
.starts_with("sha256:")
);
assert!(
entry["writer"]["actorId"]
.as_str()
.unwrap()
.starts_with("actor:")
);
if entry["eventType"] == "work_object_proposed" {
assert_eq!(entry["summary"]["kind"], "revision_captured");
} else {
assert_eq!(entry["summary"]["kind"], entry["eventType"]);
}
}
let observations = entries_of_type(&history, "review_observation_recorded");
assert_eq!(observations.len(), 1);
let obs = observations[0];
assert_eq!(obs["summary"]["title"], "Observed change");
assert_eq!(obs["summary"]["target"]["kind"], "range");
assert_eq!(obs["summary"]["target"]["filePath"], "src/lib.rs");
assert_eq!(obs["summary"]["target"]["startLine"], 2);
assert_eq!(obs["summary"]["target"]["endLine"], 2);
assert_eq!(obs["trackId"], "agent:codex");
assert_eq!(obs["subject"]["revisionId"], store.revision_id.as_str());
}
#[test]
fn api_units_lists_captured_unit_with_counts_and_target_display() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let units = inspector.get_json("/api/revisions");
assert_eq!(units["schema"], "pointbreak.inspect-revisions");
assert_eq!(units["revisionCount"], 1);
let entry = &units["entries"][0];
assert_eq!(entry["revisionId"], store.revision_id.as_str());
assert_eq!(entry["snapshotId"], store.snapshot_id.as_str());
assert!(entry["targetDisplay"]["label"].is_string());
assert_eq!(entry["targetDisplay"]["pathPrivate"], true);
assert!(entry["targetDisplay"]["head"]["commitOidShort"].is_string());
}
#[test]
fn api_units_include_additive_overview_summary() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let units = inspector.get_json("/api/revisions");
let revision = inspector.get_json(&format!("/api/revisions/{}", urlencode(&store.revision_id)));
let entry = &units["entries"][0];
assert_eq!(entry["revisionId"], store.revision_id.as_str());
assert_eq!(entry["snapshotId"], store.snapshot_id.as_str());
assert!(entry["target"].is_object());
assert!(entry["base"].is_object());
assert!(entry["targetDisplay"].is_object());
let overview = &entry["overview"];
assert_eq!(overview["currentAssessment"]["status"], "resolved");
assert_eq!(overview["currentAssessment"]["assessment"], "accepted");
let attention = &overview["attention"];
assert_eq!(attention["unassessed"], false);
assert_eq!(attention["acceptedWithFollowUp"], false);
assert_eq!(attention["openInputRequestCount"], 1);
assert_eq!(attention["failedValidationCount"], 1);
assert_eq!(attention["erroredValidationCount"], 0);
assert_eq!(attention["staleFactCount"], 0);
let counts = &overview["counts"];
assert_eq!(counts["files"], revision["summary"]["fileCount"]);
assert_eq!(counts["rows"], revision["summary"]["rowCount"]);
assert_eq!(
counts["observations"],
revision["summary"]["observationCount"]
);
assert_eq!(
counts["inputRequests"],
revision["summary"]["inputRequestCount"]
);
assert_eq!(
counts["assessments"],
revision["summary"]["assessmentCount"]
);
assert_eq!(
counts["validationChecks"],
revision["summary"]["validationCheckCount"]
);
let latest_activity = &overview["latestActivity"];
if !latest_activity.is_null() {
assert!(latest_activity["kind"].is_string());
assert!(latest_activity["title"].is_string());
assert!(latest_activity["at"].is_string());
}
}
#[test]
fn api_revisions_cache_serves_fresh_payload_after_store_writes() {
let repo = GitRepo::new();
repo.write("src/lib.rs", "pub fn value() -> u32 { 1 }\n");
repo.commit_all("base");
repo.write("src/lib.rs", "pub fn value() -> u32 { 2 }\n");
let first_revision = capture(repo.path());
let inspector = Inspector::spawn(repo.path());
let initial = inspector.get_json("/api/revisions");
assert_eq!(initial["revisionCount"], 1);
assert_eq!(initial["entries"][0]["revisionId"], first_revision.as_str());
let repeat = inspector.get_json("/api/revisions");
assert_eq!(repeat, initial);
repo.write("src/lib.rs", "pub fn value() -> u32 { 3 }\n");
let second_revision = capture(repo.path());
let refreshed = inspector.get_json("/api/revisions");
assert_eq!(refreshed["revisionCount"], 2);
let ids: Vec<&str> = refreshed["entries"]
.as_array()
.expect("entries is an array")
.iter()
.filter_map(|entry| entry["revisionId"].as_str())
.collect();
assert!(ids.contains(&first_revision.as_str()), "{ids:?}");
assert!(ids.contains(&second_revision.as_str()), "{ids:?}");
assert_ne!(refreshed["eventSetHash"], initial["eventSetHash"]);
}
#[test]
fn api_snapshot_returns_snapshot_scoped_artifact() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let snapshot = inspector.get_json(&format!("/api/snapshots/{}", urlencode(&store.snapshot_id)));
assert!(
snapshot["contentHash"]
.as_str()
.unwrap()
.starts_with("sha256:")
);
assert!(snapshot.get("revisionId").is_none());
assert!(snapshot.get("target").is_none());
assert!(snapshot.get("base").is_none());
assert!(snapshot.get("source").is_none());
assert!(snapshot.get("worktreeRootRedacted").is_none());
let files = snapshot["snapshot"]["files"].as_array().unwrap();
assert!(!files.is_empty());
let hunks = files[0]["hunks"].as_array().unwrap();
assert!(!hunks.is_empty());
}
#[test]
fn api_freshness_exposes_the_event_count_marker() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let history = inspector.get_json("/api/history");
let freshness = inspector.get_json("/api/freshness");
assert_eq!(freshness["schema"], "pointbreak.inspect-freshness");
assert!(freshness["eventCount"].is_u64());
assert_eq!(freshness["eventCount"], history["eventCount"]);
assert!(freshness.get("eventSetHash").is_none());
assert!(freshness.get("diagnosticCount").is_none());
assert!(freshness["commitGraphStamp"].is_string());
}
#[test]
fn error_routes_over_real_socket() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let (status, body) = inspector.get_error("/api/nope");
assert!(status.contains("404"), "status: {status}");
assert_eq!(body["error"], "no such route");
let (status, body) = inspector.get_error("/api/snapshots/");
assert!(status.contains("400"), "status: {status}");
assert!(body["error"].as_str().unwrap().contains("id"));
let status = inspector.request("POST", "/api/history");
assert!(status.contains("405"), "status: {status}");
}
#[test]
fn payloads_never_expose_raw_repository_paths_on_path_private_surfaces() {
let store = representative_store();
let repo_path = store.repo.path().to_string_lossy().to_string();
let inspector = Inspector::spawn(store.repo.path());
let freshness = inspector.get_json("/api/freshness");
assert!(!freshness.to_string().contains(&repo_path));
let snapshot = inspector.get_json(&format!("/api/snapshots/{}", urlencode(&store.snapshot_id)));
assert!(snapshot.get("target").is_none());
assert!(
!snapshot.to_string().contains(&repo_path),
"object-scoped wire must not carry the raw worktree path"
);
let units = inspector.get_json("/api/revisions");
let target_display = &units["entries"][0]["targetDisplay"];
assert!(!target_display.to_string().contains(&repo_path));
}
#[test]
fn inspect_history_endpoint_renders_endorsement_readback() {
let home = tempfile::tempdir().unwrap();
let env_home = home.path().to_str().unwrap();
let env: [(&str, &str); 1] = [("SHORE_HOME", env_home)];
assert!(
shore_env(["key", "init", "--name", "default"], &env)
.status
.success()
);
let repo = GitRepo::new();
repo.write("src/lib.rs", "pub fn v() -> u32 { 1 }\n");
repo.commit_all("base");
repo.write("src/lib.rs", "pub fn v() -> u32 { 2 }\n");
let repo_arg = repo.path().to_str().unwrap();
assert!(
shore_env(
[
"key",
"enroll",
"default",
"--actor",
"actor:git-email:kevin@swiber.dev",
"--repo",
repo_arg,
],
&env,
)
.status
.success()
);
assert!(
shore_env(
["capture", "--repo", repo_arg],
&[("SHORE_HOME", env_home), ("SHORE_SIGNING", "off")],
)
.status
.success()
);
let target = captured_event_id(repo.path());
assert!(
shore_env(
["endorse", &target, "--repo", repo_arg],
&[
("SHORE_HOME", env_home),
("SHORE_ACTOR_ID", "actor:git-email:kevin@swiber.dev"),
],
)
.status
.success()
);
let inspector = Inspector::spawn(repo.path());
let history = inspector.get_json("/api/history");
let endorsement = history["entries"]
.as_array()
.unwrap()
.iter()
.find_map(|e| e.get("endorsements").and_then(|x| x.get(0)))
.expect("an endorsement readback in the inspector history");
assert_eq!(endorsement["classification"], "endorsement-trusted");
assert_eq!(endorsement["endorser"], "actor:git-email:kevin@swiber.dev");
}
#[test]
fn tokens_css_is_served_as_the_single_token_source() {
let (_repo, inspector) = served_asset_inspector();
let (status, body) = inspector.raw_get("/tokens.css");
assert!(
status.contains("200 OK"),
"tokens.css is served, got {status}"
);
assert!(
body.contains("--success"),
"tokens.css holds the semantic status aliases"
);
assert!(
body.contains("--r-md"),
"tokens.css carries the radii scale"
);
assert!(body.contains("--sans"), "tokens.css carries the sans stack");
let index = inspector.get_text("/");
let tokens_at = index.find("/tokens.css").expect("index links /tokens.css");
let app_at = index.find("/app.css").expect("index links /app.css");
assert!(
tokens_at < app_at,
"tokens.css must be linked before app.css"
);
}
#[test]
fn app_css_no_longer_declares_the_root_token_block() {
let (_repo, inspector) = served_asset_inspector();
let app_css = inspector.get_text("/app.css");
assert!(
!app_css.contains(":root"),
"app.css must not declare any :root token block (single-sourced in tokens.css)"
);
}
#[test]
fn design_system_docs_state_the_component_state_contract() {
let readme = include_str!("../src/cli/inspect/design-system/README.md");
let styles = include_str!("../src/cli/inspect/design-system/styles.css");
assert!(
!styles.contains("mirror the live inspector 1:1"),
"the gallery stylesheet must not claim complete live-app mirroring"
);
assert!(
readme.contains("component/state preview"),
"README names the narrower gallery contract"
);
assert!(
readme.contains("not a full live-app mirror"),
"README says runtime behavior belongs to the live inspector"
);
assert!(
readme.contains("shared tokens"),
"README keeps token sharing explicit"
);
assert!(
readme.contains("status/readback/diff/shell/feedback"),
"README names the critical parity surface set"
);
assert!(
readme.contains("../assets/tokens.css") && readme.contains("live token source"),
"README names the served token sheet as Review's live source"
);
assert!(
readme.contains("contrast-check.mjs") && readme.contains("audit of record"),
"README names the product-local contrast audit"
);
assert!(
readme.contains("Node") && readme.contains("design tooling only"),
"README keeps Node outside the Rust build and runtime"
);
assert!(
!readme.contains("PR #261") && !styles.contains("PR #261"),
"gallery docs should describe current state, not a completed PR redo"
);
}
#[test]
fn design_system_bake_is_gated_by_a_local_live_token_audit() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let audit_path = root.join("src/cli/inspect/design-system/contrast-check.mjs");
let audit = std::fs::read_to_string(&audit_path)
.unwrap_or_else(|error| panic!("{} must exist: {error}", audit_path.display()));
let bake = std::fs::read_to_string(root.join("src/cli/inspect/design-system/_bodies/bake.sh"))
.expect("design-system bake script is readable");
for required in [
"assets/tokens.css",
"--bg-row-sel",
"--sel-bg",
"--diff-add-fg",
"--emph-add-bg",
"--error-bg",
"--evt-assessment",
"--tok-keyword",
] {
assert!(audit.contains(required), "audit must require {required}");
}
assert!(
!audit.contains("withpointbreak.com"),
"the product audit must not depend on the marketing repository"
);
let audit_at = bake
.find("contrast-check.mjs")
.expect("bake invokes the product-local contrast audit");
let publish_at = bake
.find("cat \"$TOKENS\"")
.expect("bake publishes the generated token layer");
assert!(
audit_at < publish_at,
"contrast verification must run before generated files are written"
);
}
#[test]
fn design_system_gallery_is_claude_design_sync_ready() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let design_system = root.join("src/cli/inspect/design-system");
let styles = std::fs::read_to_string(design_system.join("styles.css"))
.expect("design-system stylesheet is readable");
let bake = std::fs::read_to_string(design_system.join("_bodies/bake.sh"))
.expect("design-system bake script is readable");
let readme = std::fs::read_to_string(design_system.join("README.md"))
.expect("design-system README is readable");
let gitignore = std::fs::read_to_string(design_system.join(".gitignore"))
.expect("design-system gitignore is readable");
let identity = std::fs::read_to_string(design_system.join("_bodies/identity-large.body.html"))
.expect("large identity body is readable");
let brand_check = std::fs::read_to_string(design_system.join("brand-check.mjs"))
.expect("design-system brand checker is readable");
assert!(
!styles.contains("url(\"/pointbreak-logo-mono") && !styles.contains("../../assets/"),
"gallery styles must not use origin-absolute or project-escaping mono-logo URLs"
);
assert!(
styles.contains("url(\"logo/pointbreak-logo-mono.svg\")"),
"gallery styles use one project-root-relative mono-logo URL"
);
assert!(
bake.contains(
"cp \"$DS/../assets/pointbreak-logo-mono.svg\" \"$DS/logo/pointbreak-logo-mono.svg\""
),
"bake publishes the live mono logo inside the synced project"
);
assert!(
bake.contains("s#url(\"logo/#url(\"../logo/#g"),
"bake rewrites project-root logo URLs for one-level-deep cards"
);
assert!(
readme.contains("pointbreak-product-ds"),
"README names the active Claude Design project"
);
assert!(
identity.contains("<svg class=\"large-identity-mark large-identity-mark-multiband\"")
&& !identity.contains("<img"),
"large identity must inline multiband geometry so SVG sanitization cannot remove its fills"
);
for fill in [
"var(--wave-deep)",
"var(--wave-trough)",
"var(--wave-face)",
"var(--wave-mid)",
"var(--wave-crest)",
] {
assert!(
styles.contains(fill),
"large identity styles must use {fill}"
);
}
assert!(
brand_check.contains("_bodies/identity-large.body.html")
&& brand_check.contains("inline identity geometry"),
"brand check must validate inline identity geometry against the brand lock"
);
for ignored in [
"/logo/pointbreak-logo-mono.svg",
"/_ds_*",
"/_adherence.oxlintrc.json",
"templates/**/.thumbnail",
] {
assert!(
gitignore.contains(ignored),
"gitignore must include {ignored}"
);
}
}
#[test]
fn design_system_brand_assets_are_locked_and_verified_offline() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let design_system = root.join("src/cli/inspect/design-system");
let lock_path = design_system.join("pointbreak-brand.lock.json");
let lock_source = std::fs::read_to_string(&lock_path)
.unwrap_or_else(|error| panic!("{} must exist: {error}", lock_path.display()));
let lock: serde_json::Value =
serde_json::from_str(&lock_source).expect("brand lock is valid JSON");
let checker_path = design_system.join("brand-check.mjs");
let checker = std::fs::read_to_string(&checker_path)
.unwrap_or_else(|error| panic!("{} must exist: {error}", checker_path.display()));
let bake = std::fs::read_to_string(design_system.join("_bodies/bake.sh"))
.expect("design-system bake script is readable");
let server = std::fs::read_to_string(root.join("src/cli/inspect/server.rs"))
.expect("inspector server source is readable");
let index = std::fs::read_to_string(root.join("src/cli/inspect/assets/index.html"))
.expect("inspector index is readable");
assert_eq!(lock["schema"], "com.withpointbreak.brand-lock/v1");
assert_eq!(
lock["source"]["repository"],
"https://github.com/withpointbreak/brand"
);
assert_eq!(
lock["source"]["commit"],
"45f3bc61a00535f5f7b59bf04dc6391a1153f31c"
);
assert_eq!(
lock["source"]["manifestSha256"],
"a6d36770cd2e9db2951c45835c7739fbb6d89ad45e959c50fe2bbe2e7a76eabe"
);
for field in ["commit", "manifestSha256"] {
let value = lock["source"][field]
.as_str()
.unwrap_or_else(|| panic!("source.{field} must be a string"));
let expected_len = if field == "commit" { 40 } else { 64 };
assert_eq!(value.len(), expected_len, "source.{field} has exact length");
assert!(
value
.bytes()
.all(|byte| byte.is_ascii_hexdigit() && !byte.is_ascii_uppercase()),
"source.{field} is lowercase hexadecimal"
);
}
let destinations = lock["artifacts"]
.as_array()
.expect("brand lock artifacts are an array")
.iter()
.map(|artifact| {
artifact["destination"]
.as_str()
.expect("every locked artifact has a destination")
})
.collect::<std::collections::BTreeSet<_>>();
let mut expected = vec![
"src/cli/inspect/assets/pointbreak-logo-mono.svg".to_owned(),
"src/cli/inspect/design-system/logo/pointbreak-logo.svg".to_owned(),
"src/cli/inspect/design-system/fonts/OFL.txt".to_owned(),
];
for name in [
"Bold",
"BoldItalic",
"ExtraBold",
"ExtraBoldItalic",
"ExtraLight",
"ExtraLightItalic",
"Italic",
"Light",
"LightItalic",
"Medium",
"MediumItalic",
"Regular",
"SemiBold",
"SemiBoldItalic",
"Thin",
"ThinItalic",
] {
expected.push(format!(
"src/cli/inspect/design-system/fonts/JetBrainsMono-{name}.woff2"
));
}
for destination in expected {
assert!(
destinations.contains(destination.as_str()),
"brand lock must cover {destination}"
);
}
for forbidden in [
"node:child_process",
"fetch(",
"http.request",
"https.request",
"POINTBREAK_BRAND_DIR",
"/Users/",
] {
assert!(
!checker.contains(forbidden),
"offline checker must not contain {forbidden}"
);
}
let brand_at = bake
.find("brand-check.mjs")
.expect("bake invokes the offline brand checker");
let audit_at = bake
.find("contrast-check.mjs")
.expect("bake invokes the local contrast audit");
assert!(
brand_at < audit_at,
"brand verification must precede contrast verification"
);
assert!(
!server.contains("design-system/logo") && !index.contains("pointbreak-logo.svg"),
"the multiband logo must remain gallery-only; live chrome keeps its mono asset"
);
}
#[test]
fn design_system_gallery_covers_live_shell_and_overlay_states() {
let bodies = [
include_str!("../src/cli/inspect/design-system/_bodies/navigation-topbar.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/inputs-controls.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/feedback-diagnostics.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/data-diff.body.html"),
]
.join("\n");
let styles = include_str!("../src/cli/inspect/design-system/styles.css");
let bake = include_str!("../src/cli/inspect/design-system/_bodies/bake.sh");
for marker in [
"id=\"topbar\"",
"id=\"lens-switcher\"",
"class=\"lens-tab\"",
"class=\"split\"",
"id=\"master\"",
"id=\"detail\"",
"class=\"route-diagnostic\"",
"id=\"cmd-palette\"",
"class=\"cmd-item\"",
"class=\"cmd-empty\"",
"id=\"key-help\"",
"class=\"key-help-list\"",
"class=\"advisory-note\"",
"class=\"reader-scope-note\"",
"class=\"modal\"",
"class=\"modal-card\"",
"data-ds-state=\"narrow\"",
] {
assert!(bodies.contains(marker), "gallery bodies include {marker}");
}
for selector in [
".lens-tab",
".route-diagnostic",
".cmd-item",
".key-help-list",
".advisory-note",
".reader-scope-note",
".modal-card",
".split",
] {
assert!(
styles.contains(selector),
"gallery styles include {selector}"
);
}
for output in [
"navigation/topbar-light.html",
"inputs/controls-light.html",
"feedback/diagnostics-light.html",
] {
assert!(bake.contains(output), "bake matrix includes {output}");
}
let normalized_bake = bake.split_whitespace().collect::<Vec<_>>().join(" ");
for named_pair in [
"bake navigation-topbar.body.html navigation/topbar.html Navigation \"Navigation — top bar, tabs, stats\" \"\" \"\" \"Navigation — dark\" \"Dark theme\"",
"bake inputs-controls.body.html inputs/controls.html Inputs \"Inputs — toolbar, buttons, toggles\" \"\" \"\" \"Inputs — dark\" \"Dark theme\"",
"bake feedback-diagnostics.body.html feedback/diagnostics.html Feedback \"Feedback — diagnostics & errors\" \"\" \"\" \"Feedback — dark\" \"Dark theme\"",
] {
assert!(
normalized_bake.contains(named_pair),
"dark theme twin carries explicit marker name + subtitle: {named_pair}"
);
}
}
#[test]
fn design_system_gallery_covers_the_shipped_attention_lens() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let body = std::fs::read_to_string(
root.join("src/cli/inspect/design-system/_bodies/data-attention.body.html"),
)
.expect("Attention gallery body exists");
let styles = std::fs::read_to_string(root.join("src/cli/inspect/design-system/styles.css"))
.expect("gallery styles exist");
for marker in [
"attention-card",
"attention-tier",
"attention-kind",
"attention-freshness",
] {
assert!(
body.contains(marker) || styles.contains(marker),
"missing {marker}"
);
}
assert!(body.contains("Needs input"));
assert!(body.contains("Advisory"));
for marker in [
"open-input-request",
"ambiguous-assessment",
"stale-assessment",
"failed-validation",
"manual_decision_required",
"accepted · current",
"superseded by",
] {
assert!(
body.contains(marker),
"Attention body must include {marker}"
);
}
}
#[test]
fn design_system_promotes_selected_review_treatments_and_soft_operational_dark() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let tokens = std::fs::read_to_string(root.join("src/cli/inspect/assets/tokens.css"))
.expect("live Review tokens exist");
for declaration in [
"--bg: #101817;",
"--bg-elev: #151f1e;",
"--bg-row: #1b2725;",
"--bg-row-sel: #243331;",
"--bg-topbar: #131d1b;",
"--sel-bg: #243331;",
"--bg-code: #121c1a;",
"--border: #2d3d39;",
"--fg: #e5ebe7;",
"--fg-dim: #9eaaa5;",
"--accent: #5ce5f4;",
"--accent-strong: #1fc4d6;",
"--on-accent: #071012;",
"--bg: #fdfbf5;",
"--bg-elev: #fffefa;",
"--bg-row: #f7f3e9;",
"--bg-row-sel: #e2dbce;",
"--bg-topbar: #f4f0e6;",
"--sel-bg: #f7f3e9;",
"--bg-code: #fffefa;",
"--border: #9eaaa4;",
"--fg: #1b1d1c;",
"--fg-dim: #4e5853;",
"--accent: #006875;",
"--accent-strong: #007885;",
"--on-accent: #ffffff;",
] {
assert!(
tokens.contains(declaration),
"live tokens must promote {declaration}"
);
}
for unchanged in [
"--row-pad: 8px 14px;",
"--row-pad: 4px 12px;",
"--success: #6dd28a;",
"--success: #1a7f37;",
"--tok-string: var(--success);",
"--tok-type: var(--info);",
] {
assert!(
tokens.contains(unchanged),
"unselected contract must remain unchanged: {unchanged}"
);
}
let styles = std::fs::read_to_string(root.join("src/cli/inspect/design-system/styles.css"))
.expect("gallery styles exist");
let mono_identity = styles
.split(".large-identity-mark-mono {")
.nth(1)
.and_then(|rest| rest.split('}').next())
.expect("large mono identity selector");
let multiband_identity = styles
.split(".large-identity-mark-multiband {")
.nth(1)
.and_then(|rest| rest.split('}').next())
.expect("large multiband identity selector");
assert!(mono_identity.contains("display: none;"));
assert!(multiband_identity.contains("display: block;"));
let app_css = std::fs::read_to_string(root.join("src/cli/inspect/assets/app.css"))
.expect("live component styles exist");
assert!(app_css.contains("url(\"/pointbreak-logo-mono.svg\")"));
assert!(
!app_css.contains("pointbreak-logo.svg"),
"compact live chrome must remain mono"
);
}
#[test]
fn design_system_final_state_has_no_temporary_visual_system() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
assert!(
!root.join("src/cli/inspect/design-system/variants").exists(),
"the promoted visual system must not leave a temporary variant directory"
);
let bake = include_str!("../src/cli/inspect/design-system/_bodies/bake.sh");
for forbidden in [
"data-visual-variant",
"bake_variant",
"bake_comparison",
"comparisons/",
] {
assert!(
!bake.contains(forbidden),
"final bake must not contain {forbidden}"
);
}
assert!(bake.contains("identity/large.html"));
assert!(bake.contains("identity/large-light.html"));
assert!(bake.contains("data/attention.html"));
assert!(bake.contains("data/attention-light.html"));
let review_facts =
include_str!("../src/cli/inspect/design-system/_bodies/data-review-facts.body.html");
for marker in ["replaced", "current", "signature valid"] {
assert!(
review_facts.contains(marker),
"review-facts comparison preserves {marker}"
);
}
let attention =
include_str!("../src/cli/inspect/design-system/_bodies/data-attention.body.html");
assert!(attention.contains("stale-assessment"));
assert!(attention.contains("accepted · current"));
let large_identity =
include_str!("../src/cli/inspect/design-system/_bodies/identity-large.body.html");
assert!(
large_identity.contains("<svg class=\"large-identity-mark large-identity-mark-multiband\"")
);
assert!(!large_identity.contains("<img"));
}
#[test]
fn design_system_soft_operational_dark_study_stays_gallery_only() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let study = root.join("src/cli/inspect/design-system/studies/soft-operational-dark");
for required in ["README.md", "tokens.css", "audit.mjs", "bake.sh"] {
assert!(
study.join(required).is_file(),
"soft operational study must include {required}"
);
}
let study_tokens = std::fs::read_to_string(study.join("tokens.css"))
.expect("soft operational study tokens exist");
assert!(
study_tokens.contains("data-tone=\"study-baseline\""),
"study must retain the accepted pre-trial baseline"
);
for held_constant in [
"--accent",
"--success",
"--warning",
"--danger",
"--diff-add-bg",
"--tok-keyword",
"--row-pad",
] {
assert!(
!study_tokens.contains(held_constant),
"study must not override held-constant token {held_constant}"
);
}
let live_tokens = include_str!("../src/cli/inspect/assets/tokens.css");
let live_styles = include_str!("../src/cli/inspect/assets/app.css");
let canonical_bake = include_str!("../src/cli/inspect/design-system/_bodies/bake.sh");
for live_source in [live_tokens, live_styles, canonical_bake] {
assert!(
!live_source.contains("soft-operational"),
"the gallery-only study must not enter live tokens, styles, or the canonical bake"
);
}
}
#[test]
fn design_system_contrast_audit_gates_every_syntax_tinted_row_pair() {
let audit = include_str!("../src/cli/inspect/design-system/contrast-check.mjs");
for marker in [
"add row",
"delete row",
"emphasized add",
"emphasized delete",
] {
assert!(audit.contains(marker), "final audit must cover {marker}");
}
assert!(
!audit.contains("result.diagnostic") && !audit.contains("diagnostic = false"),
"syntax/tinted-row pairs must be release gates, not diagnostics"
);
assert!(!audit.contains("--variant"));
let tokens = include_str!("../src/cli/inspect/assets/tokens.css");
for correction in [
"--diff-add-bg: #f3fbf3;",
"--diff-del-bg: #fff8f6;",
"--emph-add-bg: #e0ffe0;",
"--emph-del-bg: #fff2e6;",
] {
assert!(
tokens.contains(correction),
"light diff correction must include {correction}"
);
}
}
#[test]
fn review_visual_promotion_leaves_terminal_palettes_compatibility_frozen() {
let terminal = include_str!("../src/cli/theme.rs");
let readme = include_str!("../src/cli/inspect/design-system/README.md");
assert!(readme.contains("remain compatibility-frozen"));
assert!(readme.contains("not mechanically follow"));
for pinned in [
"\\x1b[38;2;90;169;230m", "\\x1b[48;2;0;96;0m", "\\x1b[38;2;3;105;161m", "\\x1b[48;2;160;239;160m", ] {
assert!(
terminal.contains(pinned),
"terminal compatibility pin must remain {pinned:?}"
);
}
}
#[test]
fn design_system_gallery_keeps_dag_edges_and_current_copy_in_sync() {
let styles = include_str!("../src/cli/inspect/design-system/styles.css");
let data_cards = include_str!("../src/cli/inspect/design-system/_bodies/data-cards.body.html");
assert!(
styles.contains("--dag-edge"),
"gallery DAG styles should carry the same default edge token as the live inspector"
);
let edge_block = styles
.split(".dag-edge {")
.nth(1)
.and_then(|rest| rest.split('}').next())
.expect(".dag-edge block");
assert!(
edge_block.contains("stroke: var(--dag-edge)")
&& !edge_block.contains("stroke: var(--border)"),
"gallery DAG edges should not fall back to only the quiet border token: {edge_block}"
);
let arrow_block = styles
.split(".dag-arrow-head {")
.nth(1)
.and_then(|rest| rest.split('}').next())
.expect(".dag-arrow-head block");
assert!(
arrow_block.contains("fill: var(--dag-edge)")
&& !arrow_block.contains("fill: var(--border)"),
"gallery DAG arrowheads should share the stronger edge token: {arrow_block}"
);
assert!(
data_cards.contains("current in thread"),
"gallery revision-card examples should use the live current-state wording"
);
assert!(
!data_cards.contains(">head</span>") && !data_cards.contains("revision thread · head "),
"gallery examples should avoid the old bare head copy"
);
}
#[test]
fn tokens_css_carries_a_light_theme_override_block() {
let (_repo, inspector) = served_asset_inspector();
let tokens = inspector.get_text("/tokens.css");
assert!(
tokens.contains("[data-theme=\"light\"]"),
"tokens.css carries the light-theme alias override block"
);
assert!(
tokens.contains("color-scheme"),
"tokens.css declares color-scheme"
);
}
#[test]
fn topbar_exposes_an_accessible_theme_toggle() {
let (_repo, inspector) = served_asset_inspector();
let index = inspector.get_text("/");
assert!(
index.contains("aria-label=\"Color theme:"),
"the topbar carries an accessible theme toggle"
);
}
#[test]
fn status_palette_has_a_non_color_redundancy_layer() {
let (_repo, inspector) = served_asset_inspector();
let app_css = inspector.get_text("/app.css");
assert!(
app_css.contains("::before") && app_css.contains("content:"),
"status classes carry a per-state glyph so meaning never rides on hue alone"
);
assert!(
app_css.contains("dashed"),
"superseded revisions read as dashed, a shape cue beyond color"
);
assert!(
app_css.contains("tabular-nums") && app_css.contains("slashed-zero"),
"mono/id columns disambiguate 0/O and align digits"
);
}
#[test]
fn positive_advisory_states_use_text_not_checkmark_glyphs() {
let (_repo, inspector) = served_asset_inspector();
let app_css = inspector.get_text("/app.css");
let gallery_css = include_str!("../src/cli/inspect/design-system/styles.css");
let gallery_bodies = [
include_str!("../src/cli/inspect/design-system/_bodies/data-diff.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/data-review-facts.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/data-timeline.body.html"),
include_str!("../src/cli/inspect/design-system/_bodies/feedback-diagnostics.body.html"),
]
.join("\n");
for (label, css) in [("app", app_css.as_str()), ("gallery", gallery_css)] {
assert!(
!css.contains("content: \"✓\""),
"{label} CSS should not use a positive checkmark glyph"
);
for selector in [
".fact-status.passed::before",
".fact-status.responded::before",
".fact-status.current::before",
".verdict-accepted .verdict-value::before",
".verdict-accepted_with_follow_up .verdict-value::before",
".s-added::before",
] {
assert!(
!css.contains(selector),
"{label} CSS should leave positive state labels text-only: {selector}"
);
}
assert!(
css.contains(".verify-valid::before") && css.contains("content: \"·\""),
"{label} signature readback leads valid rows with a neutral middot, not a checkmark"
);
for glyph in [
"content: \"✕\"",
"content: \"!\"",
"content: \"?\"",
"content: \"~\"",
"content: \"○\"",
] {
assert!(
css.contains(glyph),
"{label} CSS keeps non-positive status glyph redundancy: {glyph}"
);
}
}
for label in [
"accepted",
"passed",
"responded",
"current",
"signature valid",
"added",
] {
assert!(
gallery_bodies.contains(label),
"gallery examples keep the positive state text label visible: {label}"
);
}
}
#[test]
fn tokens_css_carries_the_type_scale() {
let (_repo, inspector) = served_asset_inspector();
let tokens = inspector.get_text("/tokens.css");
for step in ["--fs-xs", "--fs-sm", "--fs-md", "--fs-base"] {
assert!(
tokens.contains(step),
"tokens.css carries the {step} type-scale step"
);
}
}
#[test]
fn topbar_exposes_a_density_toggle() {
let (_repo, inspector) = served_asset_inspector();
let index = inspector.get_text("/");
assert!(
index.contains("aria-label=\"Density:"),
"the topbar carries an accessible comfortable/compact density toggle"
);
}
#[test]
fn advisory_framing_is_rendered_text_not_tooltip_only() {
let (_repo, inspector) = served_asset_inspector();
let index = inspector.get_text("/");
assert!(
index.contains("never gates writes") && index.contains("reader-relative"),
"the store-identity popover carries the read-only / advisory framing as rendered text"
);
}
#[test]
fn api_history_windows_with_limit_and_continues_via_offset() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let full = inspector.get_json("/api/history");
let total = full["entries"].as_array().unwrap().len();
let event_count = full["eventCount"].clone();
assert!(
total >= 2,
"representative store should yield multiple history entries, got {total}"
);
let page1 = inspector.get_json("/api/history?limit=1");
assert_eq!(page1["entries"].as_array().unwrap().len(), 1);
assert_eq!(page1["offset"], 0);
assert_eq!(page1["eventCount"], event_count);
assert_eq!(page1["matchCount"], total);
let page2 = inspector.get_json("/api/history?limit=1&offset=1");
assert_eq!(page2["entries"].as_array().unwrap().len(), 1);
assert_eq!(page2["offset"], 1);
assert_ne!(
page2["entries"][0]["eventId"],
page1["entries"][0]["eventId"]
);
assert!(full.as_object().unwrap().get("nextCursor").is_none());
assert!(page1.as_object().unwrap().get("nextCursor").is_none());
}
#[test]
fn api_history_rejects_malformed_window_params() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
assert!(
inspector
.get_error("/api/history?limit=abc")
.0
.contains("400")
);
assert!(
inspector
.get_error("/api/history?offset=abc")
.0
.contains("400")
);
assert_eq!(
inspector.get_json("/api/history?cursor=whatever")["matchCount"],
inspector.get_json("/api/history")["matchCount"]
);
}
#[test]
fn api_history_q_filters_entries_and_reports_facets_and_match_count() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let full = inspector.get_json("/api/history");
let observations = entries_of_type(&full, "review_observation_recorded").len();
assert!(observations >= 1, "store should have observations");
let filtered = inspector.get_json("/api/history?type=review_observation_recorded");
assert!(
filtered["entries"]
.as_array()
.unwrap()
.iter()
.all(|entry| entry["eventType"] == "review_observation_recorded")
);
assert_eq!(filtered["matchCount"], observations);
assert_eq!(
filtered["facets"]["review_observation_recorded"],
observations
);
assert!(
filtered["facets"]["review_assessment_recorded"]
.as_u64()
.unwrap_or(0)
>= 1,
"facets count assessments even under a type=observation page filter"
);
}
#[test]
fn api_history_q_full_text_search_narrows_the_page() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let full = inspector.get_json("/api/history");
let total = full["matchCount"].as_u64().unwrap();
let filtered = inspector.get_json("/api/history?q=type%3Aobservation");
let filtered_count = filtered["matchCount"].as_u64().unwrap();
assert!(filtered_count <= total);
assert!(
filtered["entries"]
.as_array()
.unwrap()
.iter()
.all(|entry| entry["eventType"] == "review_observation_recorded")
);
}
#[test]
fn api_history_rejects_an_unsupported_qualifier_with_400() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let (status, body) = inspector.get_error("/api/history?q=attention%3Ax");
assert!(status.contains("400"), "status: {status}");
assert!(body.get("error").is_some(), "body: {body}");
}
#[test]
fn api_history_aliases_status_to_check_and_reports_a_deprecation_notice() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let filtered = inspector.get_json("/api/history?q=status%3Apassed");
let notices = filtered["queryNotices"]
.as_array()
.expect("queryNotices array");
assert!(
!notices.is_empty(),
"expected a deprecation notice: {filtered}"
);
assert!(filtered["matchCount"].as_u64().unwrap() >= 1);
for entry in filtered["entries"].as_array().unwrap() {
assert_eq!(entry["eventType"], "validation_check_recorded");
assert_eq!(entry["summary"]["status"], "passed"); }
}
#[test]
fn api_history_offset_windows_the_filtered_set() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let total = inspector.get_json("/api/history")["matchCount"]
.as_u64()
.unwrap();
let page = inspector.get_json("/api/history?offset=1&limit=2");
assert_eq!(page["offset"], 1);
assert!(page["entries"].as_array().unwrap().len() <= 2);
assert_eq!(page["matchCount"], total);
}
#[test]
fn api_history_at_locates_the_page_and_sets_match_index() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let full = inspector.get_json("/api/history");
let target = full["entries"][0]["eventId"].as_str().unwrap().to_owned();
let located = inspector.get_json(&format!("/api/history?limit=2&at={}", urlencode(&target)));
assert!(located["matchIndex"].is_u64());
assert!(
located["entries"]
.as_array()
.unwrap()
.iter()
.any(|entry| entry["eventId"] == target.as_str())
);
}
#[test]
fn api_history_unparamd_shape_is_unchanged_plus_additive_fields() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let full = inspector.get_json("/api/history");
let entries = full["entries"].as_array().unwrap().len();
assert_eq!(full["schema"], "pointbreak.inspect-history");
assert_eq!(full["historyCount"], entries);
assert!(full["facets"].is_object());
assert_eq!(full["offset"], 0);
assert_eq!(full["matchCount"], entries);
assert!(full.get("matchIndex").is_none() || full["matchIndex"].is_null());
assert!(full.as_object().unwrap().get("nextCursor").is_none());
}
#[test]
fn api_history_rejects_malformed_offset_and_order() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
assert!(
inspector
.get_error("/api/history?offset=abc")
.0
.contains("400")
);
assert!(
inspector
.get_error("/api/history?order=sideways")
.0
.contains("400")
);
}
#[test]
fn api_history_reflects_a_new_event_after_an_append() {
let store = representative_store();
let inspector = Inspector::spawn(store.repo.path());
let before = inspector.get_json("/api/history")["matchCount"]
.as_u64()
.unwrap();
store.repo.write(
"src/lib.rs",
"pub fn value() -> u32 {\n 99\n}\n\npub fn other() -> u32 {\n 7\n}\n",
);
capture(store.repo.path());
let after = inspector.get_json("/api/history")["matchCount"]
.as_u64()
.unwrap();
assert!(
after > before,
"the cache invalidates on a new event (marker changed): {before} -> {after}"
);
}
#[test]
fn inspector_serves_revision_and_history_over_a_swept_body() {
let repo = GitRepo::new();
repo.write("src/lib.rs", "pub fn value() -> u32 { 1 }\n");
repo.commit_all("base");
repo.write("src/lib.rs", "pub fn value() -> u32 { 2 }\n");
let revision_id = capture(repo.path());
let arg = repo.path().to_str().unwrap();
let body = "x".repeat(5000);
let observation = shore_env(
[
"observation",
"add",
"--repo",
arg,
"--track",
"agent:codex",
"--title",
"a large observation",
"--body",
&body,
],
&[],
);
assert!(
observation.status.success(),
"observation add stderr:\n{}",
String::from_utf8_lossy(&observation.stderr)
);
let removed = shore_env(
["store", "remove", "--repo", arg, "--revision", &revision_id],
&[],
);
assert!(removed.status.success());
let compacted = shore_env(["store", "compact", "--repo", arg, "--yes"], &[]);
assert!(compacted.status.success());
let inspector = Inspector::spawn(repo.path());
let revision = inspector.get_json(&format!("/api/revisions/{}", urlencode(&revision_id)));
let entry = &revision["observations"][0];
assert!(entry.get("body").is_none());
assert_eq!(entry["bodyContentState"], "physically_removed");
let history = inspector.get_json("/api/history");
assert_eq!(history["schema"], "pointbreak.inspect-history");
assert!(
!history["entries"].as_array().unwrap().is_empty(),
"the always-hydrating history base cache must survive a swept body"
);
}