Skip to content

Commit 9ac2661

Browse files
committed
Another deep audit and production-hardening pass is complete. 99 roadmap tests, smoke, operator smoke, and production audit all pass.
Kernel + roadmap unified cockpit kernel_cockpit.py now merges per-project roadmap steering into the kernel operator view: _roadmap_cockpit_brief() — pulls live session_brief() (identity, bootstrap state, digest) build_cockpit_report() — includes roadmap_steering in the payload format_cockpit_report() — shows project name, stack, verify command, bootstrap fill guidance, and roadmap health Agents/operators get one screen for both kernel patch state and project-specific roadmap steering. Richer project fingerprint project_fingerprint.py adds industry-standard signals: Signal Source compose_services docker-compose.yml / compose.yml service names .cursor/rules/*.mdc Cursor rule files (alongside .md) Runtime hint Uses compose service names when Docker is present These flow through steering context, digest, and agent steering lines. Bootstrap fill — no dead-end fallbacks _fallback_replacement() now chains through purpose_hint → operators_hint → runtime_center_hint → stack_summary → steering_brief before ever reaching manual review. Unmapped phrases get project-specific replacements whenever any fingerprint signal exists. Dynamic gate messaging gate.py evaluate_gate_checks() now personalizes closed gates: Bootstrap gate — why includes project steering_brief + placeholder count Schema gate — when bootstrap incomplete, fix prioritizes apply_bootstrap_fill before validate collect_gate_inputs() — passes project_fingerprint through for enrichment Cross-surface wiring JoyZoning _merge_steering_next_actions — adds Project verify: make verify from digest Roadmap cockpit report — shows verification commands during bootstrap fill Agent steering lines — show Compose services when present Audit expansion Production audit now verifies: JoyZoning verify hint from digest Gate why/fix personalization with project brief Kernel cockpit roadmap_steering payload + formatted bootstrap/verify lines Architecture (end-to-end) project_fingerprint (verify, compose, cursor rules, CODEOWNERS, …) → gate inputs + bootstrap_fill_plan → project_steering_digest → session / roadmap cockpit / kernel cockpit / write hints / joyzoning → apply_bootstrap_fill → validate → recommended_next_action Evidence-driven skeletons with README + Makefile can still autofill all template phrases in one pass; partial placeholders route through apply_bootstrap_fill with per-project replacements from fingerprint, git, and code soup audit.
1 parent c3e31aa commit 9ac2661

11 files changed

Lines changed: 237 additions & 9 deletions

lib/agent/joyzoning/workflow.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def _merge_steering_next_actions(
5858

5959
digest = roadmap_brief.get("project_steering_digest") or {}
6060
remaining = digest.get("bootstrap_remaining")
61+
verify_cmds = digest.get("verification_commands") or []
62+
if verify_cmds:
63+
verify_hint = f"Project verify: {verify_cmds[0]}"
64+
if verify_hint not in base and verify_hint not in hints:
65+
hints.append(verify_hint)
6166
if remaining and int(remaining) > 0:
6267
fill_hint = (
6368
f"Bootstrap fill: {remaining} template phrase(s) — "

lib/agent/kernel_cockpit.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,20 @@ def _find_last_operation(*, action: str, status: str) -> dict[str, Any] | None:
270270
return None
271271

272272

273+
def _roadmap_cockpit_brief() -> dict[str, Any] | None:
274+
"""Per-project roadmap steering for unified kernel + roadmap operator view."""
275+
try:
276+
from plugins.dietcode.lib.agent.roadmap.config import get_roadmap_config
277+
278+
if not get_roadmap_config().enabled:
279+
return None
280+
from plugins.dietcode.lib.agent.roadmap.session import session_brief
281+
282+
return session_brief()
283+
except Exception:
284+
return None
285+
286+
273287
def build_cockpit_report() -> dict[str, Any]:
274288
try:
275289
from plugins.dietcode.lib.agent.kernel_progress import (
@@ -342,6 +356,7 @@ def build_cockpit_report() -> dict[str, Any]:
342356
"operation_state": operation_state,
343357
"current_operation": current_op,
344358
"workspace_root": gate.get("resolved_workspace_root"),
359+
"roadmap_steering": _roadmap_cockpit_brief(),
345360
"patch_gate": {
346361
"patch_allowed": bool(gate.get("patch_allowed")),
347362
"mutations_enabled": bool(gate.get("mutations_enabled")),
@@ -392,6 +407,29 @@ def format_cockpit_report() -> str:
392407
ws = payload.get("workspace_root") or "(unresolved)"
393408
lines.append(f"Workspace: {ws}")
394409

410+
roadmap = payload.get("roadmap_steering") or {}
411+
if roadmap.get("enabled"):
412+
if roadmap.get("steering_brief") or roadmap.get("steering_identity"):
413+
lines.append(f"Project: {roadmap.get('steering_brief') or roadmap.get('steering_identity')}")
414+
if roadmap.get("stack_summary"):
415+
lines.append(f"Stack: {roadmap['stack_summary']}")
416+
digest = roadmap.get("project_steering_digest") or {}
417+
verify_cmds = digest.get("verification_commands") or roadmap.get("verification_commands") or []
418+
if verify_cmds:
419+
lines.append(f"Verify: {verify_cmds[0]}")
420+
if roadmap.get("bootstrap_complete") is False:
421+
count = roadmap.get("bootstrap_placeholder_count") or digest.get("bootstrap_remaining") or "?"
422+
lines.append(
423+
f"Roadmap bootstrap: {count} template phrase(s) — "
424+
"roadmap(action='apply_bootstrap_fill', context='write')"
425+
)
426+
elif roadmap.get("roadmap_exists"):
427+
health = roadmap.get("health_status") or "present"
428+
lines.append(f"Roadmap: health={health} | {roadmap.get('roadmap_path') or 'ROADMAP.md'}")
429+
elif roadmap.get("success") is not False:
430+
lines.append("Roadmap: missing — roadmap(action='checkpoint')")
431+
lines.append("")
432+
395433
pg = payload.get("patch_gate") or {}
396434
gate_sym = symbol("complete") if pg.get("patch_allowed") else symbol("warning")
397435
lines.append(

lib/agent/roadmap/agent_steering.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ def _project_context_lines(steering: dict[str, Any]) -> list[str]:
4444
if verify_cmds:
4545
lines.append(f"Verify: {', '.join(verify_cmds[:3])}")
4646

47+
compose = steering.get("compose_services") or []
48+
if compose:
49+
lines.append(f"Compose: {', '.join(compose[:4])}")
50+
4751
docs_roots = steering.get("docs_roots") or []
4852
if docs_roots:
4953
lines.append(f"Docs: {', '.join(docs_roots[:3])}")

lib/agent/roadmap/bootstrap_fill.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,17 @@ def _suggest_replacement(
201201
def _fallback_replacement(phrase: str, *, fingerprint: dict[str, Any]) -> tuple[str, str]:
202202
brief = fingerprint.get("steering_brief") or fingerprint.get("steering_identity") or ""
203203
purpose = fingerprint.get("purpose_hint") or ""
204+
operators = fingerprint.get("operators_hint") or ""
205+
runtime = fingerprint.get("runtime_center_hint") or ""
206+
stack = fingerprint.get("stack_summary") or ""
204207
if purpose:
205208
return purpose, "project_fingerprint.purpose_hint"
209+
if operators:
210+
return operators[:240], "project_fingerprint.operators_hint"
211+
if runtime:
212+
return runtime[:240], "project_fingerprint.runtime_center_hint"
213+
if stack and brief:
214+
return f"Document project-specific detail for {brief} ({stack}).", "project_fingerprint.stack_summary"
206215
if brief:
207216
return f"Document project-specific detail for {brief}.", "project_fingerprint.steering_brief"
208217
return phrase, "manual — review bootstrap_fill_plan.tasks"
@@ -500,6 +509,7 @@ def build_project_steering_digest(
500509
"docs_roots": fingerprint.get("docs_roots") or [],
501510
"license": fingerprint.get("license"),
502511
"runtime_versions": fingerprint.get("runtime_versions"),
512+
"compose_services": fingerprint.get("compose_services"),
503513
"has_codeowners": fingerprint.get("has_codeowners"),
504514
"dependency_automation": fingerprint.get("dependency_automation"),
505515
"has_backstage_catalog": fingerprint.get("has_backstage_catalog"),

lib/agent/roadmap/cockpit.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ def format_cockpit_report(*, workspace: Optional[str] = None) -> str:
214214
make_targets = digest.get("makefile_targets") or data.get("project_fingerprint", {}).get("makefile_targets") or []
215215
if make_targets:
216216
lines.append(f"Makefile targets: {', '.join(make_targets[:4])}")
217+
verify_cmds = digest.get("verification_commands") or data.get("project_fingerprint", {}).get("verification_commands") or []
218+
if verify_cmds:
219+
lines.append(f"Verify: {', '.join(verify_cmds[:3])}")
217220
sample = digest.get("sample_fill_task") or {}
218221
if sample.get("suggested_replacement"):
219222
repl = str(sample["suggested_replacement"])

lib/agent/roadmap/gate.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def collect_gate_inputs(
9696
"workspace_state": ws_state or None,
9797
"bootstrap_complete": bootstrap_complete,
9898
"bootstrap_placeholder_count": bootstrap_placeholder_count,
99+
"project_fingerprint": evidence.get("project_fingerprint"),
99100
}
100101

101102

@@ -238,16 +239,30 @@ def evaluate_gate_checks(inputs: dict[str, Any]) -> tuple[list[dict[str, Any]],
238239
"""Return (closed_gates, open_gate_ids) in kernel explain-gate shape."""
239240
closed: list[dict[str, Any]] = []
240241
open_ids: list[str] = []
242+
fp = inputs.get("project_fingerprint") or {}
243+
brief = fp.get("steering_brief") or fp.get("steering_identity") or ""
241244
for check in _GATE_CHECKS:
242245
is_open_fn: Callable[..., bool] = check["is_open"]
243246
if is_open_fn(check, inputs):
244247
open_ids.append(str(check["id"]))
245248
else:
249+
why = check["why_closed"]
250+
fix = check["fix"]
251+
gate_id = str(check["id"])
252+
if gate_id == "bootstrap_complete" and brief:
253+
count = inputs.get("bootstrap_placeholder_count")
254+
why = f"{brief}: {count or 'some'} unfilled bootstrap template phrase(s) remain"
255+
elif gate_id == "schema_valid" and inputs.get("bootstrap_complete") is False:
256+
fix = "roadmap(action='apply_bootstrap_fill', context='write') then roadmap(action='validate')"
257+
if brief:
258+
why = f"{brief}: schema validation failed — bootstrap placeholders may still remain"
259+
elif gate_id == "schema_valid" and brief:
260+
fix = f"Repair ROADMAP.md schema for {brief}, then roadmap(action='validate')"
246261
closed.append({
247-
"id": check["id"],
262+
"id": gate_id,
248263
"label": check["label"],
249-
"why": check["why_closed"],
250-
"fix": check["fix"],
264+
"why": why,
265+
"fix": fix,
251266
"safe_to_apply": bool(check["safe"]),
252267
"blocks_kanban_complete": bool(check.get("blocks_kanban_complete")),
253268
})

lib/agent/roadmap/project_fingerprint.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ def _fingerprint_cache_token(root: Path) -> float:
9999
"CODEOWNERS",
100100
"renovate.json",
101101
".github/dependabot.yml",
102+
"docker-compose.yml",
103+
"compose.yml",
102104
):
103105
path = root / rel
104106
if path.is_file():
@@ -424,15 +426,38 @@ def _agent_rules_files(root: Path) -> list[str]:
424426
found.append(rel)
425427
rules_dir = root / ".cursor" / "rules"
426428
if rules_dir.is_dir():
427-
for path in sorted(rules_dir.glob("*.md"))[:5]:
429+
for path in sorted(list(rules_dir.glob("*.md")) + list(rules_dir.glob("*.mdc")))[:5]:
428430
rel = f".cursor/rules/{path.name}"
429431
if rel not in found:
430432
found.append(rel)
431-
if rules_dir.is_dir() and ".cursor/rules" not in found and not any(p.suffix == ".md" for p in rules_dir.glob("*.md")):
432-
found.append(".cursor/rules")
433+
if not any(p.suffix in {".md", ".mdc"} for p in rules_dir.iterdir() if p.is_file()):
434+
if ".cursor/rules" not in found:
435+
found.append(".cursor/rules")
433436
return found[:8]
434437

435438

439+
def _compose_services(root: Path) -> list[str]:
440+
for name in ("docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"):
441+
path = root / name
442+
if not path.is_file():
443+
continue
444+
services: list[str] = []
445+
in_services = False
446+
for line in _read_text(path, limit=4000).splitlines():
447+
if re.match(r"^\s*services:\s*$", line):
448+
in_services = True
449+
continue
450+
if not in_services:
451+
continue
452+
match = re.match(r"^\s{2}([\w-]+):\s*$", line)
453+
if match:
454+
services.append(match.group(1))
455+
elif line.strip() and not line.startswith(" "):
456+
break
457+
return services[:6]
458+
return []
459+
460+
436461
def _catalog_metadata(root: Path) -> dict[str, Optional[str]]:
437462
catalog = root / "catalog-info.yaml"
438463
if not catalog.is_file():
@@ -568,6 +593,7 @@ def _build_project_fingerprint(root: Path) -> dict[str, Any]:
568593
makefile_targets = _makefile_targets(root)
569594
runtime_versions = _runtime_versions(root)
570595
dependency_automation = _dependency_automation(root)
596+
compose_services = _compose_services(root)
571597
has_codeowners = (root / ".github" / "CODEOWNERS").is_file() or (root / "CODEOWNERS").is_file()
572598
verification_commands = _verification_commands(
573599
root,
@@ -597,7 +623,10 @@ def _build_project_fingerprint(root: Path) -> dict[str, Any]:
597623
elif archetype == "web-app":
598624
runtime_hint = f"Web application root at {root.name} — deploy/runtime config in repo manifests"
599625
elif has_docker:
600-
runtime_hint = "Containerized runtime — Docker/Docker Compose manifests define operational center"
626+
if compose_services:
627+
runtime_hint = f"Containerized runtime — services: {', '.join(compose_services[:4])}"
628+
else:
629+
runtime_hint = "Containerized runtime — Docker/Docker Compose manifests define operational center"
601630
elif frameworks:
602631
runtime_hint = f"Primary stack: {', '.join(frameworks[:3])} — operational truth in repo config and entrypoints"
603632

@@ -644,6 +673,7 @@ def _build_project_fingerprint(root: Path) -> dict[str, Any]:
644673
"runtime_versions": runtime_versions or None,
645674
"dependency_automation": dependency_automation or None,
646675
"has_codeowners": has_codeowners,
676+
"compose_services": compose_services or None,
647677
"has_backstage_catalog": has_backstage,
648678
"catalog_name": catalog_meta.get("catalog_name"),
649679
"catalog_description": catalog_meta.get("catalog_description"),

lib/agent/roadmap/steering_context.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ def build_steering_context(*, workspace: Optional[str] = None) -> dict[str, Any]
170170
"runtime_versions",
171171
"has_codeowners",
172172
"dependency_automation",
173+
"compose_services",
173174
"has_backstage_catalog",
174175
"catalog_name",
175176
"catalog_description",

scripts/roadmap_audit.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,83 @@ def main() -> int:
526526
if not any("apply_bootstrap_fill" in h for h in merged2):
527527
failures.append("joyzoning merge missing apply_bootstrap_fill from recommended_next_action")
528528

529+
merged3 = wf_mod._merge_steering_next_actions(
530+
["joyzoning(action='begin')"],
531+
roadmap_brief={
532+
"enabled": True,
533+
"project_steering_digest": {"verification_commands": ["make verify"], "bootstrap_remaining": 2},
534+
},
535+
)
536+
if not any("Project verify:" in h for h in merged3):
537+
failures.append("joyzoning merge missing project verify hint from digest")
538+
539+
from plugins.dietcode.lib.agent.roadmap.gate import evaluate_gate_checks
540+
541+
gate_inputs = {
542+
"config": get_roadmap_config() if False else None,
543+
"workspace": str(root),
544+
"roadmap_present": True,
545+
"bootstrap_complete": False,
546+
"bootstrap_placeholder_count": fill_plan.get("remaining_count", 3),
547+
"project_fingerprint": fp,
548+
"validation": {"valid": False},
549+
"freshness": {"stale": False},
550+
"workspace_state": {},
551+
}
552+
from plugins.dietcode.lib.agent.roadmap.config import get_roadmap_config
553+
554+
gate_inputs["config"] = get_roadmap_config()
555+
closed_gates, _open = evaluate_gate_checks(gate_inputs)
556+
bootstrap_closed = [g for g in closed_gates if g.get("id") == "bootstrap_complete"]
557+
if not bootstrap_closed:
558+
failures.append("gate audit expected closed bootstrap_complete gate")
559+
elif "Audit Project" not in str(bootstrap_closed[0].get("why") or ""):
560+
failures.append("bootstrap gate why should include project steering brief")
561+
schema_closed = [g for g in closed_gates if g.get("id") == "schema_valid"]
562+
if schema_closed and "apply_bootstrap_fill" not in str(schema_closed[0].get("fix") or ""):
563+
failures.append("schema gate fix should prioritize bootstrap fill when placeholders remain")
564+
565+
try:
566+
from plugins.dietcode.lib.agent import kernel_cockpit as kc_mod
567+
from unittest import mock as audit_mock
568+
569+
fake_brief = {
570+
"enabled": True,
571+
"steering_brief": fp.get("steering_brief"),
572+
"stack_summary": fp.get("stack_summary"),
573+
"bootstrap_complete": False,
574+
"bootstrap_placeholder_count": fill_plan.get("remaining_count", 3),
575+
"roadmap_exists": True,
576+
"health_status": "Coherent",
577+
"roadmap_path": str(root / "ROADMAP.md"),
578+
"project_steering_digest": digest,
579+
}
580+
kernel_gate = {
581+
"resolved_workspace_root": str(root),
582+
"patch_allowed": True,
583+
"mutations_enabled": True,
584+
"socket_ready": True,
585+
"token_ready": True,
586+
"workspace_safe_for_mutation": True,
587+
}
588+
kernel_router = {"raw_write_policy": "warn", "would_block_raw_writes": False, "would_warn_on_raw_write": False}
589+
with audit_mock.patch.object(
590+
kc_mod,
591+
"_gate_context",
592+
return_value={"config": None, "gate": kernel_gate, "router": kernel_router},
593+
):
594+
with audit_mock.patch.object(kc_mod, "_roadmap_cockpit_brief", return_value=fake_brief):
595+
kc_payload = kc_mod.build_cockpit_report()
596+
kc_text = kc_mod.format_cockpit_report()
597+
if not kc_payload.get("roadmap_steering"):
598+
failures.append("kernel cockpit missing roadmap_steering brief")
599+
if "apply_bootstrap_fill" not in kc_text:
600+
failures.append("kernel cockpit report missing bootstrap fill guidance")
601+
if "Verify:" not in kc_text:
602+
failures.append("kernel cockpit report missing project verify line")
603+
except ImportError:
604+
pass
605+
529606
invalidate_snapshot(str(root))
530607
snapshot_mod._CACHE.clear()
531608
t0 = time.perf_counter()

tests/test_kernel_cockpit.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,26 @@ def test_cockpit_report_structure(self) -> None:
9393
"resolved_workspace_root": "/tmp/project",
9494
}
9595
router = {"raw_write_policy": "warn", "would_block_raw_writes": False, "would_warn_on_raw_write": True}
96+
fake_roadmap = {
97+
"enabled": True,
98+
"steering_brief": "Demo — Python",
99+
"stack_summary": "Python",
100+
"bootstrap_complete": False,
101+
"bootstrap_placeholder_count": 2,
102+
"roadmap_exists": True,
103+
"project_steering_digest": {"verification_commands": ["make verify"], "bootstrap_remaining": 2},
104+
}
96105
with mock.patch.object(cockpit, "_gate_context", return_value={"config": KernelBridgeConfig(), "gate": gate, "router": router}):
97-
payload = cockpit.build_cockpit_report()
106+
with mock.patch.object(cockpit, "_roadmap_cockpit_brief", return_value=fake_roadmap):
107+
payload = cockpit.build_cockpit_report()
108+
text = cockpit.format_cockpit_report()
98109
self.assertIn("recommended_next_action", payload)
110+
self.assertIn("roadmap_steering", payload)
99111
self.assertEqual(payload["recommended_next_action"]["action"], cockpit.ACTION_ENABLE_MUTATIONS)
100-
text = cockpit.format_cockpit_report()
101112
self.assertIn("Kernel cockpit", text)
102113
self.assertIn("Next action:", text)
114+
self.assertIn("apply_bootstrap_fill", text)
115+
self.assertIn("Verify:", text)
103116

104117
def test_ux_budget_enrichment(self) -> None:
105118
events = [

0 commit comments

Comments
 (0)