feat(perception): record E39 R1 refinement

This commit is contained in:
DCCONSTRUCTIONS
2026-07-28 10:06:31 +03:00
parent c018f2b074
commit 6e5124bd9c
12 changed files with 2197 additions and 1 deletions
@@ -718,6 +718,18 @@ Execution was strictly sequential through E35: E30 determined what E31 was
allowed to change; E31 determined the E32 profile; E32 determined the E33
runtime input; E32/E33 then bound the E34 layer; E32E34 then bound E35.
Exact nominal and degradation accounting are closed, so A8 is complete.
R1 perception quality is now measured by two immutable Worker 006 results.
E38 established the baseline at 82.2% presence, 81.5% geometry association,
95.2% freshness and 14 high-severity failures. E39 result
`e39-perception-refinement-2fd253940c9d9a2fd3b3237f3f0932f81a9f69741935d793771243d5779af464`
used a fixed package-bound camera + LiDAR feature projection and improved
presence and geometry association to 84.9% while reducing high-severity
failures to 8. Freshness remained above target at 93.2%. Its development
cross-validation exceeded 90% but did not predict the sealed result, so R1
remains open. The next iteration is development-only grouped time/scene
qualification with a source-coordinate-free representation; validation is not
opened for item-level tuning.
E36 is the first generalization gate. A separate product decision follows:
either keep the result as operator/shadow evidence, or start L5 occupied-space
integration. No LAB in this cycle can enable navigation, commands or safety
@@ -246,9 +246,18 @@ The first R1 baseline is E38 immutable Worker 006 result
Its sealed 146-item validation measures presence at 82.2%, geometry
association at 81.5% and freshness at 95.2%, with 100% accounting, zero
false-free claims and 14 high-severity failures. R1 therefore remains open;
the next bounded iteration targets detector/background presence and
the next bounded iteration targeted detector/background presence and
geometry-only association without changing the E37 validation set.
E39 completed that refinement in immutable Worker 006 result
`e39-perception-refinement-2fd253940c9d9a2fd3b3237f3f0932f81a9f69741935d793771243d5779af464`.
Five-fold development CV crossed 90% for all three dimensions without
validation-label access. Sealed validation improved presence to 84.9%,
geometry association to 84.9% and reduced high-severity failures from 14 to
8; freshness remained above target at 93.2%. The aggregate gate remains
failed. R1 now advances to a harder grouped time/scene development protocol
and a source-coordinate-free representation before any new sealed evaluation.
- [x] Reproduce all 4,489 immutable E29 frames with the exact frozen profile
before applying E31/E30 changes.
- [x] Apply only the admitted semantic self-mask, two exact geometry
@@ -78,6 +78,22 @@ high-severity validation cases fail, so R1 is not accepted. The next R1
iteration is bounded to detector/background presence, geometry-only
association and the camera-only freshness tail without changing validation.
The second R1 measurement is immutable result
`e39-perception-refinement-2fd253940c9d9a2fd3b3237f3f0932f81a9f69741935d793771243d5779af464`.
Its fixed robust three-neighbour refinement used exact camera-crop, LiDAR
shape and projection features and was selected only through five-fold
development cross-validation. Development reached 90.3% presence, 90.6%
geometry association and 96.5% freshness without validation-label access.
Sealed validation reached 84.9%, 84.9% and 93.2% respectively. Accounting
remains 100%, false-free claims remain zero and high-severity failures fall
from 14 to 8, but R1 is still not accepted.
The next R1 iteration must address the development-to-validation gap before
adding model complexity: grouped time/scene development folds replace
item-hash folds, and a source-coordinate-free representation is compared under
that harder protocol. No individual E39 validation label may be used for
diagnosis, fitting or selection.
## Experiment rules
1. RAVNOVES00 remains immutable and is never relabelled as a LAB result.
@@ -0,0 +1,167 @@
# LAB E39 — RAVNOVES00 R1 perception refinement
Date: 2026-07-28
Status: completed refinement; R1 quality gate not passed
## Why this LAB exists
E38 established the first immutable R1 baseline on the frozen E37 contract:
82.2% presence, 81.5% geometry association, 95.2% freshness and 14
high-severity failures. E39 tests whether a richer exact camera + LiDAR
representation can close that gap without fitting or selecting against the
sealed validation labels.
The experiment remains source-scoped to RAVNOVES00. It does not evaluate
navigation, planning, commands, safety or transfer to another route or rig.
## Immutable inputs
| Input | Identity |
| --- | --- |
| Physical source | `20260720T065719Z_viewer_live` (`RAVNOVES00`) |
| Frozen E37 contract | `e37-ravnoves-acceptance-01b1efd586f747341c712d82f0907b39436a6f91ae92b1dfae987eca05fd8344` |
| E37 item digest | `c6e4f474f59867ce0cc86825193043245c227106400cc216a2dac0645dca54ab` |
| E30 materialization | `e30-materialization-841af926d8d28ab93538c46d8f31278a2234c4d1c12c7dc4dc296b249d59735a` |
| E30 item digest | `827b498c7b7ab520cc3998e288134ebb5a2e8ebba0532d5cc3905e1a4460b0a7` |
| E39 profile | `e39-ravnoves00-r1-development-knn/v1` |
| Profile digest | `805828c1eee7b680325c0e72acca0b6a700ead1d267b2745ad7e5227ad6dce34` |
The denominator is unchanged: 486 reviewed cases split into 340 development
and 146 sealed validation cases.
## Method
E39 derives 262 deterministic features for each immutable E37 case:
- source frame and case ordinal;
- source stratum, range and geometry categories;
- LiDAR point counts, axis quantiles, covariance ratios and class fractions;
- projected pixel, depth and height distributions;
- a fixed 6×6 RGB camera crop plus luminance quantiles.
Features are robustly scaled from development statistics. Presence is
predicted by a fixed three-neighbour classifier. Geometry association and
freshness are projected from predicted presence plus the immutable source
stratum; they are not independent learned models in E39.
The fixed profile is admitted only if deterministic five-fold development
cross-validation reaches all three 90% targets. The split seed is
`e39-dev-cv`. Validation labels are neither read by feature construction nor
used for fitting, threshold selection or model selection. After development
qualification, the frozen model is evaluated once on all 146 sealed cases.
The package includes a digest-bound feature cache so the pinned Worker image
requires only NumPy at execution time. Exact camera images and point arrays
remain packaged for audit. Cache manifest, feature names, arrays, package
contents and result artifacts are independently hashed.
## Development qualification
| Dimension | Correct | Accuracy | Target | Development gate |
| --- | ---: | ---: | ---: | --- |
| Presence | 307 / 340 | 90.3% | >= 90% | pass |
| Geometry association | 308 / 340 | 90.6% | >= 90% | pass |
| Freshness | 328 / 340 | 96.5% | >= 90% | pass |
This qualification authorized one sealed evaluation. It did not authorize a
release decision by itself.
## Worker execution
| Property | Value |
| --- | --- |
| Worker | `DESKTOP-OPJ8J04` (`Worker 006`) |
| Worker package | `e39-worker-package-4902eafcc3fff1750d807775214d4262d777ad628a3532128b2cb55625f46b25` |
| Package materialization | 967 files, 65,139,625 bytes |
| Container | `ndc-mission-core-e39-refinement` |
| Pinned image | `nvcr.io/nvidia/tritonserver:26.06-py3@sha256:58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794` |
| Network | disabled |
| Limits | 2 CPU, 1 GiB memory and swap, 128 PIDs |
| Filesystem | read-only runtime, explicit output mount, 64 MiB no-exec tmpfs |
| Authority | commands false; navigation/safety acceptance false |
The run was executed sequentially to preserve the 18 GiB operator machine and
the shared Worker. The immutable result was copied back from Worker 006 and
validated against its manifest and artifact digests.
## Official result
Result identity:
`e39-perception-refinement-2fd253940c9d9a2fd3b3237f3f0932f81a9f69741935d793771243d5779af464`
| Dimension | Correct | Accuracy | Target | Gate |
| --- | ---: | ---: | ---: | --- |
| Presence | 124 / 146 | 84.9% | >= 90% | fail |
| Geometry association | 124 / 146 | 84.9% | >= 90% | fail |
| Freshness | 136 / 146 | 93.2% | >= 90% | pass |
| Evidence accounting | 146 / 146 | 100% | 100% | pass |
| False-free claims | 0 | — | 0 | pass |
| High-severity failures | 8 | — | 0 | fail |
The R1 quality gate is not passed. Blocking checks are presence target,
geometry-association target and zero high-severity failures.
### Change from E38
| Measure | E38 | E39 | Change |
| --- | ---: | ---: | ---: |
| Presence | 82.2% | 84.9% | +2.7 percentage points |
| Geometry association | 81.5% | 84.9% | +3.4 percentage points |
| Freshness | 95.2% | 93.2% | -2.0 percentage points |
| High-severity failures | 14 | 8 | -6 |
E39 is a real improvement in presence, geometry and severe-error count, but it
does not satisfy the acceptance contract. The development-to-validation gap
is approximately 5.4 percentage points for presence and 5.7 points for
geometry association.
### Remaining weak strata
- Presence and geometry association are both 79.5% on `camera-only`.
- Presence and geometry association are both 78.9% on `geometry-only`.
- Freshness is 79.5% on `camera-only`.
- `conflict` is 100%, but contains only 11 validation cases and must not mask
the larger weak strata.
The observed CV-to-validation gap is consistent with insufficiently
independent development folds and an overly source-local representation,
especially because source-frame coordinates are explicit features. This is an
engineering interpretation, not a proven causal diagnosis.
## What E39 proves
- Richer exact camera + LiDAR features improve E38 on the same frozen source.
- The complete Worker packaging and package-bound cache are reproducible
without modifying the pinned runtime image.
- All 146 validation cases receive terminal outcomes.
- Accounting remains 100% and no missing evidence becomes asserted free
space.
- High-severity failures fall from 14 to 8.
## What E39 does not prove
- Presence and geometry association do not reach 90%.
- The development CV estimate is not sufficiently predictive of sealed
validation.
- The source-coordinate-heavy representation is not route-independent.
- E39 does not prove another camera, mount, K1 unit, vegetation environment
or rover installation.
- E39 grants no navigation, command, planning or safety authority.
## Decision and next iteration
Keep E39 immutable as the second measured R1 result. Do not retune the
three-neighbour model against its sealed predictions.
The next R1 iteration must be developed only on the 340 development cases and
must first replace optimistic item-hash folds with deterministic grouped
time/scene folds. It should then compare a source-coordinate-free
representation against E39 under that harder development protocol. A new
sealed evaluation is allowed only if the grouped development gate reaches all
three targets and the method is frozen under a new LAB identity.
Individual validation labels remain unavailable for error mining or parameter
selection. Aggregate E39 metrics may be reported as historical evidence but
must not become training features.
@@ -0,0 +1,29 @@
{
"authority": {
"commands_enabled": false,
"navigation_or_safety_accepted": false
},
"model": {
"cross_validation_folds": 5,
"cross_validation_seed": "e39-dev-cv",
"feature_set": "source-scoped-camera-lidar-shape-v1",
"neighbors": 3,
"robust_clip": 20.0,
"type": "deterministic-robust-knn"
},
"profile_id": "e39-ravnoves00-r1-development-knn/v1",
"schema_version": "missioncore.e39-perception-refinement-profile/v1",
"source": {
"acceptance_result_id": "e37-ravnoves-acceptance-01b1efd586f747341c712d82f0907b39436a6f91ae92b1dfae987eca05fd8344",
"display_name": "RAVNOVES00",
"materialization_id": "e30-materialization-841af926d8d28ab93538c46d8f31278a2234c4d1c12c7dc4dc296b249d59735a",
"session_id": "20260720T065719Z_viewer_live"
},
"targets": {
"accounting_target": 1.0,
"freshness_target": 0.9,
"geometry_association_target": 0.9,
"maximum_false_free_claims": 0,
"presence_target": 0.9
}
}
@@ -0,0 +1,440 @@
#!/usr/bin/env python3
"""Build an immutable camera/LiDAR E39 package for Worker 006."""
from __future__ import annotations
import argparse
import hashlib
import io
import json
import os
import shutil
import uuid
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
import numpy as np
from k1link.compute.e39_perception_refinement import (
_FEATURE_CACHE_ARRAYS,
_FEATURE_CACHE_MANIFEST,
_FEATURE_CACHE_SCHEMA,
E39_PACKAGE_SCHEMA,
E39_PROFILE_SCHEMA,
_feature_names,
_feature_vector,
)
_RUNTIME_FILES = {
"runtime/k1link/__init__.py": "src/k1link/__init__.py",
"runtime/k1link/compute/__init__.py": None,
"runtime/k1link/compute/e37_acceptance_contract.py": (
"src/k1link/compute/e37_acceptance_contract.py"
),
"runtime/k1link/compute/e39_perception_refinement.py": (
"src/k1link/compute/e39_perception_refinement.py"
),
"runtime/run_e39_perception_refinement.py": (
"experiments/perception/worker/run_e39_perception_refinement.py"
),
"runtime/Invoke-E39PerceptionRefinement.ps1": (
"experiments/perception/worker/Invoke-E39PerceptionRefinement.ps1"
),
}
_GENERATED_COMPUTE_INIT = (
'"""Minimal E39 worker projection; import contract modules explicitly."""\n'
)
_ACCEPTANCE_FILES = (
"manifest.json",
"acceptance-items.jsonl",
"acceptance-contract.json",
"run-report.json",
)
_MATERIALIZATION_FILES = ("manifest.json", "materialized-items.jsonl")
class E39WorkerPackageError(RuntimeError):
"""The E39 package source or immutable package is invalid."""
def build_e39_worker_package(
*,
repository_root: Path,
acceptance_root: Path,
materialization_root: Path,
profile_path: Path,
output_root: Path,
) -> Path:
"""Build or verify one content-addressed E39 worker package."""
repository = repository_root.resolve(strict=True)
profile_source = profile_path.resolve(strict=True)
profile = _read_json(profile_source)
if profile.get("schema_version") != E39_PROFILE_SCHEMA:
raise E39WorkerPackageError("E39 package profile is incompatible")
acceptance = acceptance_root.resolve(strict=True)
materialization = materialization_root.resolve(strict=True)
expected_ids = {
"acceptance": profile["source"]["acceptance_result_id"],
"materialization": profile["source"]["materialization_id"],
}
if (
acceptance.name != expected_ids["acceptance"]
or materialization.name != expected_ids["materialization"]
):
raise E39WorkerPackageError("E39 source identity changed")
sources: dict[str, Path | bytes | None] = {}
for target, relative in _RUNTIME_FILES.items():
source = None if relative is None else repository / relative
if source is not None and (not source.is_file() or source.is_symlink()):
raise E39WorkerPackageError(f"E39 runtime source is invalid: {relative}")
sources[target] = source
sources["profile.json"] = profile_source
for filename in _ACCEPTANCE_FILES:
source = acceptance / filename
if not source.is_file() or source.is_symlink():
raise E39WorkerPackageError("E39 acceptance artifact is invalid")
sources[
f"input/acceptance/{acceptance.name}/{filename}"
] = source
for filename in _MATERIALIZATION_FILES:
source = materialization / filename
if not source.is_file() or source.is_symlink():
raise E39WorkerPackageError("E39 materialization artifact is invalid")
sources[
f"input/materialization/{materialization.name}/{filename}"
] = source
_add_materialized_evidence(
sources,
materialization=materialization,
)
_add_feature_cache(
sources,
acceptance=acceptance,
materialization=materialization,
)
descriptors = []
for relative, source in sorted(sources.items()):
payload = (
_GENERATED_COMPUTE_INIT.encode()
if source is None
else source
if isinstance(source, bytes)
else source.read_bytes()
)
descriptors.append(
{
"path": relative,
"byte_length": len(payload),
"sha256": hashlib.sha256(payload).hexdigest(),
}
)
identity = {
"schema_version": E39_PACKAGE_SCHEMA,
"classification": "immutable-ravnoves00-r1-camera-lidar-worker-input",
"source_ids": expected_ids,
"profile_sha256": _sha256(profile_source),
"runtime_requirements": {
"python": "3.12",
"numpy": "1.26+",
},
"build_requirements": {"pillow": "10+"},
"artifact_paths": [row["path"] for row in descriptors],
"source_artifacts": descriptors,
"authority": {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
},
}
identity_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
package_id = f"e39-worker-package-{identity_sha256}"
output = output_root.expanduser().absolute()
output.mkdir(mode=0o700, parents=True, exist_ok=True)
destination = output / package_id
if destination.exists():
validate_e39_worker_package(destination)
return destination
staging = output / f".{package_id}.{uuid.uuid4().hex}.tmp"
staging.mkdir(mode=0o700, exist_ok=False)
try:
for relative, source in sources.items():
target = staging / relative
target.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
if source is None:
target.write_text(_GENERATED_COMPUTE_INIT, encoding="utf-8")
elif isinstance(source, bytes):
target.write_bytes(source)
else:
shutil.copyfile(source, target)
artifacts = [
{
"kind": relative,
"path": relative,
"byte_length": (staging / relative).stat().st_size,
"sha256": _sha256(staging / relative),
}
for relative in sorted(sources)
]
manifest = {
"schema_version": E39_PACKAGE_SCHEMA,
"package_id": package_id,
"identity_sha256": identity_sha256,
"identity": identity,
"created_at_utc": datetime.now(UTC)
.isoformat(timespec="milliseconds")
.replace("+00:00", "Z"),
"artifacts": artifacts,
}
_write_json(staging / "manifest.json", manifest)
validate_e39_worker_package(staging, allow_staging=True)
os.replace(staging, destination)
except BaseException:
shutil.rmtree(staging, ignore_errors=True)
raise
validate_e39_worker_package(destination)
return destination
def validate_e39_worker_package(
root: Path,
*,
allow_staging: bool = False,
) -> dict[str, Any]:
"""Validate package identity, exact file set, and every member digest."""
resolved = root.resolve(strict=True)
manifest = _read_json(resolved / "manifest.json")
identity = manifest.get("identity")
identity_sha256 = manifest.get("identity_sha256")
package_id = manifest.get("package_id")
artifacts = manifest.get("artifacts")
expected_name = (
isinstance(package_id, str)
and (
resolved.name == package_id
or (
allow_staging
and resolved.name.startswith(f".{package_id}.")
and resolved.name.endswith(".tmp")
)
)
)
if (
manifest.get("schema_version") != E39_PACKAGE_SCHEMA
or not isinstance(identity, dict)
or not isinstance(identity_sha256, str)
or hashlib.sha256(_canonical_json(identity)).hexdigest() != identity_sha256
or package_id != f"e39-worker-package-{identity_sha256}"
or not expected_name
or not isinstance(artifacts, list)
):
raise E39WorkerPackageError("E39 worker package identity is invalid")
expected_paths = set(identity.get("artifact_paths", []))
actual_paths = {
path.relative_to(resolved).as_posix()
for path in resolved.rglob("*")
if path.is_file()
}
if (
not expected_paths
or actual_paths != expected_paths | {"manifest.json"}
or len(artifacts) != len(expected_paths)
):
raise E39WorkerPackageError("E39 worker package file set changed")
observed: set[str] = set()
for row in artifacts:
if not isinstance(row, dict):
raise E39WorkerPackageError("E39 worker package artifact is invalid")
relative = row.get("path")
path = resolved / str(relative)
if (
not isinstance(relative, str)
or relative not in expected_paths
or relative in observed
or Path(relative).is_absolute()
or ".." in Path(relative).parts
or not path.is_file()
or path.is_symlink()
or row.get("kind") != relative
or row.get("byte_length") != path.stat().st_size
or row.get("sha256") != _sha256(path)
):
raise E39WorkerPackageError("E39 worker package artifact changed")
observed.add(relative)
if observed != expected_paths:
raise E39WorkerPackageError("E39 worker package coverage changed")
return manifest
def _add_materialized_evidence(
sources: dict[str, Path | bytes | None],
*,
materialization: Path,
) -> None:
rows = _read_jsonl(materialization / "materialized-items.jsonl")
if len(rows) != 486:
raise E39WorkerPackageError("E39 materialization denominator changed")
for row in rows:
for descriptor_name in ("artifact", "camera_frame"):
descriptor = row.get(descriptor_name)
if not isinstance(descriptor, dict):
raise E39WorkerPackageError(
"E39 materialization descriptor is invalid"
)
relative = descriptor.get("path")
if (
not isinstance(relative, str)
or Path(relative).is_absolute()
or ".." in Path(relative).parts
):
raise E39WorkerPackageError("E39 materialization path is invalid")
source = materialization / relative
if (
not source.is_file()
or source.is_symlink()
or descriptor.get("byte_length") != source.stat().st_size
or descriptor.get("sha256") != _sha256(source)
):
raise E39WorkerPackageError(
"E39 materialized evidence content changed"
)
target = (
f"input/materialization/{materialization.name}/{relative}"
)
existing = sources.get(target)
if existing is not None and existing != source:
raise E39WorkerPackageError("E39 package target collision")
sources[target] = source
def _add_feature_cache(
sources: dict[str, Path | bytes | None],
*,
acceptance: Path,
materialization: Path,
) -> None:
acceptance_rows = _read_jsonl(acceptance / "acceptance-items.jsonl")
materialization_rows = _read_jsonl(
materialization / "materialized-items.jsonl"
)
acceptance_by_id = {
str(row["item_id"]): row for row in acceptance_rows
}
if (
len(acceptance_by_id) != 486
or {str(row["item_id"]) for row in materialization_rows}
!= set(acceptance_by_id)
):
raise E39WorkerPackageError("E39 feature-cache denominator changed")
item_ids = [str(row["item_id"]) for row in materialization_rows]
features = np.asarray(
[
_feature_vector(
acceptance_by_id[item_id],
row,
materialization,
)
for item_id, row in zip(item_ids, materialization_rows, strict=True)
],
dtype=np.float64,
)
names = _feature_names()
if features.shape != (486, len(names)) or not np.isfinite(features).all():
raise E39WorkerPackageError("E39 feature-cache matrix is invalid")
arrays_stream = io.BytesIO()
np.savez_compressed(
arrays_stream,
item_ids=np.asarray(item_ids, dtype=f"<U{max(map(len, item_ids))}"),
features=features,
)
arrays_payload = arrays_stream.getvalue()
manifest = {
"schema_version": _FEATURE_CACHE_SCHEMA,
"materialization_id": materialization.name,
"materialization_index_sha256": _sha256(
materialization / "materialized-items.jsonl"
),
"feature_names_sha256": hashlib.sha256(
_canonical_json(names)
).hexdigest(),
"items": 486,
"dimensions": len(names),
"arrays_path": _FEATURE_CACHE_ARRAYS,
"arrays_byte_length": len(arrays_payload),
"arrays_sha256": hashlib.sha256(arrays_payload).hexdigest(),
}
manifest_payload = (
json.dumps(manifest, indent=2, sort_keys=True) + "\n"
).encode()
prefix = f"input/materialization/{materialization.name}"
sources[f"{prefix}/{_FEATURE_CACHE_ARRAYS}"] = arrays_payload
sources[f"{prefix}/{_FEATURE_CACHE_MANIFEST}"] = manifest_payload
def _canonical_json(value: object) -> bytes:
return json.dumps(
value,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
).encode()
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while chunk := stream.read(1024 * 1024):
digest.update(chunk)
return digest.hexdigest()
def _read_json(path: Path) -> dict[str, Any]:
value = json.loads(path.read_text(encoding="utf-8-sig"))
if not isinstance(value, dict):
raise E39WorkerPackageError(f"JSON object expected: {path.name}")
return value
def _read_jsonl(path: Path) -> list[dict[str, Any]]:
rows = [
json.loads(line)
for line in path.read_text(encoding="utf-8-sig").splitlines()
]
if not all(isinstance(row, dict) for row in rows):
raise E39WorkerPackageError(f"JSONL object expected: {path.name}")
return rows
def _write_json(path: Path, value: object) -> None:
with path.open("x", encoding="utf-8", newline="\n") as stream:
json.dump(value, stream, indent=2, sort_keys=True)
stream.write("\n")
stream.flush()
os.fsync(stream.fileno())
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--repository-root", type=Path, required=True)
parser.add_argument("--acceptance", type=Path, required=True)
parser.add_argument("--materialization", type=Path, required=True)
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--output-root", type=Path, required=True)
args = parser.parse_args()
package = build_e39_worker_package(
repository_root=args.repository_root,
acceptance_root=args.acceptance,
materialization_root=args.materialization,
profile_path=args.profile,
output_root=args.output_root,
)
print(package)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Build the development-qualified RAVNOVES00 R1 refinement."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from k1link.compute.e39_perception_refinement import (
build_e39_perception_refinement,
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--acceptance", type=Path, required=True)
parser.add_argument("--materialization", type=Path, required=True)
parser.add_argument("--profile", type=Path, required=True)
parser.add_argument("--output-root", type=Path, required=True)
parser.add_argument("--worker-node", default=os.environ.get("COMPUTERNAME"))
args = parser.parse_args()
result = build_e39_perception_refinement(
acceptance_root=args.acceptance,
materialization_root=args.materialization,
profile_path=args.profile,
output_root=args.output_root,
worker_node=args.worker_node,
)
print(
json.dumps(
{
"result_id": result.result_id,
"result_root": str(result.result_root),
"quality_gate_passed": result.quality_gate_passed,
"development_cross_validation": result.report[
"development_cross_validation"
],
"metrics": result.report["metrics"],
"blocking_checks": result.report["quality_gate"][
"blocking_checks"
],
},
ensure_ascii=False,
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,138 @@
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$PackageRoot,
[string]$OutputRoot = "D:\NDC_MISSIONCORE\runtime\derived\e39-refinement",
[string]$ContainerImage = "nvcr.io/nvidia/tritonserver:26.06-py3@sha256:58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794",
[ValidateRange(1, 1000)]
[int]$FreeGiBFloor = 300
)
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
function Assert-LastExitCode([string]$Operation) {
if ($LASTEXITCODE -ne 0) {
throw "$Operation failed with exit code $LASTEXITCODE"
}
}
function Resolve-DDirectory([string]$Path, [string]$Label) {
$item = Get-Item -LiteralPath (Resolve-Path -LiteralPath $Path).Path -Force
$root = [IO.Path]::GetPathRoot($item.FullName).TrimEnd("\")
if (
-not $item.PSIsContainer -or
($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
$root -ine "D:"
) {
throw "$Label must be a real D: directory"
}
return $item.FullName
}
function Convert-ToDockerPath([string]$Path) {
return $Path.Replace("\", "/")
}
function Assert-FreeSpace([string]$Phase) {
$free = [int64](Get-PSDrive -Name D).Free
$floor = [int64]$FreeGiBFloor * 1GB
Write-Host (
"DISK_GUARD PHASE={0} DRIVE=D FREE_BYTES={1} FREE_GIB={2} FLOOR_GIB={3}" -f
$Phase, $free, [math]::Round($free / 1GB, 3), $FreeGiBFloor
)
if ($free -lt ($floor + 1GB)) {
throw "D: lacks the guarded E39 reserve during $Phase"
}
return $free
}
$package = Resolve-DDirectory $PackageRoot "E39 package"
$packageManifestPath = Join-Path $package "manifest.json"
if (-not (Test-Path -LiteralPath $packageManifestPath -PathType Leaf)) {
throw "E39 package manifest is missing"
}
$packageManifest = Get-Content -LiteralPath $packageManifestPath -Raw |
ConvertFrom-Json
if (
$packageManifest.schema_version -ne "missioncore.e39-worker-package/v1" -or
$packageManifest.package_id -ne (Split-Path $package -Leaf) -or
$packageManifest.package_id -notmatch "^e39-worker-package-[a-f0-9]{64}$"
) {
throw "E39 package manifest is incompatible"
}
if (-not (Test-Path -LiteralPath $OutputRoot)) {
$null = New-Item -ItemType Directory -Path $OutputRoot
}
$output = Resolve-DDirectory $OutputRoot "E39 output root"
$freeBefore = Assert-FreeSpace "preflight"
& docker image inspect $ContainerImage *> $null
Assert-LastExitCode "Pinned E39 container image inspection"
$dockerPackage = Convert-ToDockerPath $package
$dockerOutput = Convert-ToDockerPath $output
$packageName = Split-Path $package -Leaf
$containerPackage = "/opt/e39-input/$packageName"
$command = @(
"run", "--rm",
"--name", "ndc-mission-core-e39-refinement",
"--network", "none",
"--read-only",
"--security-opt", "no-new-privileges:true",
"--cap-drop", "ALL",
"--pids-limit", "128",
"--memory", "1g",
"--memory-swap", "1g",
"--cpus", "2",
"--tmpfs", "/tmp:rw,noexec,nosuid,size=64m",
"-e", "PYTHONDONTWRITEBYTECODE=1",
"-e", ("PYTHONPATH={0}/runtime" -f $containerPackage),
"-e", ("E39_WORKER_NODE={0}" -f $env:COMPUTERNAME),
"-v", ("{0}:{1}:ro" -f $dockerPackage, $containerPackage),
"-v", ("{0}:/output:rw" -f $dockerOutput),
"--entrypoint", "python3",
$ContainerImage,
("{0}/runtime/run_e39_perception_refinement.py" -f $containerPackage),
"--package", $containerPackage,
"--output-root", "/output"
)
Write-Output ("PACKAGE_ID={0}" -f $packageManifest.package_id)
Write-Output ("PACKAGE_IDENTITY_SHA256={0}" -f $packageManifest.identity_sha256)
Write-Output ("CONTAINER_IMAGE={0}" -f $ContainerImage)
& docker @command
Assert-LastExitCode "E39 perception refinement"
$matches = @(
Get-ChildItem -LiteralPath $output -Directory -Filter "e39-perception-refinement-*" |
Where-Object {
$manifestPath = Join-Path $_.FullName "manifest.json"
if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) {
return $false
}
$manifest = Get-Content -LiteralPath $manifestPath -Raw |
ConvertFrom-Json
return (
$manifest.schema_version -eq
"missioncore.e39-perception-refinement/v1" -and
$manifest.acceptance_state -eq
"completed-r1-source-scoped-refinement" -and
$manifest.identity.execution.worker_node -eq $env:COMPUTERNAME
)
}
)
if ($matches.Count -ne 1) {
throw "E39 immutable result could not be resolved uniquely"
}
$resultRoot = $matches[0].FullName
$resultManifest = Get-Content -LiteralPath (
Join-Path $resultRoot "manifest.json"
) -Raw | ConvertFrom-Json
$freeAfter = Assert-FreeSpace "completed"
Write-Output ("RESULT_ROOT={0}" -f $resultRoot)
Write-Output ("RESULT_ID={0}" -f $resultManifest.result_id)
Write-Output ("QUALITY_GATE_PASSED={0}" -f $resultManifest.quality_gate_passed)
Write-Output ("DISK_FREE_BYTES_BEFORE={0}" -f $freeBefore)
Write-Output ("DISK_FREE_BYTES_AFTER={0}" -f $freeAfter)
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Execute a packaged E39 refinement inside the pinned Worker 006 container."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from k1link.compute.e39_perception_refinement import (
build_e39_perception_refinement,
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--package", type=Path, required=True)
parser.add_argument("--output-root", type=Path, required=True)
args = parser.parse_args()
package = args.package.resolve(strict=True)
profile = json.loads((package / "profile.json").read_text(encoding="utf-8"))
acceptance_id = profile["source"]["acceptance_result_id"]
materialization_id = profile["source"]["materialization_id"]
result = build_e39_perception_refinement(
acceptance_root=package / "input" / "acceptance" / acceptance_id,
materialization_root=(
package / "input" / "materialization" / materialization_id
),
profile_path=package / "profile.json",
output_root=args.output_root,
worker_node=os.environ.get("E39_WORKER_NODE"),
)
print(
json.dumps(
{
"result_id": result.result_id,
"result_root": str(result.result_root),
"quality_gate_passed": result.quality_gate_passed,
"metrics": result.report["metrics"],
"blocking_checks": result.report["quality_gate"][
"blocking_checks"
],
},
ensure_ascii=False,
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
from __future__ import annotations
import numpy as np
from k1link.compute.e39_perception_refinement import (
_feature_names,
_fit_robust_scaler,
_predict_presence,
_project_dimensions,
_transform,
)
def test_e39_feature_contract_and_knn_are_deterministic() -> None:
assert len(_feature_names()) == 262
matrix = np.asarray(
[
[0.0, 1.0],
[0.1, 1.1],
[4.9, 5.0],
[5.0, 5.1],
],
dtype=np.float64,
)
median, scale = _fit_robust_scaler(matrix)
transformed = _transform(matrix, median=median, scale=scale, clip=20.0)
first = _predict_presence(
transformed[0],
transformed[1:],
["background", "object", "object"],
neighbors=3,
)
second = _predict_presence(
transformed[0],
transformed[1:],
["background", "object", "object"],
neighbors=3,
)
assert first == second == ("object", 2 / 3)
def test_e39_projects_presence_through_frozen_stratum_ontology() -> None:
assert _project_dimensions("camera-only", "object-present") == {
"presence": "object-present",
"geometry_association": "insufficient-support",
"freshness": "unavailable",
}
assert _project_dimensions("geometry-only", "occupied-environment") == {
"presence": "occupied-environment",
"geometry_association": "independent-occupied",
"freshness": "current",
}
assert _project_dimensions("unknown", "background-or-noise") == {
"presence": "background-or-noise",
"geometry_association": "rejected-nonobject",
"freshness": "current",
}
+73
View File
@@ -0,0 +1,73 @@
from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
def _module() -> object:
path = (
Path(__file__).resolve().parents[1]
/ "experiments"
/ "perception"
/ "prepare_e39_worker_package.py"
)
spec = importlib.util.spec_from_file_location("e39_worker_package_test", path)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
def test_e39_package_contains_bound_camera_lidar_evidence(tmp_path: Path) -> None:
module = _module()
repository = Path(__file__).resolve().parents[1]
acceptance = (
repository
/ ".runtime"
/ "compute-experiments"
/ "e37"
/ "results"
/ (
"e37-ravnoves-acceptance-"
"01b1efd586f747341c712d82f0907b39436a6f91ae92b1dfae987eca05fd8344"
)
)
materialization = (
repository
/ ".runtime"
/ "compute-experiments"
/ "e30"
/ "materializations"
/ (
"e30-materialization-"
"841af926d8d28ab93538c46d8f31278a2234c4d1c12c7dc4dc296b249d59735a"
)
)
package = module.build_e39_worker_package(
repository_root=repository,
acceptance_root=acceptance,
materialization_root=materialization,
profile_path=(
repository
/ "experiments"
/ "perception"
/ "e39_ravnoves00_r1_refinement_profile.json"
),
output_root=tmp_path,
)
manifest = module.validate_e39_worker_package(package)
assert package.name == f"e39-worker-package-{manifest['identity_sha256']}"
assert manifest["identity"]["classification"] == (
"immutable-ravnoves00-r1-camera-lidar-worker-input"
)
assert len(manifest["artifacts"]) > 800
assert (
package
/ "input"
/ "materialization"
/ materialization.name
/ "frames"
/ "frame-001005.jpg"
).is_file()