refactor(platform): bound lab canon and contour identity

This commit is contained in:
DCCONSTRUCTIONS
2026-08-05 12:00:27 +03:00
parent de12e96297
commit 6d0abbc569
10 changed files with 199 additions and 8 deletions
@@ -478,7 +478,7 @@ export function ComputeContourSettingsWindow({
<dd>{network?.broker.bind_address ?? "—"}</dd>
</div>
<div>
<dt>Worker 006</dt>
<dt>{contour?.display_name ?? "Worker"}</dt>
<dd>{network?.worker.reachable
? `${network.worker.mqtt_host ?? "—"}:${network.worker.mqtt_port ?? "—"}`
: "Недоступен"}</dd>
@@ -28,7 +28,7 @@ export function useComputeContourSettings(): ComputeContourSettingsController {
{
label: "Обновить телеметрию выбранного контура",
icon: "refresh",
disabled: contours.selectedContour?.contour_id !== "worker-006",
disabled: contours.selectedContour === null,
onClick: contours.refreshTelemetry,
},
{
@@ -48,7 +48,11 @@ export function useWorkerTelemetry(
setError(null);
} catch (reason: unknown) {
if (controller.signal.aborted) return;
setError(reason instanceof Error ? reason.message : "Worker 006 не ответил.");
setError(
reason instanceof Error
? reason.message
: "Вычислительный контур не ответил.",
);
} finally {
if (!controller.signal.aborted) setLoading(false);
}
@@ -62,8 +62,7 @@ export function ComputeModulesWorkspace() {
selectedContour,
telemetryRefreshGeneration,
} = useComputeContours();
const legacyDiagnostic = selectedContour?.contour_id === "worker-006"
&& selectedContour.telemetry_mode === "legacy-ssh";
const legacyDiagnostic = selectedContour?.telemetry_mode === "legacy-ssh";
const { telemetry, error } = useWorkerTelemetry(
selectedContour?.contour_id ?? null,
(selectedContour?.telemetry_poll_interval_seconds ?? 3) * 1_000,
@@ -20,8 +20,7 @@ export function NetworkWorkspace() {
selectedContour,
telemetryRefreshGeneration,
} = useComputeContours();
const legacyDiagnostic = selectedContour?.contour_id === "worker-006"
&& selectedContour.telemetry_mode === "legacy-ssh";
const legacyDiagnostic = selectedContour?.telemetry_mode === "legacy-ssh";
const { telemetry, error } = useWorkerTelemetry(
selectedContour?.contour_id ?? null,
(selectedContour?.telemetry_poll_interval_seconds ?? 3) * 1_000,
@@ -9,7 +9,7 @@ async function read(relativePath) {
return readFile(new URL(relativePath, sourceRoot), "utf8");
}
test("Worker 006 telemetry remains a bounded system feature slice", async () => {
test("Compute-contour telemetry remains a bounded system feature slice", async () => {
const [
productModel,
workspaceHub,
@@ -88,6 +88,18 @@ test("Worker 006 telemetry remains a bounded system feature slice", async () =>
assert.match(panelActions, /actions\.push\(\.\.\.systemUtilityActions\)/);
assert.match(contourSettingsHook, /icon: "refresh"/);
assert.match(contourSettingsHook, /icon: "settings"/);
assert.doesNotMatch(contourSettingsHook, /contour_id\s*!==\s*"worker-006"/);
assert.doesNotMatch(
computeWorkspace,
/contour_id\s*===\s*"worker-006"[\s\S]*telemetry_mode/,
);
assert.doesNotMatch(
networkWorkspace,
/contour_id\s*===\s*"worker-006"[\s\S]*telemetry_mode/,
);
assert.doesNotMatch(contourSettings, /<dt>Worker 006<\/dt>/);
assert.match(contourSettings, /contour\?\.display_name/);
assert.match(telemetryPolling, /Вычислительный контур не ответил\./);
assert.match(contourSettings, /FieldFrame label="Операционная система"/);
assert.match(contourSettings, /label="Обновление интерфейса"/);
assert.match(contourSettings, /label="Интервал MQTT агента"/);
+23
View File
@@ -216,6 +216,29 @@ A LAB run may be shown as diagnostic evidence with `legacy-partial` method
metadata. It may be called reproducible or promoted only when the method is
`complete` and its experiment-specific acceptance gates pass.
## Lifecycle classes and bounded canonicalization
ADR 0039 separates the value of laboratory evidence from the maturity of its
execution architecture:
- `canonical` is the ordinary reusable path through versioned source, provider,
graph and run contracts;
- `experimental` is an admitted bounded adapter or package for a novel stack or
method which the current graph cannot honestly express;
- `legacy` is immutable historical evidence retained through its existing
validator/projector without retroactive provenance.
An experimental LAB is not rejected merely because it does not fit the current
canonical stack. It still must retain real source/configuration/runtime/artifact
identities, visual evidence, terminal outcome, limitations and forbidden
authority. It may not silently become a core dependency. Promotion occurs only
after repeated value justifies a reusable provider or graph contract.
Mission Core does not bulk-migrate the archive. E33, E35 and E46J are the bounded
execution canaries. Once they prove one automatic run-to-evidence path, the LAB
canonicalization slice closes and remaining historical work stays `legacy` unless
an integrity or product need justifies a targeted migration.
## Planning discipline
A planned LAB number is not a placeholder page. Before execution it must name:
@@ -102,6 +102,30 @@ real authority.
4. Add MCAP only as a normalized P1/P2 sidecar; retain MQTT/fMP4 P0 evidence.
5. Require an independent safety gate before any real actuator authority.
## Architecture stabilization gate before the next main CV increment
The evidence/report layer is now generic and proof-bound, but historical LAB
execution remains heterogeneous. ADR 0039 limits the remaining stabilization
work instead of turning it into a bulk archive migration.
The gate is:
1. Preserve all existing historical LABs as immutable `legacy` evidence.
2. Admit genuinely novel stacks as bounded `experimental` adapters rather than
discarding them or importing them directly into core.
3. Prove one source/provider/graph/run path on E33, E35 and E46J.
4. Ensure a new ordinary `canonical` LAB does not add a new branch to the
application shell, advanced dispatcher or generic workspace.
5. Close local telemetry operational debt: multi-contour credential enrollment,
executable agent bundle, journal rotation, restart/reconnect/duplicate/stale/
identity-mismatch acceptance and run correlation.
6. Record production/fleet, second-source, Quick Connect, physical mount and
live-authority gaps as intentional non-blocking debt with explicit triggers.
A9/E36 remains a later scientific transfer gate. It is not a precondition for
this architecture stabilization and cannot be executed without a qualified
second mounted source.
## Current implementation slice
- [x] Preserve E29 as the accepted immutable diagnostic baseline.
@@ -179,6 +179,15 @@ Legacy/integrated diagnostic viewers may keep a result interaction inside the
evidence slot only where that viewer is already the admitted result instrument.
This exception does not apply automatically to a new LAB.
ADR 0039 adds a lifecycle distinction to this code shape. A `canonical` LAB
enters through the reusable registry and must not add another experiment-named
branch to `App.tsx`, the generic workspace or the advanced dispatcher. An
`experimental` LAB may have a bounded adapter or renderer when the current graph
cannot express its evidence, but the adapter remains feature-local, declares its
classification and cannot change generic product behavior. A `legacy` LAB keeps
its existing read-only projector and is not rewritten solely to satisfy the
latest code shape.
## Local ontology decision
Mission Core already has three semantic mechanisms:
@@ -216,6 +225,11 @@ vocabulary and executable contracts. They do not create a second runtime model.
`test/laboratoryProductUi.test.mjs` additionally enforces the versioned LAB
report fields and shared result component across bounded LAB modules.
The next executable laboratory architecture gate extends these tests to reject
new unclassified experiment branches while allowing a declared bounded
experimental adapter. The gate protects core composition; it does not forbid a
novel research stack.
The line limits are ratchets, not quality targets. When a file reaches a limit,
split a feature; do not raise the limit to accommodate unrelated behavior.
@@ -0,0 +1,116 @@
# ADR 0039: Bounded laboratory canonicalization and intentional debt
Date: 2026-08-05
Status: accepted; executable canary migration remains open
## Context
Mission Core accumulated valuable immutable laboratory evidence while the
perception contracts, worker boundary and product presentation were still being
discovered. Rewriting every historical experiment would consume the same effort
as new product work, risk changing preserved evidence and falsely imply that old
runs were produced by contracts which did not exist at the time.
The opposite extreme is also unsafe. If every new experiment adds another core
router, application branch and presentation component, the product composition
will keep growing with the research history. A novel detector, runtime or
evaluation method must remain possible without either being discarded or being
promoted directly into the stable product architecture.
ADR 0036 made standard evidence discovery configurative. ADR 0038 made the
selected immutable evidence report generic and proof-bound. Neither decision
made the historical experiment implementations reusable execution graphs.
## Decision
Mission Core admits three laboratory lifecycle classes.
### Canonical
A canonical LAB uses versioned source, provider, graph and run contracts. Its
runner automatically publishes identity, configuration, method, runtime,
resources, metrics, gates, artifacts, visual evidence, limitations and retained
authority. Adding an ordinary canonical LAB must not add an experiment-specific
branch to the application shell or product composition root.
The first executable canaries are deliberately limited to:
- E33 worker shadow, for source pacing, queues, worker identity and telemetry;
- E35 degradation/recovery, for deterministic graph variants and safe terminal
accounting;
- E46J raw-fisheye realtime, for model/runtime configuration, GPU capacity and
full visual evidence.
Passing those three canaries closes the laboratory canonicalization slice. It
does not authorize a bulk migration of historical runs.
### Experimental
An experimental LAB may use a stack or execution shape which the current
canonical graph cannot express. It is retained through a bounded adapter or
separate experiment package instead of being deleted or hidden.
It must still freeze:
- the immutable source and derivative inputs;
- code, configuration, model/runtime and provider identities which are known;
- real artifacts, visual evidence and resource observations;
- terminal outcome, limitations and forbidden authority.
An experimental adapter may not silently change generic product behavior,
grant command/navigation/safety authority or require a new visual language.
Repeated demonstrated value is the trigger for promotion into a versioned
provider or graph contract. Novelty by itself is not a failure and is not a
reason to discard evidence.
### Legacy
Legacy LABs remain immutable and read-only through their existing validators and
bounded projectors. Missing historical provenance remains explicit. Legacy code
is changed only for integrity, security, compatibility or preservation defects;
it is not rewritten for cosmetic uniformity.
Legacy evidence may be compared or reused as an input reference, but it does not
become canonical execution evidence retroactively.
## Core admission rule
Architecture tests must prevent uncontrolled core growth, not experimental
work itself. A failure is one of the following:
- a canonical LAB needs a new experiment-named branch in `app.py`, the advanced
LAB dispatcher or the generic workspace;
- evidence publication bypasses identity, artifact or authority validation;
- reusable provider or graph behavior is copied into another experiment;
- an experimental implementation is imported by core without an explicit
bounded adapter and lifecycle classification.
A self-contained experimental package with honest evidence is allowed even when
its stack cannot yet satisfy the canonical graph.
## Worker and telemetry boundary
The compute-contour catalog, selector, generic MQTT topic namespace and telemetry
query path already support more than one contour. They do not constitute worker
provisioning. Credential enrollment, a digest-bound agent bundle and an accepted
second agent remain open. Installing GPU drivers, Docker/WSL, Triton, models and
the perception runtime is a separate deployment-profile problem and is not folded
into a universal one-click installer.
Local telemetry stabilization is part of the architecture freeze: multi-contour
credential issuance, executable agent installation, bounded journal rotation,
restart/reconnect/duplicate handling, stale and identity-mismatch behavior, and
run correlation must be accepted. Fleet TLS, Linux acceptance, HA and production
storage/deployment remain explicit intentional debt until their deployment trigger
exists.
## Consequences
- The historical archive remains useful without dictating current code shape.
- Three representative LABs, not the whole archive, prove the executable canon.
- A new research stack has a legitimate bounded path and is not forced into a
premature universal abstraction.
- The product core grows only when repeated value justifies a reusable contract.
- Debt is not treated as a binary pass/fail list: every deferred item names the
claim it blocks and the event which returns it to the critical path.