#!/usr/bin/env python3 """Validate every full Schema leaf against Cobra Help and smoke runtime wiring. The script loads ``dws schema --all --format json`` exactly once and uses those full leaf payloads directly. Every leaf receives a bidirectional Schema/Help flag contract check that excludes root execution controls and reviewed generic payload escape hatches, but retains effective product/group flags. Runtime execution is opt-in: only a leaf that publishes a valid ``dry_run`` object is invoked with ``--dry-run``. Merely inheriting the global flag is never treated as capability evidence, and ``--yes`` is never injected. The subprocess result is only a final-binary exit-health check. It deliberately does not infer preview evidence from human-readable text. The Go Agent-example gate is the sole proof of preview kind, absence of real ToolCaller invocations, and non-interactive safety. Run the fast, binary-free self-tests with:: python3 -m unittest scripts/dev/schema_command_smoke_test.py """ from __future__ import annotations import argparse import concurrent.futures import itertools import json import re import shlex import subprocess import tempfile import time from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path from typing import Any GLOBAL_EXECUTION_CONTROL_FLAGS = frozenset( { "client-id", "client-secret", "debug", "dry-run", "fields", "format", "jq", "mock", "output", "profile", "timeout", "token", "verbose", "yes", } ) COBRA_FRAMEWORK_FLAGS = frozenset({"help"}) DRY_RUN_PREVIEW_KINDS = frozenset({"invocation", "request", "plan", "diff"}) GENERIC_PAYLOAD_FLAG_USAGES = { "json": "Base JSON object payload for this tool invocation", "params": "Additional JSON object payload merged after --json", } HELP_FLAG_PATTERN = re.compile( r"^\s*(?:-[a-zA-Z0-9],\s*)?--([a-zA-Z0-9][a-zA-Z0-9_.-]*)(?:[ =]|$)" ) @dataclass class SmokeResult: canonical_path: str case_name: str cli_path: str command: list[str] status: str exit_code: int stdout: str stderr: str error: str = "" def should_retry_json_failure(output: str) -> bool: return any( token in output for token in [ "TOKEN_VERIFIED_FAILED", "tools/list failed", "returned HTTP 400", ] ) def run_json(argv: list[str], cwd: Path, timeout: int, attempts: int = 3) -> Any: last_output = "" last_code = 1 for attempt in range(attempts): proc = subprocess.run( argv, cwd=cwd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, ) if proc.returncode == 0: return json.loads(proc.stdout) last_code = proc.returncode last_output = (proc.stderr or proc.stdout).strip() if attempt + 1 < attempts and should_retry_json_failure(last_output): time.sleep(1 + attempt) continue break raise RuntimeError(f"{shlex.join(argv)} exited {last_code}: {last_output}") def kebab_to_words(value: str) -> str: return re.sub(r"[-_]+", " ", value.lower()) def scalar_value(flag: str, param: dict[str, Any], canonical_path: str) -> str: if param.get("example") not in (None, ""): return str(param["example"]) enum = param.get("enum") or [] if enum: return str(enum[0]) value_format = str(param.get("format", "")).lower() is_end = flag == "end" or flag.startswith("end-") or flag.endswith("-end") if value_format in {"numeric-id", "positive-integer"}: return "1" if value_format == "a1-range": return "A1:B2" if value_format == "file-path": return str(Path(tempfile.gettempdir()) / "dws-schema-smoke-fixture.txt") if value_format == "date-time": return "2027-01-15T11:00:00+08:00" if is_end else "2027-01-15T10:00:00+08:00" if value_format == "date": return "2027-01-16" if is_end else "2027-01-15" if "default" in param and param["default"] not in (None, ""): return str(param["default"]) haystack = " ".join( [ kebab_to_words(flag), kebab_to_words(str(param.get("property", ""))), str(param.get("description", "")).lower(), ] ) if flag in {"start", "end", "start-time", "end-time"}: return "2027-01-15T11:00:00+08:00" if is_end else "2027-01-15T10:00:00+08:00" if flag == "fields": return '[{"fieldName":"Name","type":"text"}]' if flag in {"records", "record"}: return '[{"cells":{"fld1":"value"}}]' if flag == "json": samples = { "aitable.view_update_aggregate": '{"fld1":"COUNT"}', "aitable.view_update_card": '{"displayFieldName":true}', "aitable.view_update_field_widths": '{"fld1":160}', "aitable.view_update_timebar": '{"startField":"fld_start"}', } if canonical_path in samples: return samples[canonical_path] if canonical_path == "attendance.generateTurnSchedule" and flag == "scheduleVOS": return '[{"userId":"user-smoke","workDate":"2026-07-09 09:00:00","classId":1,"isRest":"N"}]' if canonical_path == "attendance.create_group_setting" and flag == "type": return "NONE" if canonical_path == "attendance.query_at_approve_template" and flag == "type": return "leave" if canonical_path == "attendance.save_self_setting" and flag == "setting-scene": return "checkResultNotify" if canonical_path == "attendance.get_attendance_summary" and flag == "date": return "2026-07-09 10:00:00" if "json" in haystack: if "array" in haystack or "数组" in haystack: return "[]" return "{}" if flag == "config" or flag == "layout" or flag.endswith("-config"): return "{}" if flag == "scope": return "all" if flag == "format": return "excel" if "enabled" in haystack or "allow back" in haystack: return "true" if flag in {"to", "cc", "bcc", "from"}: return "user@example.com" if "url" in haystack or "callback" in haystack or "homepage" in haystack: return "https://example.com" if "email" in haystack or "mail" in haystack: return "user@example.com" if "mobile" in haystack or "phone" in haystack: return "13800138000" if "date" in haystack and "time" not in haystack: return "2026-07-09" if "time" in haystack or "deadline" in haystack: return "2026-07-09T10:00:00+08:00" if "file" in haystack or "path" in haystack or "attachment" in haystack or flag == "output": return str(Path(tempfile.gettempdir()) / "dws-schema-smoke-fixture.txt") if "confirm name" in haystack: return "SchemaSmoke" if flag in {"redirect-urls", "sso-urls"}: return "https://example.com" if flag == "ip-whitelist" or "ip" in haystack: return "192.0.2.10" if "secret" in haystack: return "test-secret" if "robot code" in haystack: return "robot-code-smoke" if flag == "mode" and any(item in haystack for item in ["https", "stream", "aiskill"]): return "STREAM" if flag == "share-type": return "PUBLIC" if flag in {"id", "parent-id", "dept-id"} or "dept id" in haystack: return "1" if "version" in haystack: return "1.0.0" if "content" in haystack or "message" in haystack or "desc" in haystack: return "schema smoke" if "name" in haystack or "title" in haystack or "subject" in haystack: return "SchemaSmoke" if "type" in haystack: return "app" return f"{flag}-smoke" def value_for(flag: str, param: dict[str, Any], canonical_path: str) -> str | None: # Reviewed examples and declared enums are contract data. They must win # before type/name heuristics (notably integer enums such as mute-time). if param.get("example") not in (None, ""): return str(param["example"]) enum = param.get("enum") or [] if enum: return str(enum[0]) if canonical_path == "sheet.range_batch_set_style" and flag == "batch": return str(Path(tempfile.gettempdir()) / "dws-schema-smoke-style.json") if canonical_path == "report.create_report" and flag == "contents-file": return "tmp/dws-schema-smoke-report.json" typ = str(param.get("type", "string")).lower() prop = str(param.get("property", "")) haystack = " ".join([kebab_to_words(flag), kebab_to_words(prop)]) if typ == "boolean": return None if typ in {"integer", "number"}: return "1" if typ == "object": return "{}" if typ == "array": if "url" in haystack: return "https://example.com" if "ip" in haystack: return "192.0.2.10" if any(token in haystack for token in [" id", " ids", "user", "users", "field", "fields"]): return "value1,value2" if any(token in haystack for token in ["record", "records"]): return '[{"cells":{"fld1":"value"}}]' if any(token in haystack for token in ["sort"]): return "[]" if any(token in haystack for token in ["field", "fields"]): return "field1,field2" return "value1,value2" return scalar_value(flag, param, canonical_path) def smoke_extra_flags(canonical_path: str) -> set[str]: # Avoid environment-dependent auto-detection in dry-run smoke. The command # accepts --email as optional, but without it the CLI probes the bound mailbox. return { "mail.search_mail_users": {"email"}, }.get(canonical_path, set()) def constraint_groups(leaf: dict[str, Any], name: str) -> list[list[str]]: constraints = leaf.get("constraints") or {} groups = constraints.get(name) or [] return [[str(item) for item in group] for group in groups if group] def available_one_of_groups(leaf: dict[str, Any]) -> list[list[str]]: params = leaf.get("parameters") or {} positional_names = { str(item.get("name")) for item in (leaf.get("positionals") or []) if item.get("name") } available = set(params) | positional_names return [ [name for name in group if name in available] for group in constraint_groups(leaf, "require_one_of") if any(name in available for name in group) ] def one_of_cases(leaf: dict[str, Any]) -> list[tuple[str, ...]]: groups = available_one_of_groups(leaf) if not groups: return [()] cases: list[tuple[str, ...]] = [] seen: set[tuple[str, ...]] = set() mutually_exclusive = constraint_groups(leaf, "mutually_exclusive") for choices in itertools.product(*groups): selected = set(choices) if any(sum(name in selected for name in group) > 1 for group in mutually_exclusive): continue if choices not in seen: seen.add(choices) cases.append(choices) return cases or [()] def required_when_matches( expression: str, params: dict[str, Any], selected_params: set[str], canonical_path: str, ) -> bool: expression = expression.strip() value_match = re.fullmatch(r"([a-zA-Z0-9_.-]+) is (.+)", expression) if value_match: controller, expected_raw = value_match.groups() controller_param = params.get(controller) or {} if controller in selected_params: actual = value_for(controller, controller_param, canonical_path) actual_value = "true" if actual is None else str(actual) elif controller_param.get("default") not in (None, ""): actual_value = str(controller_param["default"]) elif str(controller_param.get("type", "")).lower() == "boolean": actual_value = "false" else: return False expected = [item.strip() for item in re.split(r"\s+or\s+", expected_raw)] return actual_value in expected any_flag_match = re.fullmatch( r"any ([a-zA-Z0-9_.-]+)\* flag is provided", expression ) if any_flag_match: prefix = any_flag_match.group(1) return any(name.startswith(prefix) for name in selected_params) return False def selected_inputs( leaf: dict[str, Any], include_optional: bool, one_of_choices: tuple[str, ...] = (), ) -> tuple[set[str], set[str]]: params = leaf.get("parameters") or {} canonical_path = str(leaf.get("canonical_path", "")) positionals = { str(item.get("name")): item for item in (leaf.get("positionals") or []) if item.get("name") } selected_params = { name for name, param in params.items() if include_optional or bool((param or {}).get("required")) } selected_positionals = { name for name, positional in positionals.items() if bool((positional or {}).get("required")) } def is_selected(name: str) -> bool: return name in selected_params or name in selected_positionals def select(name: str) -> bool: if name in params: selected_params.add(name) return True if name in positionals: selected_positionals.add(name) return True return False one_of_groups = available_one_of_groups(leaf) choices = one_of_choices or tuple(group[0] for group in one_of_groups) preferred = set(choices) for group, choice in zip(one_of_groups, choices): for name in group: selected_params.discard(name) selected_positionals.discard(name) select(choice) changed = True while changed: changed = False for group in constraint_groups(leaf, "require_together"): if not any(is_selected(name) for name in group): continue for name in group: if not is_selected(name) and select(name): changed = True for name, param in params.items(): if name in selected_params: continue required_when = str((param or {}).get("required_when", "")) if required_when_matches( required_when, params, selected_params, canonical_path ): selected_params.add(name) changed = True for group in constraint_groups(leaf, "mutually_exclusive"): selected = [name for name in group if is_selected(name)] keep = next((name for name in selected if name in preferred), selected[0] if selected else "") for name in selected: if name == keep: continue selected_params.discard(name) selected_positionals.discard(name) return selected_params, selected_positionals def build_command( binary: str, leaf: dict[str, Any], include_optional: bool, one_of_choices: tuple[str, ...] = (), ) -> list[str]: if not declared_dry_run(leaf): raise ValueError("runtime smoke requires an explicit leaf dry_run capability") cli_path = str(leaf["cli_path"]) canonical_path = str(leaf.get("canonical_path", "")) extra_flags = smoke_extra_flags(canonical_path) argv = [binary, *shlex.split(cli_path)] params = leaf.get("parameters") or {} selected_params, selected_positionals = selected_inputs( leaf, include_optional, one_of_choices ) positionals = sorted( (leaf.get("positionals") or []), key=lambda item: int(item.get("index", 0)), ) for positional in positionals: name = str(positional.get("name", "")) if name not in selected_positionals: continue value = value_for(name, positional, canonical_path) argv.append("" if value is None else value) for flag in sorted(params): param = params[flag] or {} if flag == "yes": # A preview must prove that confirmation cannot be bypassed. continue if flag not in selected_params and flag not in extra_flags: continue if str(param.get("type", "")).lower() == "boolean": argv.append(f"--{flag}") continue value = value_for(flag, param, canonical_path) argv.extend([f"--{flag}", "" if value is None else value]) # A positive leaf dry_run declaration is the only caller-side admission # condition. Confirmation must never be bypassed by injecting --yes, and # no output flag is appended because commands may own a same-named flag. argv.append("--dry-run") return argv def effective_schema_flags_from_help(output: str) -> set[str]: """Return executable non-root flags from Cobra's rendered Help. Cobra renders a leaf's own flags under ``Flags`` and all persistent ancestors under ``Global Flags``. Schema intentionally excludes only the root execution controls; product/group persistent flags remain part of the leaf contract. Keeping section origin prevents a local business ``--format`` flag from being confused with the root output-format control. """ local_flags: set[str] = set() inherited_flags: set[str] = set() section = "" saw_flags_section = False for line in output.splitlines(): heading = line.strip() if heading in {"Flags:", "Local Flags:"}: section = "local" saw_flags_section = True continue if heading in {"Global Flags:", "Inherited Flags:"}: section = "inherited" saw_flags_section = True continue if re.fullmatch(r"[A-Za-z][A-Za-z ]*:", heading): section = "" continue if not section: continue match = HELP_FLAG_PATTERN.match(line) if not match: continue name = match.group(1) generic_usage = GENERIC_PAYLOAD_FLAG_USAGES.get(name) if generic_usage and generic_usage in line: # These two generic transport escape hatches are intentionally not # projected as typed Schema parameters. Match their reviewed usage # text rather than excluding every business flag named json/params. continue if section == "local": local_flags.add(name) else: inherited_flags.add(name) if not saw_flags_section: raise RuntimeError("command help has no recognizable Flags section") return ( local_flags | (inherited_flags - GLOBAL_EXECUTION_CONTROL_FLAGS) ) - COBRA_FRAMEWORK_FLAGS def help_schema_flags(binary: str, cwd: Path, cli_path: str, timeout: int) -> set[str]: proc = subprocess.run( [binary, *shlex.split(cli_path), "--help"], cwd=cwd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, ) if proc.returncode != 0: raise RuntimeError( f"{binary} {cli_path} --help exited {proc.returncode}: " f"{(proc.stderr or proc.stdout).strip()}" ) return effective_schema_flags_from_help(proc.stdout) def run_smoke_case( binary: str, cwd: Path, path: str, leaf: dict[str, Any], timeout: int, include_optional: bool, choices: tuple[str, ...], ) -> SmokeResult: case_name = ( "dry_run/default" if not choices else "dry_run/one_of:" + "+".join(choices) ) try: command = build_command(binary, leaf, include_optional, choices) proc = subprocess.run( command, cwd=cwd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, ) # Exit zero proves only that the built command accepted and completed # the reviewed dry-run invocation. Preview/safety evidence belongs to # the fail-closed Go Agent-example gate, not text scraping here. status = ( "runtime_exit_pass" if proc.returncode == 0 else "runtime_exit_fail" ) return SmokeResult( canonical_path=path, case_name=case_name, cli_path=str(leaf.get("cli_path", "")), command=command, status=status, exit_code=proc.returncode, stdout=proc.stdout, stderr=proc.stderr, ) except subprocess.TimeoutExpired as exc: return SmokeResult( canonical_path=path, case_name=case_name, cli_path="", command=exc.cmd if isinstance(exc.cmd, list) else [str(exc.cmd)], status="timeout", exit_code=124, stdout=exc.stdout or "", stderr=exc.stderr or "", error=str(exc), ) except Exception as exc: # noqa: BLE001 - record all smoke failures. return SmokeResult( canonical_path=path, case_name=case_name, cli_path="", command=[], status="error", exit_code=1, stdout="", stderr="", error=str(exc), ) def dry_run_capability_error(leaf: dict[str, Any]) -> str: """Return a closed-shape error for a leaf-local dry_run declaration.""" if "dry_run" not in leaf: return "" capability = leaf["dry_run"] if not isinstance(capability, dict): return "dry_run must be an object" unknown_fields = sorted(set(capability) - {"preview_kind", "remote_reads"}) if unknown_fields: return "dry_run has unsupported fields: " + ", ".join(unknown_fields) preview_kind = capability.get("preview_kind") if not isinstance(preview_kind, str) or preview_kind not in DRY_RUN_PREVIEW_KINDS: allowed = ", ".join(sorted(DRY_RUN_PREVIEW_KINDS)) return f"dry_run.preview_kind must be one of: {allowed}" if "remote_reads" in capability and not isinstance(capability["remote_reads"], bool): return "dry_run.remote_reads must be a boolean" return "" def declared_dry_run(leaf: dict[str, Any]) -> bool: """Return true only for a valid, positive leaf-local declaration.""" problem = dry_run_capability_error(leaf) if problem: raise ValueError(problem) return "dry_run" in leaf def run_one( binary: str, cwd: Path, leaf: dict[str, Any], timeout: int, include_optional: bool, ) -> list[SmokeResult]: path = str(leaf.get("canonical_path", "")) cli_path = str(leaf.get("cli_path", "")) help_command = [binary, *shlex.split(cli_path), "--help"] try: if not path or not cli_path: raise ValueError("full Schema leaf requires canonical_path and cli_path") parameters = leaf.get("parameters") if not isinstance(parameters, dict): raise ValueError("full Schema leaf parameters must be an object") declared = set(parameters) executable = help_schema_flags(binary, cwd, cli_path, timeout) schema_only = sorted(declared - executable) help_only = sorted(executable - declared) if schema_only or help_only: problems = [] if schema_only: problems.append( "Schema-only/non-effective flags: " + ", ".join(schema_only) ) if help_only: problems.append( "effective non-global Help flags missing from Schema: " + ", ".join(help_only) ) return [ SmokeResult( canonical_path=path, case_name="contract", cli_path=cli_path, command=help_command, status="schema_flag_mismatch", exit_code=3, stdout="", stderr="", error="; ".join(problems), ) ] contract = SmokeResult( canonical_path=path, case_name="contract", cli_path=cli_path, command=help_command, status="contract_pass", exit_code=0, stdout="", stderr="", ) capability_problem = dry_run_capability_error(leaf) if capability_problem: contract.status = "invalid_dry_run_capability" contract.exit_code = 3 contract.error = capability_problem return [contract] if not declared_dry_run(leaf): return [contract] return [ contract, *[ run_smoke_case( binary, cwd, path, leaf, timeout, include_optional, choices, ) for choices in one_of_cases(leaf) ], ] except subprocess.TimeoutExpired as exc: return [ SmokeResult( canonical_path=path, case_name="contract", cli_path=cli_path, command=exc.cmd if isinstance(exc.cmd, list) else [str(exc.cmd)], status="timeout", exit_code=124, stdout=exc.stdout or "", stderr=exc.stderr or "", error=str(exc), ) ] except Exception as exc: # noqa: BLE001 - record all smoke failures. return [ SmokeResult( canonical_path=path, case_name="contract", cli_path=cli_path, command=help_command, status="error", exit_code=1, stdout="", stderr="", error=str(exc), ) ] def result_to_dict(result: SmokeResult) -> dict[str, Any]: return { "canonical_path": result.canonical_path, "case": result.case_name, "phase": ( "contract" if result.case_name == "contract" else "runtime_exit_health" ), "cli_path": result.cli_path, "command": result.command, "status": result.status, "exit_code": result.exit_code, "stdout": result.stdout[-4000:], "stderr": result.stderr[-4000:], "error": result.error, } def load_schema_leaves( binary: str, cwd: Path, timeout: int, requested_paths: list[str] | None = None, ) -> list[dict[str, Any]]: """Load the full inventory once and optionally select canonical paths.""" listing = run_json( [binary, "schema", "--all", "--format", "json"], cwd, timeout, attempts=1, ) if not isinstance(listing, dict): raise RuntimeError("schema --all payload must be an object") products = listing.get("products") if not isinstance(products, list): raise RuntimeError("schema --all products must be an array") by_path: dict[str, dict[str, Any]] = {} for product_index, product in enumerate(products): if not isinstance(product, dict): raise RuntimeError( f"schema --all product {product_index} must be an object" ) tools = product.get("tools") if not isinstance(tools, list): raise RuntimeError( f"schema --all product {product_index} tools must be an array" ) for raw_leaf in tools: if not isinstance(raw_leaf, dict): raise RuntimeError("schema --all returned a non-object tool") raw_path = raw_leaf.get("canonical_path") if not isinstance(raw_path, str) or not raw_path.strip(): raise RuntimeError("schema --all returned a tool without canonical_path") path = raw_path.strip() if path in by_path: raise RuntimeError(f"schema --all returned duplicate tool {path}") cli_path = raw_leaf.get("cli_path") if not isinstance(cli_path, str) or not cli_path.strip(): raise RuntimeError( f"schema --all tool {path} has no non-empty cli_path" ) if "parameters" not in raw_leaf: raise RuntimeError( f"schema --all tool {path} is a summary, not a full leaf" ) if not isinstance(raw_leaf["parameters"], dict): raise RuntimeError( f"schema --all full tool {path} parameters must be an object" ) for parameter_name, parameter in raw_leaf["parameters"].items(): if not isinstance(parameter, dict): raise RuntimeError( "schema --all full tool " f"{path} parameter {parameter_name!r} must be an object" ) capability_problem = dry_run_capability_error(raw_leaf) if capability_problem: raise RuntimeError( f"schema --all tool {path} has invalid dry_run: " f"{capability_problem}" ) by_path[path] = raw_leaf if not by_path: raise RuntimeError("schema --all returned no full tools") if not requested_paths: return [by_path[path] for path in sorted(by_path)] selected_paths = list(dict.fromkeys(requested_paths)) missing = sorted(set(selected_paths) - set(by_path)) if missing: raise RuntimeError( "requested canonical path missing from schema --all: " + ", ".join(missing) ) return [by_path[path] for path in selected_paths] def write_markdown( results: list[SmokeResult], output: Path, tool_count: int, runtime_tool_count: int, ) -> None: counts: dict[str, int] = {} for result in results: counts[result.status] = counts.get(result.status, 0) + 1 lines = [ "# Schema Command Smoke Results", "", f"- Generated: {datetime.now(timezone.utc).isoformat()}", f"- Tools: {tool_count}", f"- Contract checks: {sum(r.case_name == 'contract' for r in results)}", f"- Runtime exit-health tools: {runtime_tool_count}", f"- Runtime exit-health cases: {sum(r.case_name.startswith('dry_run/') for r in results)}", f"- Result rows: {len(results)}", "- Safety proof: Go Agent-example dry-run gate (not inferred here)", ] for status in sorted(counts): lines.append(f"- {status}: {counts[status]}") lines.extend(["", "## Non-passing cases", ""]) failures = [ r for r in results if r.status not in {"contract_pass", "runtime_exit_pass"} ] if not failures: lines.append("No failures.") else: lines.append("| canonical_path | case | cli_path | status | exit | issue |") lines.append("| --- | --- | --- | --- | --- | --- |") for result in failures: issue = result.error or result.stderr.strip() or result.stdout.strip() issue = issue.replace("\n", "
") if len(issue) > 500: issue = issue[:500] + "..." lines.append( "| " + " | ".join( [ f"`{result.canonical_path}`", f"`{result.case_name}`", f"`{result.cli_path}`", result.status, str(result.exit_code), issue or "-", ] ) + " |" ) output.write_text("\n".join(lines) + "\n", encoding="utf-8") def main() -> int: parser = argparse.ArgumentParser( description=( "Load full schema --all once, check every selected leaf against " "Cobra Help, and exit-health-check only explicit dry_run capabilities." ) ) parser.add_argument("--binary", default="./dws", help="dws binary to inspect") parser.add_argument("--output-jsonl", default="tmp/schema-command-smoke.jsonl") parser.add_argument("--output-md", default="tmp/schema-command-smoke.md") parser.add_argument( "--jobs", type=int, default=8, help="parallel Help/runtime-health workers" ) parser.add_argument("--timeout", type=int, default=20, help="seconds per subprocess") parser.add_argument( "--include-optional", action="store_true", help="include optional parameters in explicit runtime exit-health cases", ) parser.add_argument( "--path", action="append", help=( "canonical path selected from the single schema --all payload; " "repeatable" ), ) args = parser.parse_args() cwd = Path.cwd() leaves = load_schema_leaves( args.binary, cwd, args.timeout, requested_paths=args.path ) runtime_tool_count = sum(declared_dry_run(leaf) for leaf in leaves) if runtime_tool_count: fixture = Path(tempfile.gettempdir()) / "dws-schema-smoke-fixture.txt" fixture.write_text("schema smoke fixture\n", encoding="utf-8") style_fixture = Path(tempfile.gettempdir()) / "dws-schema-smoke-style.json" style_fixture.write_text( '[{"sheetId":"sheet-smoke","range":"A1","fontSize":12}]\n', encoding="utf-8", ) report_fixture = cwd / "tmp" / "dws-schema-smoke-report.json" report_fixture.parent.mkdir(parents=True, exist_ok=True) report_fixture.write_text( '[{"content":"schema smoke","sort":"0","key":"work",' '"contentType":"markdown","type":"1"}]\n', encoding="utf-8", ) with concurrent.futures.ThreadPoolExecutor(max_workers=args.jobs) as executor: result_groups = list( executor.map( lambda leaf: run_one( args.binary, cwd, leaf, args.timeout, args.include_optional ), leaves, ) ) results = [result for group in result_groups for result in group] results.sort(key=lambda item: (item.canonical_path, item.case_name)) jsonl_path = Path(args.output_jsonl) jsonl_path.parent.mkdir(parents=True, exist_ok=True) with jsonl_path.open("w", encoding="utf-8") as fh: for result in results: fh.write(json.dumps(result_to_dict(result), ensure_ascii=False) + "\n") md_path = Path(args.output_md) md_path.parent.mkdir(parents=True, exist_ok=True) write_markdown(results, md_path, len(leaves), runtime_tool_count) accepted = {"contract_pass", "runtime_exit_pass"} failures = [result for result in results if result.status not in accepted] contract_results = [result for result in results if result.case_name == "contract"] runtime_results = [ result for result in results if result.case_name.startswith("dry_run/") ] print(f"tools={len(leaves)}") print( "contract_pass=" f"{sum(result.status == 'contract_pass' for result in contract_results)}" ) print( "contract_failures=" f"{sum(result.status != 'contract_pass' for result in contract_results)}" ) print(f"runtime_exit_tools={runtime_tool_count}") print(f"runtime_exit_cases={len(runtime_results)}") print( "runtime_exit_failures=" f"{sum(result.status != 'runtime_exit_pass' for result in runtime_results)}" ) print(f"total={len(results)}") print(f"failures={len(failures)}") print(f"jsonl={jsonl_path}") print(f"markdown={md_path}") return 1 if failures else 0 if __name__ == "__main__": raise SystemExit(main())