refactor(platform): bound lab canon and contour identity
This commit is contained in:
@@ -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 агента"/);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user