Skip to content

feat: Playb00k Assurance view + SysMD solver sidecar (stacked on #93) - #94

Merged
elasticdotventures merged 4 commits into
mainfrom
feat/playbook-assurance-sysmd-sidecar
Oct 7, 2026
Merged

elasticdotventures merged 4 commits into
mainfrom
feat/playbook-assurance-sysmd-sidecar

Conversation

@elasticdotventures

@elasticdotventures elasticdotventures commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Stacked on #93 (base is feat/assurance-thread, so this diff is only the UI work). Retarget to main once #93 merges.

What

A Playb00k Assurance tab over the /assurance/* routes.

  • Requirements table: the five assurance states shown as label and symbol (never colour alone), state chips with counts, source-kind badges (binding / policy / guidance), gap tags. Filters (state, status, owner, gap) are applied by the server, so only the needed rows load.
  • Detail drawer: the whole thread: source obligations, the asserted system element, the control with its implementation path (an empty one is shown as an implementation gap), the verification case, revision-bound evidence (which of model/implementation/configuration moved, artifact integrity), links resolved or dangling, gaps.
  • Run a case from the page: explicit confirm step naming the command and the revision, runs at the revision shown, refusals (409 / 403) explained, nothing claimed on failure.
  • Diagram: authenticated fetch to a blob URL, fit / 2x / 3x zoom in a scrolling frame, open full size. (Fit-to-width was unreadable with 36 nodes; found by looking at it in a browser.)
  • Audit: hash-chain status, decisions, denials.
  • Setup: optional access token, kept in sessionStorage only (verified: not in localStorage), sent only as an Authorization header.

Server change to review carefully

KR0KI_PUBLIC_UI (default off, no behaviour change unless set): serves only the static /playbook GET routes without a token. A browser navigation cannot send Authorization, so with per-identity grants on the page could not otherwise load. Exact patterns only (gateway::PUBLIC_UI_PATTERNS, unit-tested to be static playbook GETs holding no grant); tested that data routes, /mcp/tools, a POST to /playbook/x and lookalike paths still return 401.

Verification

  • Real browser, real server (gateway on, real baseline and evidence store): 401 -> "add a token under Setup" -> token in Setup -> list, drawer, diagram, audit (chain verifies, a refused commit shown as a denial), and a VC-A02 run from the page flipped the row from stale to verified (7 s, the real cargo test, 6 tests), with the older stale evidence kept as history.
  • Playb00k unit tests 206 (44 new for this view, fixtures are the server's real JSON); cargo test --workspace --no-fail-fast 50 suites; fmt and clippy -D warnings clean.

Known limits

  • Other Playb00k tabs still call the server without a token. With grants on they show auth errors (the diagram-type catalog is empty in my run). Only the Assurance tab sends the token. A follow-up could thread the token through the other fetches.
  • A scrubbed fixture path (/home/... in artifact_uri) exists in the earlier commit's history in this branch.
  • Not covered: keyboard-only pass and a screen-reader pass (the markup uses real buttons, a live alert and labelled regions, but I haven't driven it that way).

Also in this PR: the SysMD sidecar (second commit, a5527f2)

tukcps/SysMD (interval constraint solver) as an optional black-box sidecar: kr0ki sends model text over REST, reads solved variables back, links no SysMD code. Without KR0KI_SYSMD_URL, /sysmd/solve answers 503 and nothing else changes.

  • POST /sysmd/solve[?language=sysml|kerml|sysmd] (gateway model.read), MCP tool solve_constraints (now 33 tools), sysmd health check, just sysmd-image | sysmd-up | sysmd-down | test-live-sysmd, systemd unit, scripts/build-sysmd.sh, docs/SYSMD-SIDECAR.md.
  • Soundness (review this): SysMD returns display strings, and Representer loses information: 2.000001 prints 2, 0..1e-7 prints 0 (only the lower bound when the bounds are within 1e-5), 1..1e9 prints 0..1e9. sysmd_client::parse_value widens every printed bound outward so the interval contains the true range (an exact 6 returns about [5.99997, 6.00003]). Unbounded, empty and NaN are separate variants, never numbers. A model SysMD rejects is a verdict: error report, a violated constraint is inconsistent.
  • Units: values are SI base (5 mm -> 0.005 m); kg m / s^2-style units are mapped to ufo_types::quantity::Unit by dimension, unknown ones reported rather than guessed.
  • Four upstream patches in the fork PromptExecution/SysMD (integration branch kr0ki/sidecar): toolchain resolver, distinct currencies, and two found while building this: POST /session created sessions with no standard library (every REST model failed with an NPE; regression test fails without the fix), and no way to delete a REST session. Not yet sent upstream.

Verified: 12 client unit tests (rounding table, unit table, wiremock flow), 5 server tests, 3 live tests against the real hardened container (containment of the true values, error and inconsistent verdicts, no leaked sessions), and a real kr0ki-server -> container run of /health and /sysmd/solve. Full gate: fmt, clippy -D warnings, cargo test --workspace 51 suites / 819 tests / 0 failed, bridge 14 tests.

Limits: SysMD has no auth, so loopback only; the image takes ~2 minutes from a warm gradle cache and holds a 136 MB jar (gitignored; build with just sysmd-image, alone, not beside cargo).

🤖 Generated with Claude Code

https://claude.ai/code/session_01GgXQRGsprSZc2oXGNj9n8X

@elasticdotventures elasticdotventures changed the title feat(playbook): Assurance view (stacked on #93) feat: Playb00k Assurance view + SysMD solver sidecar (stacked on #93) Oct 5, 2026
@elasticdotventures
elasticdotventures changed the base branch from feat/assurance-thread to main October 7, 2026 00:49
elasticdotventures and others added 4 commits October 7, 2026 01:09
… + session-only token + opt-in public UI

Playb00k Assurance tab over the /assurance/* routes:
- requirement table with the five assurance states shown as label + symbol (never colour alone),
  state chips with counts, server-side filters (state/status/owner/gap), source-kind badges;
- detail drawer with the whole thread (obligations, element, control + implementation path,
  case, revision-bound evidence with which revision moved, links resolved/dangling, gaps);
- run a case from the page: explicit confirm step, runs at the revision shown, refusals explained;
- diagram panel (authenticated blob, fit/2x/3x zoom in a scrolling frame, open full size);
- audit panel (hash-chain status, decisions, denials).
Setup gains an optional access token kept in sessionStorage only. lib/assurance.js is the client.

Server: KR0KI_PUBLIC_UI (default off) serves only the static /playbook GET routes without a token,
because a browser navigation cannot send Authorization; data routes still require one. Tested
both ways (default behind the gateway; opt-in public; data/POST/lookalike paths still 401).

Verified in a real browser against a real server (gateway on, real baseline and evidence):
401 -> Setup token -> list, drawer, diagram, audit, and a VC-A02 run flipping the row from
stale to verified. Fixtures are the server's real JSON. Playb00k tests 206; cargo workspace
50 suites; fmt and clippy -D warnings clean.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgXQRGsprSZc2oXGNj9n8X
…ent, /sysmd/solve, MCP solve_constraints)

SysMD runs headless in a hardened container (read-only root, tmpfs store, 1 GiB, cap-drop ALL, loopback). kr0ki talks REST only.
- sysmd_client: project+session per solve, deleted afterwards; parses SysMD's display strings into closed intervals widened outward for
  the Representer's 5-decimal rounding and its dropped-upper-bound / literal-0 cases (verified live), unbounded/empty/NaN kept distinct,
  SI-base compound units mapped by dimension, standard library and bookkeeping variables filtered
- POST /sysmd/solve (gateway: model.read), MCP solve_constraints (33 tools), KR0KI_SYSMD_URL, sysmd health check
- just sysmd-image|sysmd-up|sysmd-down|test-live-sysmd, systemd unit, scripts/build-sysmd.sh (fork branch kr0ki/sidecar)
- docs/SYSMD-SIDECAR.md

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgXQRGsprSZc2oXGNj9n8X
…pfs; document revision-bound evidence policy

Evidence is re-verified on minor releases, not patch bumps.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgXQRGsprSZc2oXGNj9n8X
@elasticdotventures
elasticdotventures force-pushed the feat/playbook-assurance-sysmd-sidecar branch from e10aaa6 to 671d5a9 Compare October 7, 2026 01:09
@elasticdotventures
elasticdotventures merged commit bfbbce2 into main Oct 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant