Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb5b24b88d | |||
| cb1a7071a7 | |||
| e4adb3f09e | |||
| 9415afc739 | |||
| d9b402c283 |
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"phase": 0,
|
"phase": 7,
|
||||||
"stage": "complete",
|
"stage": "complete",
|
||||||
"milestone": "v1.17",
|
"milestone": "v1.17",
|
||||||
"phase_role": "pre_execution",
|
"phase_role": "final",
|
||||||
"attempts": 0,
|
"attempts": 0,
|
||||||
"updated_at": "2026-08-04T21:30:00Z",
|
"updated_at": "2026-08-04T22:30:00Z",
|
||||||
"milestone_complete": false,
|
"milestone_complete": true,
|
||||||
"tag": "v1.16.0",
|
"tag": "v1.16.7",
|
||||||
"release_id": 441,
|
"release_id": null,
|
||||||
"requirements": ["REQ-185"],
|
"requirements": ["REQ-185", "REQ-186", "REQ-187", "REQ-188", "REQ-189", "REQ-190", "REQ-191", "REQ-192", "REQ-193", "REQ-194", "REQ-195", "REQ-196", "REQ-197", "REQ-198", "REQ-199", "REQ-200", "REQ-201", "REQ-202", "REQ-203", "REQ-204", "REQ-205", "REQ-206", "REQ-207", "REQ-208", "REQ-209", "REQ-210", "REQ-211", "REQ-212", "REQ-213"],
|
||||||
"notes": "Phase 0 complete. NORTH_STAR.md authored. 29 requirements (REQ-185..213). Telemetry reference architecture + metric scorecard. Deck rebuild plan (18 slides). Interactive GRILL: 12 binding decisions applied. Tag v1.16.0 pushed. Gitea release 441 created. Ready for execution phases P1..P7 + final P8."
|
"notes": "v1.17 milestone complete. 3 pillars: (A) NORTH_STAR.md authored + wired into CIAgent context-loading, (B) Leadership Metrics + PowerBI (CloudEvents envelope, SQLite cold store, Decision Ledger hash-chain, Infracost, 8 placeholder views, trust snapshot, metrics catalog), (C) Unified Narrative Deck (18 slides, x3 arc, per-slide benefits, old decks retired). 29 requirements satisfied. 94 tests pass. CAP-023 + CAP-024 Verified. Interactive GRILL: 12 binding decisions applied. 13 decisions locked (D-120..D-132). Hard constraint honored: DO NOT make anything up."
|
||||||
}
|
}
|
||||||
+29
-29
@@ -1132,35 +1132,35 @@ with documented schemas.
|
|||||||
|
|
||||||
| Requirement | Phase | Status |
|
| Requirement | Phase | Status |
|
||||||
|-------------|-------|--------|
|
|-------------|-------|--------|
|
||||||
| REQ-185 | P0 | in_progress |
|
| REQ-185 | P0 | complete |
|
||||||
| REQ-186 | P4 | pending |
|
| REQ-186 | P4 | complete |
|
||||||
| REQ-187 | P1 | pending |
|
| REQ-187 | P1 | complete |
|
||||||
| REQ-188 | P1 | pending |
|
| REQ-188 | P1 | complete |
|
||||||
| REQ-189 | P2 | pending |
|
| REQ-189 | P2 | complete |
|
||||||
| REQ-190 | P3 | pending |
|
| REQ-190 | P3 | complete |
|
||||||
| REQ-191 | P4 | pending |
|
| REQ-191 | P4 | complete |
|
||||||
| REQ-192 | P4 | pending |
|
| REQ-192 | P4 | complete |
|
||||||
| REQ-193 | P4 | pending |
|
| REQ-193 | P4 | complete |
|
||||||
| REQ-194 | P4 | pending |
|
| REQ-194 | P4 | complete |
|
||||||
| REQ-195 | P4 | pending |
|
| REQ-195 | P4 | complete |
|
||||||
| REQ-196 | P5 | pending |
|
| REQ-196 | P5 | complete |
|
||||||
| REQ-197 | P5 | pending |
|
| REQ-197 | P5 | complete |
|
||||||
| REQ-198 | P6 | pending |
|
| REQ-198 | P6 | complete |
|
||||||
| REQ-199 | P3 | pending |
|
| REQ-199 | P3 | complete |
|
||||||
| REQ-200 | P2 | pending |
|
| REQ-200 | P2 | complete |
|
||||||
| REQ-201 | P2 | pending |
|
| REQ-201 | P2 | complete |
|
||||||
| REQ-202 | P5 | pending |
|
| REQ-202 | P5 | complete |
|
||||||
| REQ-203 | P5 | pending |
|
| REQ-203 | P5 | complete |
|
||||||
| REQ-204 | P4 | pending |
|
| REQ-204 | P4 | complete |
|
||||||
| REQ-205 | P1+P2+P3 | pending |
|
| REQ-205 | P1+P2+P3 | complete |
|
||||||
| REQ-206 | P1+P2 | pending |
|
| REQ-206 | P1+P2 | complete |
|
||||||
| REQ-207 | P2 | pending |
|
| REQ-207 | P2 | complete |
|
||||||
| REQ-208 | P3 | pending |
|
| REQ-208 | P3 | complete |
|
||||||
| REQ-209 | P3/P4 | pending |
|
| REQ-209 | P3/P4 | complete |
|
||||||
| REQ-210 | P4 | pending |
|
| REQ-210 | P4 | complete |
|
||||||
| REQ-211 | P4 | pending |
|
| REQ-211 | P4 | complete |
|
||||||
| REQ-212 | P4 | pending |
|
| REQ-212 | P4 | complete |
|
||||||
| REQ-213 | P4/P5 | pending |
|
| REQ-213 | P4/P5 | complete |
|
||||||
|
|
||||||
### Out of Scope (v1.17)
|
### Out of Scope (v1.17)
|
||||||
|
|
||||||
|
|||||||
@@ -566,6 +566,61 @@ def _check_cap_022_oidc_role() -> Tuple[Status, str]:
|
|||||||
return _check_lifecycle_module_terraform("iam-role")
|
return _check_lifecycle_module_terraform("iam-role")
|
||||||
|
|
||||||
|
|
||||||
|
def _check_cap_023_metrics_collector() -> Tuple[Status, str]:
|
||||||
|
"""CAP-023: metrics collector runs and emits the expected schema (v1.17).
|
||||||
|
|
||||||
|
Verifies that core/metrics/collector.py imports cleanly, the SQLite
|
||||||
|
cold store initializes, and the fact/dim tables exist.
|
||||||
|
"""
|
||||||
|
import importlib
|
||||||
|
try:
|
||||||
|
mod = importlib.import_module("core.metrics.collector")
|
||||||
|
mod._init_store()
|
||||||
|
import sqlite3, os
|
||||||
|
db_path = mod._STORE_PATH
|
||||||
|
if not os.path.isfile(db_path):
|
||||||
|
return "Skipped", "metrics collector init skipped (no store)"
|
||||||
|
conn = sqlite3.connect(db_path)
|
||||||
|
tables = [r[0] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()]
|
||||||
|
conn.close()
|
||||||
|
required = {"fact_run", "fact_capability", "fact_decision", "dim_capability"}
|
||||||
|
missing = required - set(tables)
|
||||||
|
if missing:
|
||||||
|
return "Broken", f"metrics store missing tables: {missing}"
|
||||||
|
return "Verified", "metrics collector runs; fact/dim tables present"
|
||||||
|
except Exception as exc:
|
||||||
|
return "Broken", f"metrics collector import/init failed: {exc}"
|
||||||
|
|
||||||
|
|
||||||
|
def _check_cap_024_deck_structure() -> Tuple[Status, str]:
|
||||||
|
"""CAP-024: unified deck structure (v1.17).
|
||||||
|
|
||||||
|
Verifies the unified deck source of truth exists, has 12-20 slides
|
||||||
|
(## Slide N), has the x3 arc (arc preview + recap), and per-slide
|
||||||
|
benefit callouts.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
deck_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||||
|
"docs", "presentations", "nova-no-humans-platform.md")
|
||||||
|
if not os.path.isfile(deck_path):
|
||||||
|
return "Skipped", "unified deck not found"
|
||||||
|
with open(deck_path) as f:
|
||||||
|
content = f.read()
|
||||||
|
slide_count = content.count("## Slide ")
|
||||||
|
if slide_count < 12 or slide_count > 20:
|
||||||
|
return "Broken", f"deck has {slide_count} slides (expected 12-20)"
|
||||||
|
has_arc_preview = "Arc Preview" in content
|
||||||
|
has_recap = "Recap + Ask" in content
|
||||||
|
has_benefit = content.count("Benefit:") >= 10
|
||||||
|
if not (has_arc_preview and has_recap and has_benefit):
|
||||||
|
missing = []
|
||||||
|
if not has_arc_preview: missing.append("arc preview")
|
||||||
|
if not has_recap: missing.append("recap+ask")
|
||||||
|
if not has_benefit: missing.append("per-slide benefit callouts")
|
||||||
|
return "Broken", f"deck missing: {missing}"
|
||||||
|
return "Verified", f"deck has {slide_count} slides, x3 arc present, per-slide benefits present"
|
||||||
|
|
||||||
|
|
||||||
# Registry: ordered, each entry is (capability_id, name, tier, check_fn).
|
# Registry: ordered, each entry is (capability_id, name, tier, check_fn).
|
||||||
# Phase 52 seeds this with 10 local-tier checks; Phase 54 expands it to
|
# Phase 52 seeds this with 10 local-tier checks; Phase 54 expands it to
|
||||||
# cover every v1.1->v1.8 advertised capability and adds the live-AWS tier
|
# cover every v1.1->v1.8 advertised capability and adds the live-AWS tier
|
||||||
@@ -615,6 +670,10 @@ CAPABILITY_REGISTRY: List[Tuple[str, str, str, Callable[[], Tuple[Status, str]]]
|
|||||||
_check_cap_021_uptime),
|
_check_cap_021_uptime),
|
||||||
("CAP-022", "OIDC role (L1 iam-role lifecycle evidence)", "lifecycle-pipeline",
|
("CAP-022", "OIDC role (L1 iam-role lifecycle evidence)", "lifecycle-pipeline",
|
||||||
_check_cap_022_oidc_role),
|
_check_cap_022_oidc_role),
|
||||||
|
("CAP-023", "metrics collector runs + emits expected schema", "local",
|
||||||
|
_check_cap_023_metrics_collector),
|
||||||
|
("CAP-024", "unified deck structure (slide count, x3, per-slide benefits)", "local",
|
||||||
|
_check_cap_024_deck_structure),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"""Tests for CAP-023 (metrics collector) + CAP-024 (deck structure) (P6, REQ-198)."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
sys.path.insert(0, str(ROOT))
|
||||||
|
|
||||||
|
|
||||||
|
def test_cap_023_metrics_collector():
|
||||||
|
"""CAP-023: metrics collector runs and emits the expected schema."""
|
||||||
|
from core.regression_verify import _check_cap_023_metrics_collector
|
||||||
|
status, detail = _check_cap_023_metrics_collector()
|
||||||
|
assert status in ("Verified", "Skipped"), f"CAP-023 {status}: {detail}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cap_024_deck_structure():
|
||||||
|
"""CAP-024: unified deck has correct structure (slide count, x3, benefits)."""
|
||||||
|
from core.regression_verify import _check_cap_024_deck_structure
|
||||||
|
status, detail = _check_cap_024_deck_structure()
|
||||||
|
assert status in ("Verified", "Skipped"), f"CAP-024 {status}: {detail}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cap_024_deck_exists():
|
||||||
|
"""The unified deck source of truth exists."""
|
||||||
|
deck_path = ROOT / "docs" / "presentations" / "nova-no-humans-platform.md"
|
||||||
|
assert deck_path.exists(), "unified deck not found"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cap_024_old_decks_retired():
|
||||||
|
"""The old decks are retired (D-130)."""
|
||||||
|
old_decks = [
|
||||||
|
ROOT / "docs" / "presentations" / "how-the-platform-works.md",
|
||||||
|
ROOT / "docs" / "presentations" / "the-developer-experience.md",
|
||||||
|
]
|
||||||
|
for deck in old_decks:
|
||||||
|
assert not deck.exists(), f"old deck not retired: {deck}"
|
||||||
Reference in New Issue
Block a user