fix: distinguish admitted RELLIS previews from smoke

This commit is contained in:
DCCONSTRUCTIONS 2026-07-25 21:26:02 +03:00
parent 15821a1c98
commit 21c7a5507c
7 changed files with 91 additions and 22 deletions

View File

@ -601,7 +601,7 @@ export function parseDatasetNativeScanPreview(
if ( if (
safety.visualization_only !== true safety.visualization_only !== true
|| safety.navigation_or_safety_accepted !== false || safety.navigation_or_safety_accepted !== false
|| (isRellis && safety.compatibility_smoke_only !== true) || (isRellis && typeof safety.compatibility_smoke_only !== "boolean")
) { ) {
throw new DatasetGatewayContractError("Dataset preview safety boundary нарушен"); throw new DatasetGatewayContractError("Dataset preview safety boundary нарушен");
} }
@ -639,7 +639,9 @@ export function parseDatasetNativeScanPreview(
evaluationMask, evaluationMask,
classes, classes,
coordinateFrame, coordinateFrame,
compatibilitySmokeOnly: isRellis, compatibilitySmokeOnly: isRellis
? safety.compatibility_smoke_only as boolean
: false,
}; };
} }

View File

@ -78,6 +78,9 @@ function sourceDescription(source: DatasetSource): string {
if (source.sourceKind === "goose") { if (source.sourceKind === "goose") {
return "Восемь фрагментов и 961 разреженный размеченный оборот VLS-128. Здесь уже опубликовано покадровое сравнение текущего ground baseline и Patchwork++."; return "Восемь фрагментов и 961 разреженный размеченный оборот VLS-128. Здесь уже опубликовано покадровое сравнение текущего ground baseline и Patchwork++.";
} }
if (source.admissionStatus === "dataset-ready") {
return "Пять последовательностей Ouster OS1 64: 13 556 scans выровнены с labels, официальными split и pose index. Validation используется для независимой проверки переносимости алгоритмов.";
}
return "Независимый off-road источник с Ouster OS1 64. Сейчас открыт официальный frame 000104 для проверки reader, осей, ontology и ground-policy; полный benchmark ещё не выполнялся."; return "Независимый off-road источник с Ouster OS1 64. Сейчас открыт официальный frame 000104 для проверки reader, осей, ontology и ground-policy; полный benchmark ещё не выполнялся.";
} }

View File

@ -150,12 +150,22 @@ function RellisSmokeReview() {
> >
<header className="dataset-sequence-review__truth"> <header className="dataset-sequence-review__truth">
<div> <div>
<span className="section-eyebrow">RELLIS S0 · COMPATIBILITY SMOKE</span> <span className="section-eyebrow">
<h2>Официальный Ouster scan читается без конвертации формата</h2> {preview.compatibilitySmokeOnly
? "RELLIS S0 · COMPATIBILITY SMOKE"
: "RELLIS · ADMITTED VALIDATION SCAN"}
</span>
<h2>
{preview.compatibilitySmokeOnly
? "Официальный Ouster scan читается без конвертации формата"
: "Полный официальный release принят на worker D"}
</h2>
<p> <p>
Frame {preview.frameId}: исходные XYZI и point-wise labels остались Frame {preview.frameId}: исходные XYZI и point-wise labels остались
выровнены. Это проверка reader, осей, цветов и ground-policy ещё не выровнены. {preview.compatibilitySmokeOnly
сравнение алгоритмов и не основание для навигации. ? "Это проверка reader, осей, цветов и ground-policy — ещё не сравнение алгоритмов."
: "Scan входит в официальный validation split; результат алгоритмов публикуется отдельным квалификационным run."}
{" "}Это не основание для навигации.
</p> </p>
</div> </div>
<dl> <dl>
@ -177,7 +187,10 @@ function RellisSmokeReview() {
<section className="polygon-review-player"> <section className="polygon-review-player">
<header className="polygon-review-player__header"> <header className="polygon-review-player__header">
<div> <div>
<span className="section-eyebrow">OFFICIAL EXAMPLE · FRAME 000104</span> <span className="section-eyebrow">
{preview.compatibilitySmokeOnly ? "OFFICIAL EXAMPLE" : "VALIDATION"}
{" · FRAME "}{preview.frameId}
</span>
<strong>Ouster OS1 64 · X forward · Y left · Z up</strong> <strong>Ouster OS1 64 · X forward · Y left · Z up</strong>
</div> </div>
<div className="polygon-review-mode" aria-label="Режим RELLIS preview"> <div className="polygon-review-mode" aria-label="Режим RELLIS preview">

View File

@ -624,7 +624,10 @@ def read_dataset_native_scan_preview(path: Path) -> dict[str, Any]:
"navigation_or_safety_accepted": False, "navigation_or_safety_accepted": False,
} }
if identity[1] == "rellis-3d/v1.1": if identity[1] == "rellis-3d/v1.1":
expected_safety["compatibility_smoke_only"] = True compatibility_smoke_only = safety.get("compatibility_smoke_only")
if not isinstance(compatibility_smoke_only, bool):
raise DatasetAdmissionError("RELLIS preview scope is incompatible")
expected_safety["compatibility_smoke_only"] = compatibility_smoke_only
if safety != expected_safety: if safety != expected_safety:
raise DatasetAdmissionError("dataset preview safety boundary is incompatible") raise DatasetAdmissionError("dataset preview safety boundary is incompatible")
if not isinstance(document.get("frame_id"), str) or not document["frame_id"]: if not isinstance(document.get("frame_id"), str) or not document["frame_id"]:
@ -670,9 +673,9 @@ def _validate_rellis_preview_metadata(
): ):
raise DatasetAdmissionError("RELLIS class catalog is incompatible") raise DatasetAdmissionError("RELLIS class catalog is incompatible")
evidence = _object(document.get("source_evidence"), "source_evidence") evidence = _object(document.get("source_evidence"), "source_evidence")
if ( common_evidence_valid = (
set(evidence) set(evidence)
!= { == {
"repository_url", "repository_url",
"repository_commit", "repository_commit",
"label_config_sha256", "label_config_sha256",
@ -680,16 +683,31 @@ def _validate_rellis_preview_metadata(
"label_sha256", "label_sha256",
"license", "license",
} }
or evidence.get("repository_url") != "https://github.com/unmannedlab/RELLIS-3D" and evidence.get("repository_url") == "https://github.com/unmannedlab/RELLIS-3D"
or evidence.get("repository_commit") and evidence.get("repository_commit")
!= "c17a118fcaed1559f03cc32cc3a91dedc557f8b8" == "c17a118fcaed1559f03cc32cc3a91dedc557f8b8"
or evidence.get("label_config_sha256") and evidence.get("label_config_sha256")
!= "573379a232ac561805987466c391a61fd5ad338be7fb9c4c2842f3f28067e0ad" == "573379a232ac561805987466c391a61fd5ad338be7fb9c4c2842f3f28067e0ad"
or evidence.get("point_sha256") and evidence.get("license") == "CC-BY-NC-SA-3.0"
!= "ed81a9c3636d55b17d78058c72545d5d22419beecf174d50596d23ae178752af" )
or evidence.get("label_sha256") digest_values = (evidence.get("point_sha256"), evidence.get("label_sha256"))
!= "9b8c65b710873e931af4ac6dfc7d3dd2298696514ab721e50300bd55ad5b634e" digests_valid = all(
or evidence.get("license") != "CC-BY-NC-SA-3.0" isinstance(value, str)
and len(value) == 64
and all(character in "0123456789abcdef" for character in value)
for value in digest_values
)
smoke_only = document["safety"]["compatibility_smoke_only"]
smoke_digests_valid = (
evidence.get("point_sha256")
== "ed81a9c3636d55b17d78058c72545d5d22419beecf174d50596d23ae178752af"
and evidence.get("label_sha256")
== "9b8c65b710873e931af4ac6dfc7d3dd2298696514ab721e50300bd55ad5b634e"
)
if (
not common_evidence_valid
or not digests_valid
or (smoke_only and not smoke_digests_valid)
): ):
raise DatasetAdmissionError("RELLIS source evidence is incompatible") raise DatasetAdmissionError("RELLIS source evidence is incompatible")

View File

@ -195,6 +195,7 @@ def admit_rellis_release(
"label_sha256": hashlib.sha256(label_bytes).hexdigest(), "label_sha256": hashlib.sha256(label_bytes).hexdigest(),
"license": RELLIS_LICENSE, "license": RELLIS_LICENSE,
}, },
compatibility_smoke_only=False,
) )
except (OSError, KeyError, zipfile.BadZipFile, DatasetFrameError, RellisSmokeError) as exc: except (OSError, KeyError, zipfile.BadZipFile, DatasetFrameError, RellisSmokeError) as exc:
raise RellisAdmissionError("RELLIS archives could not be verified") from exc raise RellisAdmissionError("RELLIS archives could not be verified") from exc

View File

@ -143,6 +143,7 @@ def rellis_native_scan_preview(
frame_id: str, frame_id: str,
maximum_points: int, maximum_points: int,
source_evidence: dict[str, str], source_evidence: dict[str, str],
compatibility_smoke_only: bool = True,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Build the common viewer artifact from a validated RELLIS native frame.""" """Build the common viewer artifact from a validated RELLIS native frame."""
@ -243,7 +244,7 @@ def rellis_native_scan_preview(
"source_evidence": source_evidence, "source_evidence": source_evidence,
"safety": { "safety": {
"visualization_only": True, "visualization_only": True,
"compatibility_smoke_only": True, "compatibility_smoke_only": compatibility_smoke_only,
"navigation_or_safety_accepted": False, "navigation_or_safety_accepted": False,
}, },
} }

View File

@ -10,9 +10,9 @@ from fastapi import APIRouter
from fastapi.routing import APIRoute from fastapi.routing import APIRoute
from k1link.datasets import ( from k1link.datasets import (
RELLIS_SOURCE_ID,
DatasetAdmissionError, DatasetAdmissionError,
DatasetFrameError, DatasetFrameError,
RELLIS_SOURCE_ID,
dataset_gateway_catalog, dataset_gateway_catalog,
goose_admission, goose_admission,
goose_benchmark, goose_benchmark,
@ -355,6 +355,37 @@ def test_rellis_smoke_preview_keeps_semantickitti_alignment_and_ignore_policy(
rellis = catalog["sources"][1] # type: ignore[index] rellis = catalog["sources"][1] # type: ignore[index]
assert rellis["admission"]["status"] == "smoke-ready" # type: ignore[index] assert rellis["admission"]["status"] == "smoke-ready" # type: ignore[index]
admission_path = tmp_path / "rellis-admission.json"
admission_path.write_text(
json.dumps(
{
"schema_version": "missioncore.rellis-admission/v1",
"source_id": "rellis-3d/v1.1",
"status": "dataset-ready",
"storage": {
"policy": "worker-d-only",
"admitted": True,
"path_exposed": False,
},
"alignment": {
"annotated_scan_count": 13_556,
"point_label_alignment": "complete",
"pose_index_coverage": "complete",
},
"release": {"identity_sha256": "a" * 64},
}
),
encoding="utf-8",
)
admitted = dataset_gateway_catalog(
Path("/mnt/d/NDC_MISSIONCORE/datasets"),
rellis_preview_path=preview_path,
rellis_admission_path=admission_path,
)
admitted_rellis = admitted["sources"][1] # type: ignore[index]
assert admitted_rellis["admission"]["status"] == "dataset-ready" # type: ignore[index]
assert admitted["next_action"] == "qualify-rellis-current-vs-patchworkpp"
def test_goose_current_ground_is_scored_against_independent_labels( def test_goose_current_ground_is_scored_against_independent_labels(
tmp_path: Path, tmp_path: Path,