feat(control,cli,web): GET /api/v1/system/capabilities + CapabilitiesPage (ADR-W030, #9) - #263
Merged
Merged
Conversation
…uild surface Design-first record (task #9/#176, mgmt-completeness §2.7): assemble an honest capability+licence DTO from hal::probe + cfg!(feature) + the resolved AdapterReport rather than serialize a non-existent CapabilityReport (that rich telemetry is the separate SA-1+ lane #180). Pins effective_license to AGENTS.md §G / ADR-0012, build{} inline, viewer-read no-BOLA auth, control-keeps-no-hal-dep, and the static with_capabilities snapshot (invariant #10). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ce tests Failing tests first (rule 18). The SystemCapabilities DTO + CLI hal->DTO mapping compile with incomplete first-cut bodies so assertions fail: - control: gpl-codecs -> GPL (resolve still returns LGPL-clean); route 404 (not yet registered) for the viewer-200 + bad-bearer-401 cases. - cli: software backends available on the default build (no backends yet); a resolved adapter classifies the compositor (class still None). RED evidence: control: FAILED. 3 passed; 3 failed (gpl_codecs.., viewer_reads.., a_bad_bearer..) cli: FAILED. 1 passed; 2 failed (software_backends.., a_resolved_adapter..) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ability DTO (ADR-W030) Implement the honest default-build capability + licence surface (task #9/#176, mgmt-completeness §2.7) to green. multiview-control: - SystemCapabilities DTO (system.rs): backends (codec decode/encode + software composite), compositor class/device/driver, build{effective_license, redistributable,features,ndi}, optional NDI attribution. Primitives/enums only — control keeps zero dep on multiview-hal. - BuildInfo::resolve pins the compliance mapping (§G/ADR-0012): gpl-codecs -> GPL, else LGPL-clean; every shippable build redistributable. EffectiveLicense serializes to the exact strings 'LGPL-clean' / 'GPL'. - GET /api/v1/system/capabilities route (routes/system.rs), viewer-read, system-global (no BOLA axis); registered in routes/mod + openapi. - AppState::with_capabilities — a static startup snapshot, no engine channel (invariant #10); default is the coarse software-only surface. multiview-cli: - system_capabilities.rs maps hal::probe + cfg!(feature) + the resolved AdapterReport onto the DTO; graceful (absent backend -> available:false, never panics). Composite-stage GPU backends are NOT emitted as available:false rows (hal has no env probe for them) — the compositor field is authoritative. - control.rs wires .with_capabilities(...) at startup (adapter read only under the gpu feature). The SA-1+ vendor-caps deep probe (per-codec profiles, NVENC sessions, VRAM, PSI, per-backend compiled_in) is the separate tracked lane #180. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…penAPI/client (ADR-W030) Wire the web surface for GET /api/v1/system/capabilities and regenerate the committed spec + generated client. web: - api/system.ts + api/systemQueries.ts: getSystemCapabilities + the useSystemCapabilities() TanStack hook (static startup snapshot; not polled). - pages/CapabilitiesPage.tsx (/system/capabilities): three panels — Backends matrix, Compositor tier, Build & licence (effective licence, redistributable, compiled features, NDI attribution). Status by value + label, never colour alone (WCAG 1.4.1). Nav entry + route added. - pages/CapabilitiesPage.test.tsx: MSW render test (availability, compositor class, exact licence string, NDI attribution shown iff the ndi feature is on). control: rename the handler capabilities -> system_capabilities so its OpenAPI operationId no longer collides with preview::capabilities in the generated client. regen: docs/api/openapi.json + web/src/api/schema.ts. Web gate green: eslint 0-warnings, tsc --noEmit, lingui compile + vite build, vitest (CapabilitiesPage 2/2). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds the CapabilitiesPage + nav <Trans> strings to the source and locale catalogs (en/ar/pseudo) so the i18n catalog-freshness CI gate passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Run the gate's canonical i18n:extract --clean + i18n:compile and commit the regenerated compiled catalogs (en/ar messages.ts) so the i18n catalog-freshness CI gate passes (the production macro strips the source fallback, so compiled catalogs must match the .po sources). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…profile Codex review (rule 16) on PR #263: the compile-time-resolver test unconditionally asserted `LGPL-clean` + no-NDI-attribution, but `resolve_system_capabilities` correctly returns `GPL` under `--features gpl-codecs` and includes attribution under `--features ndi`. The test therefore would FAIL for exactly the compliance-sensitive profiles it claims to validate, passing on default CI only because CI builds default features — a mis-scoped test. Gate the expectations on the profile the test binary is compiled with (`GPL` when `gpl-codecs` else `LGPL-clean`; attribution present when `ndi` else absent), mirroring the `cfg!` bridge inside the resolver. This strengthens coverage (the GPL/NDI profiles are now asserted, not skipped) rather than weakening it; the exhaustive per-combo mapping is already runtime-tested in `multiview-control` via `BuildInfo::resolve`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
aperim-agent
added a commit
that referenced
this pull request
Jul 12, 2026
Add the ProbeStatus / DeviceCapability / CgroupLimits / HostInfo / DetectionInfo wire types + the observed_at / devices / host / detection fields on SystemCapabilities, with serde tests encoding the three contracts: ProbeStatus is snake_case on the wire, unknown optionals are omitted (never a fabricated zero), and observed_at is ALWAYS serialized (the provenance anchor, ADR-M014 review finding #2). The RED serde config is deliberately wrong on all three (no rename_all, no skips, observed_at carries a skip) so the tests fail first; the green commit fixes them. Types are primitives/enums only — zero multiview-hal dep (the #263/W030 boundary). Per ADR-M014 §2/§6. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds the honest default-build capability + licence surface (management-completeness §2.7, task #9) — the missing
/system/*counterpart to the existing/preview/capabilities.GET /api/v1/system/capabilities(viewer-read, system-global — no per-object BOLA axis), returning a newmultiview_control::system::SystemCapabilitiesDTO:backends: codec decode/encode + software composite, each withavailable(fromhal::probe),max_resolution?,decode_resize?.compositor: the SA-0 acceleration tier (class/device_type?/driver?) from the resolved wgpuAdapterReport(ADR-0035).build: effective build-profile licence (LGPL-clean|GPL),redistributable, compiledfeatures,ndi— the machine-readable form of ADR-0012's "effective license reported per artifact".ndi_attribution?: the mandatoryNDI® is a registered trademark of Vizrt NDI AB+ ndi.video, present iff thendifeature is compiled (AGENTS.md §G).CapabilitiesPageat/system/capabilities(nav + route): Backends matrix / Compositor / Build & licence panels. Status by value + label, never colour alone (WCAG 1.4.1).Design & isolation
multiview-controlwith primitives/enums only — zero dep onmultiview-hal. The CLI mapshal::probe+cfg!(feature)+ the resolved adapter onto it and installs it via a new staticAppState::with_capabilitiessnapshot — no engine channel (invariant Bump vite from 6.4.3 to 8.0.16 in /web #10). Design recorded in ADR-W030.effective_licenseis a pure, exhaustively-tested mapping pinned to §G/ADR-0012:gpl-codecs⇒ GPL, else LGPL-clean; every shippable build redistributable (nononfreefeature; NDI runtime-loaded, never linked). TDD asserts the exact strings per feature-combo.TDD
RED (
f4f05dd9) → GREEN (f6e214f9): control 6/6, cli 3/3, web CapabilitiesPage 2/2. Local gate green —fmt,clippy -p multiview-control -p multiview-cli --lib -D warnings, crate tests, webeslint/tsc/vite build. Spec + client regenerated (gen-openapi+generate:api).Scope boundary (rule 6)
This is the complete, honest default/software-tier surface. The SA-1+ vendor-caps deep probe (per-codec profiles, NVENC sessions, VRAM, host PSI, per-backend
compiled_in) needs feature-gated backend code + GPU-hardware validation and is the separate tracked lane #180 (blocked by this). No empty/placeholder fields stand in for it.Out of scope
The #180 deep probe; a separate
/system/buildalias (build info is inline per §3.4); wiring Output-editor encoder dropdowns to consume this.🤖 Generated with Claude Code