generated from coulomb/repo-seed
Add container smoke acceptance
This commit is contained in:
@@ -1,17 +1,16 @@
|
|||||||
<!-- custodian-brief: generated by fix-consistency — do not edit manually -->
|
<!-- custodian-brief: generated by fix-consistency — do not edit manually -->
|
||||||
# Custodian Brief — guide-board
|
# Custodian Brief — guide-board
|
||||||
|
|
||||||
**Domain:** markitect
|
**Domain:** markitect
|
||||||
**Last synced:** 2026-05-15 12:41 UTC
|
**Last synced:** 2026-05-15 12:43 UTC
|
||||||
**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)*
|
**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)*
|
||||||
|
|
||||||
## Active Workstreams
|
## Active Workstreams
|
||||||
|
|
||||||
### Assessment Operations Baseline
|
### Assessment Operations Baseline
|
||||||
Progress: 4/6 done | workstream_id: `fc5b1573-91b2-4a19-b6a9-dd4d17057d9b`
|
Progress: 5/6 done | workstream_id: `fc5b1573-91b2-4a19-b6a9-dd4d17057d9b`
|
||||||
|
|
||||||
**Open tasks:**
|
**Open tasks:**
|
||||||
- ► D2.5 - Container Smoke Acceptance `9e2e7fa7`
|
|
||||||
- · D2.6 - External Extension Acceptance Path `65fbf1df`
|
- · D2.6 - External Extension Acceptance Path `65fbf1df`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ LABEL org.opencontainers.image.title="guide-board-core"
|
|||||||
LABEL org.opencontainers.image.description="Guide Board certification and compliance preparation CLI core."
|
LABEL org.opencontainers.image.description="Guide Board certification and compliance preparation CLI core."
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV GUIDE_BOARD_SCHEMA_DIR=/opt/guide-board/docs/schemas
|
||||||
|
|
||||||
WORKDIR /opt/guide-board
|
WORKDIR /opt/guide-board
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,35 @@ podman run --rm \
|
|||||||
|
|
||||||
The run output remains on the host under `runs/sample-noop`.
|
The run output remains on the host under `runs/sample-noop`.
|
||||||
|
|
||||||
|
## Smoke Check
|
||||||
|
|
||||||
|
Run the reproducible smoke check from the repository root:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scripts/container_smoke.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script:
|
||||||
|
|
||||||
|
- detects `podman` or `docker`,
|
||||||
|
- builds `guide-board-core:smoke`,
|
||||||
|
- mounts a host output directory at `/runs`,
|
||||||
|
- runs the bundled sample assessment,
|
||||||
|
- verifies that the expected run artifacts are present on the host.
|
||||||
|
|
||||||
|
Override the runtime, image name, or output directory when needed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
CONTAINER_RUNTIME=docker \
|
||||||
|
GUIDE_BOARD_SMOKE_IMAGE=guide-board-core:local \
|
||||||
|
GUIDE_BOARD_SMOKE_RUNS_DIR=/tmp/guide-board-container-smoke \
|
||||||
|
scripts/container_smoke.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The smoke check uses only bundled sample profiles and the dependency-light core
|
||||||
|
image. Restricted harness material and extension-specific runtime dependencies
|
||||||
|
must stay in extension-specific images or explicit mounts.
|
||||||
|
|
||||||
## External Profiles
|
## External Profiles
|
||||||
|
|
||||||
Mount project-specific profiles read-only:
|
Mount project-specific profiles read-only:
|
||||||
|
|||||||
52
scripts/container_smoke.sh
Executable file
52
scripts/container_smoke.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||||
|
IMAGE="${GUIDE_BOARD_SMOKE_IMAGE:-guide-board-core:smoke}"
|
||||||
|
RUNS_DIR="${GUIDE_BOARD_SMOKE_RUNS_DIR:-${TMPDIR:-/tmp}/guide-board-container-smoke-$$}"
|
||||||
|
RUNTIME="${CONTAINER_RUNTIME:-}"
|
||||||
|
|
||||||
|
if [ -z "$RUNTIME" ]; then
|
||||||
|
if command -v podman >/dev/null 2>&1; then
|
||||||
|
RUNTIME=podman
|
||||||
|
elif command -v docker >/dev/null 2>&1; then
|
||||||
|
RUNTIME=docker
|
||||||
|
else
|
||||||
|
echo "ERROR: podman or docker is required for the container smoke check." >&2
|
||||||
|
exit 127
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$RUNS_DIR"
|
||||||
|
|
||||||
|
echo "==> Building $IMAGE with $RUNTIME"
|
||||||
|
"$RUNTIME" build -t "$IMAGE" -f "$ROOT_DIR/Containerfile" "$ROOT_DIR"
|
||||||
|
|
||||||
|
echo "==> Running bundled sample assessment"
|
||||||
|
"$RUNTIME" run --rm \
|
||||||
|
-v "$RUNS_DIR:/runs" \
|
||||||
|
"$IMAGE" \
|
||||||
|
--root /opt/guide-board run \
|
||||||
|
--target /opt/guide-board/profiles/targets/sample-repository.json \
|
||||||
|
--assessment /opt/guide-board/profiles/assessments/sample-noop.json \
|
||||||
|
--output-dir /runs/sample-noop
|
||||||
|
|
||||||
|
echo "==> Verifying mounted run artifacts"
|
||||||
|
for path in \
|
||||||
|
"$RUNS_DIR/sample-noop/run.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/plan.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/retention-summary.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/normalized/evidence.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/normalized/findings.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/normalized/mappings.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/reports/assessment-package.json" \
|
||||||
|
"$RUNS_DIR/sample-noop/reports/report.md"
|
||||||
|
do
|
||||||
|
if [ ! -f "$path" ]; then
|
||||||
|
echo "ERROR: expected artifact missing: $path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Container smoke check passed."
|
||||||
|
echo "Run artifacts: $RUNS_DIR/sample-noop"
|
||||||
@@ -7,6 +7,7 @@ project's own draft contracts.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -14,11 +15,23 @@ from guide_board.errors import ValidationError
|
|||||||
from guide_board.io import load_json
|
from guide_board.io import load_json
|
||||||
|
|
||||||
|
|
||||||
SCHEMA_DIR = Path(__file__).resolve().parents[2] / "docs" / "schemas"
|
SOURCE_SCHEMA_DIR = Path(__file__).resolve().parents[2] / "docs" / "schemas"
|
||||||
|
|
||||||
|
|
||||||
def load_schema(schema_name: str) -> dict[str, Any]:
|
def load_schema(schema_name: str) -> dict[str, Any]:
|
||||||
return load_json(SCHEMA_DIR / f"{schema_name}.schema.json")
|
return load_json(_schema_dir() / f"{schema_name}.schema.json")
|
||||||
|
|
||||||
|
|
||||||
|
def _schema_dir() -> Path:
|
||||||
|
env_dir = os.environ.get("GUIDE_BOARD_SCHEMA_DIR")
|
||||||
|
candidates = []
|
||||||
|
if env_dir:
|
||||||
|
candidates.append(Path(env_dir).expanduser())
|
||||||
|
candidates.extend([SOURCE_SCHEMA_DIR, Path.cwd() / "docs" / "schemas"])
|
||||||
|
for candidate in candidates:
|
||||||
|
if (candidate / "target-profile.schema.json").is_file():
|
||||||
|
return candidate
|
||||||
|
return candidates[0]
|
||||||
|
|
||||||
|
|
||||||
def validate_document(document: Any, schema: dict[str, Any], path: str = "$") -> list[str]:
|
def validate_document(document: Any, schema: dict[str, Any], path: str = "$") -> list[str]:
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ Progress:
|
|||||||
|
|
||||||
```task
|
```task
|
||||||
id: GUIDE-BOARD-WP-0002-T005
|
id: GUIDE-BOARD-WP-0002-T005
|
||||||
status: todo
|
status: done
|
||||||
priority: medium
|
priority: medium
|
||||||
state_hub_task_id: "9e2e7fa7-8a97-4f07-9925-e637e0366003"
|
state_hub_task_id: "9e2e7fa7-8a97-4f07-9925-e637e0366003"
|
||||||
```
|
```
|
||||||
@@ -162,6 +162,14 @@ Acceptance:
|
|||||||
- Verify mounted output directories receive run artifacts.
|
- Verify mounted output directories receive run artifacts.
|
||||||
- Keep restricted or extension-specific harness assets outside the core image.
|
- Keep restricted or extension-specific harness assets outside the core image.
|
||||||
|
|
||||||
|
Progress:
|
||||||
|
|
||||||
|
- Added `scripts/container_smoke.sh`.
|
||||||
|
- Documented the smoke check in `docs/CONTAINER.md`.
|
||||||
|
- Verified the smoke check with Docker; mounted outputs received run metadata,
|
||||||
|
normalized evidence, mappings, findings, assessment package, and Markdown
|
||||||
|
report.
|
||||||
|
|
||||||
## D2.6 - External Extension Acceptance Path
|
## D2.6 - External Extension Acceptance Path
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|||||||
Reference in New Issue
Block a user