Harden M8 preflight foundation

This commit is contained in:
rob
2026-07-20 12:08:38 -03:00
parent 188e167c1c
commit ba29e4dc4e
14 changed files with 530 additions and 53 deletions
+78 -28
View File
@@ -351,6 +351,48 @@ def _cmd_registry_update(args):
return 0
def _print_preflight_sections(report: dict, prefix: str = "") -> None:
"""Render the common portions of a structured preflight report."""
labels = (
("errors", "ERROR"),
("warnings", "WARN"),
("suggestions", "HINT"),
)
for key, marker in labels:
values = report.get(key) or []
if values:
print(f"{prefix}{key.title()} ({len(values)}):")
for value in values:
print(f" {marker}: {value}")
def _print_registry_suggestions(suggestions: dict) -> None:
"""Render registry-specific category, similarity, and scrutiny evidence."""
category = suggestions.get("category") or {}
if category.get("suggested"):
print(
f"Suggested category: {category['suggested']} "
f"({category.get('confidence', 0):.0%} confidence)"
)
similar = suggestions.get("similar_tools") or []
if similar:
print(f"Similar registry tools ({len(similar)}):")
for item in similar:
print(
f" - {item.get('name', 'unknown')} "
f"({item.get('similarity', 0):.0%} similar)"
)
scrutiny = suggestions.get("scrutiny") or {}
findings = scrutiny.get("findings") or []
if findings:
print(f"Scrutiny findings ({len(findings)}):")
for finding in findings:
marker = str(finding.get("result", "info")).upper()
print(f" {marker}: {finding.get('message', '')}")
def _cmd_registry_publish(args):
"""Publish a tool to the registry."""
from ..registry_client import RegistryError, get_client
@@ -404,6 +446,9 @@ def _cmd_registry_publish(args):
# Validate
try:
data = yaml.safe_load(config_yaml)
if not isinstance(data, dict):
print("Error: config.yaml must contain a YAML mapping", file=sys.stderr)
return 1
name = data.get("name", "")
version = data.get("version", "")
if not name or not version:
@@ -424,36 +469,41 @@ def _cmd_registry_publish(args):
print(f" README: {len(readme)} bytes")
print()
from ..preflight import analyze_tool
from ..tool import Tool
try:
local_report = analyze_tool(Tool.from_dict(data))
except (KeyError, TypeError, ValueError) as exc:
print(f"Local preflight error: {exc}", file=sys.stderr)
return 1
_print_preflight_sections(local_report.to_dict(), prefix="Local ")
if not local_report.ok:
return 1
# Attempt registry preflight if token is configured
config = load_config()
if config.registry.token:
try:
client = get_client()
result = client.publish_tool(
config_yaml, readme=readme, defaults=defaults,
dry_run=True,
)
except Exception as e:
print(f"Registry preflight error: {e}", file=sys.stderr)
return 1
errors = result.get("errors") or []
warnings = result.get("warnings") or []
suggestions = result.get("suggestions") or []
if errors:
print(f"Preflight errors ({len(errors)}):")
for err in errors:
print(f" ERROR: {err}")
if warnings:
print(f"Preflight warnings ({len(warnings)}):")
for warn in warnings:
print(f" WARN: {warn}")
if suggestions:
print(f"Suggestions ({len(suggestions)}):")
for sug in suggestions:
print(f" HINT: {sug}")
if not errors and not warnings and not suggestions:
print("Registry preflight passed.")
return 0 if not errors else 1
if not config.registry.token:
print("No registry token configured — local preflight only.")
return 0
try:
client = get_client()
result = client.publish_tool(
config_yaml, readme=readme, defaults=defaults,
dry_run=True,
)
except RegistryError as exc:
print(f"Registry preflight failed: {exc}", file=sys.stderr)
return 1
remote_report = result.get("preflight") or {}
_print_preflight_sections(remote_report, prefix="Registry ")
_print_registry_suggestions(result.get("suggestions") or {})
if not remote_report.get("errors"):
print("Registry preflight passed.")
return 0
return 1
# Check for token
config = load_config()