fix core report inspection and vendored roots
This commit is contained in:
@@ -60,6 +60,7 @@ if [[ -z "${HARNESS:-}" || ! -d "$HARNESS" ]]; then
|
|||||||
fi
|
fi
|
||||||
BASH_DIR="$HARNESS/scripts/bash"
|
BASH_DIR="$HARNESS/scripts/bash"
|
||||||
CASAN_APP_ROOT="${CASAN_APP_ROOT:-${PROJECT_ROOT:-$(cd "$HARNESS/../.." && pwd)}}"
|
CASAN_APP_ROOT="${CASAN_APP_ROOT:-${PROJECT_ROOT:-$(cd "$HARNESS/../.." && pwd)}}"
|
||||||
|
export CASAN_APP_ROOT
|
||||||
VERSION_FILE="$_self/../VERSION"
|
VERSION_FILE="$_self/../VERSION"
|
||||||
[[ -f "$VERSION_FILE" ]] || VERSION_FILE="$HARNESS/../../VERSION"
|
[[ -f "$VERSION_FILE" ]] || VERSION_FILE="$HARNESS/../../VERSION"
|
||||||
|
|
||||||
|
|||||||
@@ -351,6 +351,12 @@ echo "$VENDORED_OUT" | grep -q "Runtime.*Vendored" \
|
|||||||
( cd "$VENDORED" && "$VENDORED_ROOT/bin/casan" version >/dev/null ) \
|
( cd "$VENDORED" && "$VENDORED_ROOT/bin/casan" version >/dev/null ) \
|
||||||
&& pass "project-vendored Core includes a working local CLI" \
|
&& pass "project-vendored Core includes a working local CLI" \
|
||||||
|| fail "project-vendored CLI cannot resolve its Core runtime"
|
|| fail "project-vendored CLI cannot resolve its Core runtime"
|
||||||
|
printf 'vendored consumer smoke\n' > "$VENDORED/input.txt"
|
||||||
|
( cd "$VENDORED" && "$VENDORED_ROOT/bin/casan" run input.txt output.txt agent_step -- printf 'ok\n' >/dev/null ) \
|
||||||
|
&& [ -s "$VENDORED/.specify/logs/cost/metrics.jsonl" ] \
|
||||||
|
&& [ ! -d "$VENDORED_ROOT/.specify" ] \
|
||||||
|
&& pass "vendored CLI exports the consumer project root to harness commands" \
|
||||||
|
|| fail "vendored CLI wrote governed state inside the runtime bundle"
|
||||||
( cd "$VENDORED" && "$DKC" verify-harness >/dev/null ) \
|
( cd "$VENDORED" && "$DKC" verify-harness >/dev/null ) \
|
||||||
&& pass "global launcher resolves and verifies the project-vendored Core" \
|
&& pass "global launcher resolves and verifies the project-vendored Core" \
|
||||||
|| fail "vendored Core is not honored by the global launcher"
|
|| fail "vendored Core is not honored by the global launcher"
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ main { max-width: 1500px; margin: 0 auto; padding: 28px clamp(20px,4vw,48px) 64p
|
|||||||
.hero-meta { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 24px; color: #667085; font: 10px ui-monospace, monospace; }
|
.hero-meta { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 24px; color: #667085; font: 10px ui-monospace, monospace; }
|
||||||
.hero-actions { display: flex; flex-wrap: wrap; gap: 9px; justify-content: flex-end; }
|
.hero-actions { display: flex; flex-wrap: wrap; gap: 9px; justify-content: flex-end; }
|
||||||
.trace-hero { border-radius: 18px; padding: 20px 22px; box-shadow: none; }
|
.trace-hero { border-radius: 18px; padding: 20px 22px; box-shadow: none; }
|
||||||
|
.run-dossier-anchor { scroll-margin-top: 94px; outline: none; }
|
||||||
|
.run-dossier-anchor:focus-visible {
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.22);
|
||||||
|
}
|
||||||
.trace-title { margin: 8px 0 !important; font-size: 18px !important; }
|
.trace-title { margin: 8px 0 !important; font-size: 18px !important; }
|
||||||
.trace-meta { margin-top: 8px; }
|
.trace-meta { margin-top: 8px; }
|
||||||
.rail-spaced { margin-top: 20px; }
|
.rail-spaced { margin-top: 20px; }
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
: empty("No safe evidence fields", "This control has not emitted a sanitized evidence manifest.");
|
: empty("No safe evidence fields", "This control has not emitted a sanitized evidence manifest.");
|
||||||
const actions = `<a class="button secondary" href="${downloadUrl(`/api/v1/reports/run/${encodeURIComponent(report.trace_id)}/export`, { format: "json" })}">JSON evidence</a>
|
const actions = `<a class="button secondary" href="${downloadUrl(`/api/v1/reports/run/${encodeURIComponent(report.trace_id)}/export`, { format: "json" })}">JSON evidence</a>
|
||||||
<a class="button primary" href="${downloadUrl(`/api/v1/reports/run/${encodeURIComponent(report.trace_id)}/export`, { format: "html" })}">Export dossier</a>`;
|
<a class="button primary" href="${downloadUrl(`/api/v1/reports/run/${encodeURIComponent(report.trace_id)}/export`, { format: "html" })}">Export dossier</a>`;
|
||||||
return panel(
|
return `<section id="run-dossier" class="run-dossier-anchor" tabindex="-1">${panel(
|
||||||
"Run assurance",
|
"Run assurance",
|
||||||
"Governed execution dossier",
|
"Governed execution dossier",
|
||||||
"A control-by-control reconstruction backed by sanitized lifecycle evidence.",
|
"A control-by-control reconstruction backed by sanitized lifecycle evidence.",
|
||||||
@@ -219,7 +219,7 @@
|
|||||||
${disclosure("Safe evidence manifest", "Sanitized fields persisted by the harness · hidden by default", manifest, pill(`${entries.length} fields`))}
|
${disclosure("Safe evidence manifest", "Sanitized fields persisted by the harness · hidden by default", manifest, pill(`${entries.length} fields`))}
|
||||||
</div>`,
|
</div>`,
|
||||||
actions,
|
actions,
|
||||||
);
|
)}</section>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderH6() {
|
function renderH6() {
|
||||||
@@ -317,6 +317,16 @@
|
|||||||
try {
|
try {
|
||||||
state.run = await api(`/api/v1/reports/run/${encodeURIComponent(traceId)}`);
|
state.run = await api(`/api/v1/reports/run/${encodeURIComponent(traceId)}`);
|
||||||
setView("runs");
|
setView("runs");
|
||||||
|
const dossier = $("#run-dossier");
|
||||||
|
if (dossier) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
dossier.focus({ preventScroll: true });
|
||||||
|
dossier.scrollIntoView({
|
||||||
|
behavior: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth",
|
||||||
|
block: "start",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showError(`Run report could not be reconstructed: ${error.message}`);
|
showError(`Run report could not be reconstructed: ${error.message}`);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ FR_RE = re.compile(r"\|\s*(FR-\d+)\s*\|\s*([^|]+?)\s*\|")
|
|||||||
|
|
||||||
|
|
||||||
def project_root() -> str:
|
def project_root() -> str:
|
||||||
|
explicit = os.environ.get("CASAN_APP_ROOT")
|
||||||
|
if explicit:
|
||||||
|
return os.path.abspath(explicit)
|
||||||
# Plan-01: harness code lives in packages/casan-harness/; a fixed __file__ parent
|
# Plan-01: harness code lives in packages/casan-harness/; a fixed __file__ parent
|
||||||
# depth lands on the package, not the app. Walk UP for the `.specify` state marker
|
# depth lands on the package, not the app. Walk UP for the `.specify` state marker
|
||||||
# so this resolves the app root whether invoked via packages/... or the .specify facade.
|
# so this resolves the app root whether invoked via packages/... or the .specify facade.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import unittest
|
|||||||
|
|
||||||
|
|
||||||
MODULE = Path(__file__).resolve().parents[1] / "scripts" / "python" / "local_report.py"
|
MODULE = Path(__file__).resolve().parents[1] / "scripts" / "python" / "local_report.py"
|
||||||
|
APP_JS = Path(__file__).resolve().parents[1] / "assets" / "local-viewer" / "app.js"
|
||||||
SPEC = importlib.util.spec_from_file_location("casan_local_report", MODULE)
|
SPEC = importlib.util.spec_from_file_location("casan_local_report", MODULE)
|
||||||
REPORT = importlib.util.module_from_spec(SPEC)
|
REPORT = importlib.util.module_from_spec(SPEC)
|
||||||
assert SPEC.loader
|
assert SPEC.loader
|
||||||
@@ -153,6 +154,13 @@ class LocalReportTests(unittest.TestCase):
|
|||||||
self.assertEqual(report["verdict"], "not_found")
|
self.assertEqual(report["verdict"], "not_found")
|
||||||
self.assertFalse(report["source"]["trace_found"])
|
self.assertFalse(report["source"]["trace_found"])
|
||||||
|
|
||||||
|
def test_trace_inspection_reveals_the_loaded_dossier(self):
|
||||||
|
script = APP_JS.read_text(encoding="utf-8")
|
||||||
|
self.assertIn('id="run-dossier"', script)
|
||||||
|
self.assertIn('tabindex="-1"', script)
|
||||||
|
self.assertIn('dossier.focus({ preventScroll: true })', script)
|
||||||
|
self.assertIn("dossier.scrollIntoView({", script)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -90,6 +90,35 @@ set -e 2>/dev/null || true
|
|||||||
&& pass "out-of-range line ref fails the gate (line-level)" \
|
&& pass "out-of-range line ref fails the gate (line-level)" \
|
||||||
|| fail "line ref did not fail as expected (rc=$RC)"
|
|| fail "line ref did not fail as expected (rc=$RC)"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "===== Plan-10 vendored consumer root ====="
|
||||||
|
CONSUMER="$WORK/consumer"
|
||||||
|
python3 - "$CONSUMER" <<'PY'
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
root = sys.argv[1]
|
||||||
|
os.makedirs(os.path.join(root, "domain"), exist_ok=True)
|
||||||
|
os.makedirs(os.path.join(root, "src"), exist_ok=True)
|
||||||
|
os.makedirs(os.path.join(root, "tests"), exist_ok=True)
|
||||||
|
with open(os.path.join(root, "domain", "requirement.md"), "w", encoding="utf-8") as handle:
|
||||||
|
handle.write("| FR-01 | Consumer root must resolve | required |\n")
|
||||||
|
with open(os.path.join(root, "domain", "traceability-map.json"), "w", encoding="utf-8") as handle:
|
||||||
|
json.dump({"FR-01": {"code": ["src/app.py"], "tests": ["tests/test_app.py"]}}, handle)
|
||||||
|
for relative in ("src/app.py", "tests/test_app.py"):
|
||||||
|
with open(os.path.join(root, relative), "w", encoding="utf-8") as handle:
|
||||||
|
handle.write("# consumer fixture\n")
|
||||||
|
PY
|
||||||
|
if CASAN_APP_ROOT="$CONSUMER" python3 "$S/traceability-matrix.py" \
|
||||||
|
--requirements "$CONSUMER/domain/requirement.md" \
|
||||||
|
--map "$CONSUMER/domain/traceability-map.json" \
|
||||||
|
--out "$WORK/consumer-traceability.json" --gate >/dev/null; then
|
||||||
|
pass "explicit consumer root wins over vendored harness location"
|
||||||
|
else
|
||||||
|
fail "vendored traceability resolved files against the harness bundle"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "===== TRACEABILITY SUMMARY: PASS=$PASS FAIL=$FAIL ====="
|
echo "===== TRACEABILITY SUMMARY: PASS=$PASS FAIL=$FAIL ====="
|
||||||
[[ "$FAIL" -eq 0 ]] || exit 1
|
[[ "$FAIL" -eq 0 ]] || exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user