its-magic 0.1.3-0 → 0.1.3-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/installer.ps1 +8 -0
  2. package/installer.py +8 -0
  3. package/installer.sh +1 -0
  4. package/package.json +1 -1
  5. package/scripts/check_intake_template_parity.py +62 -0
  6. package/template/.cursor/agents/curator.mdc +1 -0
  7. package/template/.cursor/agents/po.mdc +1 -0
  8. package/template/.cursor/agents/release.mdc +1 -0
  9. package/template/.cursor/commands/auto.md +90 -0
  10. package/template/.cursor/commands/execute.md +26 -0
  11. package/template/.cursor/commands/refresh-context.md +32 -0
  12. package/template/.cursor/commands/sovereign-critic.md +104 -0
  13. package/template/.cursor/model-catalog.local.example.cursor-only.json +9 -0
  14. package/template/.cursor/model-catalog.local.example.json +9 -0
  15. package/template/.cursor/model-catalog.local.example.level-1-easy.json +9 -0
  16. package/template/.cursor/model-catalog.local.example.level-2-complex.json +9 -0
  17. package/template/.cursor/model-catalog.local.example.level-3-mega.json +9 -0
  18. package/template/.cursor/model-catalog.local.example.level-4-super.json +9 -0
  19. package/template/.cursor/model-catalog.local.example.role-based-balanced.json +18 -0
  20. package/template/.cursor/model-catalog.local.example.role-based-highend.json +18 -0
  21. package/template/.cursor/rules/sovereign-role-manifest.mdc.example +27 -0
  22. package/template/.cursor/scratchpad.local.example.md +55 -0
  23. package/template/.cursor/scratchpad.md +203 -0
  24. package/template/.cursor/sovereign-role-manifest.yaml.example +53 -0
  25. package/template/decisions/DEC-0104.md +279 -0
  26. package/template/decisions/DEC-0105.md +231 -0
  27. package/template/decisions/DEC-0107.md +246 -0
  28. package/template/docs/engineering/architecture.md +78 -0
  29. package/template/docs/engineering/auto-orchestration-reference.md +7 -0
  30. package/template/docs/engineering/context/installer-owned-paths.manifest +8 -0
  31. package/template/docs/engineering/reason_codes.md +411 -0
  32. package/template/docs/engineering/runbook.md +1119 -0
  33. package/template/docs/engineering/sovereign-memory/.gitkeep +0 -0
  34. package/template/docs/engineering/sovereign-memory/retrospectives/.gitkeep +0 -0
  35. package/template/handoffs/sovereign_decisions/.gitkeep +0 -0
  36. package/template/handoffs/sovereign_deferrals/.gitkeep +0 -0
  37. package/template/handoffs/sovereign_role_reviews.jsonl +0 -0
  38. package/template/scripts/__pycache__/decision_ledger_lib.cpython-312.pyc +0 -0
  39. package/template/scripts/check_intake_template_parity.py +181 -0
  40. package/template/scripts/decision_ledger_lib.py +732 -0
  41. package/template/scripts/ledger_validate.py +153 -0
  42. package/template/scripts/model_tier_lib.py +680 -0
  43. package/template/scripts/model_tier_validate.py +368 -0
  44. package/template/scripts/parallel_dev_arbiter.py +923 -0
  45. package/template/scripts/release_trigger_adapters.py +843 -0
  46. package/template/scripts/self_healing_deploy_lib.py +463 -0
  47. package/template/scripts/self_healing_deploy_validate.py +78 -0
  48. package/template/scripts/sovereign_convergence_lib.py +994 -0
  49. package/template/scripts/sovereign_convergence_validate.py +206 -0
  50. package/template/scripts/sovereign_critic_lib.py +629 -0
  51. package/template/scripts/sovereign_critic_validate.py +131 -0
  52. package/template/scripts/sovereign_loop_lib.py +828 -0
  53. package/template/scripts/sovereign_loop_validate.py +122 -0
  54. package/template/scripts/sovereign_memory_lib.py +869 -0
  55. package/template/scripts/sovereign_memory_validate.py +153 -0
  56. package/template/scripts/sovereign_role_manifest_lib.py +547 -0
  57. package/template/scripts/sovereign_role_manifest_validate.py +105 -0
  58. package/template/tests/us0108_contract_test.py +207 -0
  59. package/template/tests/us0109_contract_test.py +209 -0
  60. package/template/tests/us0109_us0110_compose_test.py +34 -0
  61. package/template/tests/us0111_contract_test.py +345 -0
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AI Decision Ledger JSONL validator (US-0103 / DEC-0103).
4
+
5
+ Validates:
6
+ - 12-field schema v1 per JSONL line
7
+ - One-file-per-orchestrator-run path layout
8
+ - Bounded QA digest emission
9
+
10
+ Exit codes:
11
+ - 0: All validations passed (or --self-test OK)
12
+ - 1: Fail-closed code hit
13
+ - 2: Usage error
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import json
20
+ import os
21
+ import sys
22
+ from pathlib import Path
23
+ from typing import List, Tuple
24
+
25
+ _SCRIPT_DIR = Path(__file__).resolve().parent
26
+ sys.path.insert(0, str(_SCRIPT_DIR))
27
+
28
+ from decision_ledger_lib import ( # noqa: E402
29
+ LEDGER_REQUIRED_FIELDS,
30
+ ReasonCode,
31
+ build_qa_findings_block,
32
+ is_ledger_enabled,
33
+ read_entries,
34
+ resolve_ledger_path,
35
+ schema_check,
36
+ self_test,
37
+ summary_digest,
38
+ )
39
+
40
+
41
+ def validate_single_file(ledger_path: Path, *, strict: bool = True) -> Tuple[bool, List[str], List[ReasonCode]]:
42
+ """Validate every JSONL entry in one ledger file. Returns (ok, errors, codes)."""
43
+ errors: List[str] = []
44
+ codes: List[ReasonCode] = []
45
+
46
+ if not ledger_path.exists():
47
+ return False, [f"Ledger file not found: {ledger_path}"], [ReasonCode.LEDGER_FILE_MISSING]
48
+
49
+ entries, reason, message = read_entries(ledger_path, strict=strict)
50
+ if reason is not None:
51
+ if reason in (ReasonCode.LEDGER_CORRUPT, ReasonCode.LEDGER_SCHEMA_INVALID):
52
+ errors.append(f"[{reason.value}] {message}")
53
+ codes.append(reason)
54
+ return len(errors) == 0, errors, codes
55
+ if reason == ReasonCode.LEDGER_FILE_MISSING:
56
+ errors.append(f"[{reason.value}] {message}")
57
+ codes.append(reason)
58
+ return len(errors) == 0, errors, codes
59
+ if reason == ReasonCode.LEDGER_READ_BOUND:
60
+ pass
61
+
62
+ if not ledger_path.name.endswith(".jsonl"):
63
+ errors.append(f"Ledger file must end with .jsonl: {ledger_path.name}")
64
+
65
+ if not ledger_path.parent.name == "sovereign_decisions":
66
+ errors.append(f"Ledger must live in handoffs/sovereign_decisions/: {ledger_path}")
67
+
68
+ return len(errors) == 0, errors, codes
69
+
70
+
71
+ def main() -> int:
72
+ parser = argparse.ArgumentParser(
73
+ description="Decision ledger JSONL validator (US-0103 / DEC-0103)",
74
+ formatter_class=argparse.RawDescriptionHelpFormatter,
75
+ epilog="""
76
+ Examples:
77
+ python scripts/ledger_validate.py --self-test
78
+ python scripts/ledger_validate.py --file handoffs/sovereign_decisions/auto-20260628-01.jsonl
79
+ python scripts/ledger_validate.py --repo .
80
+ python scripts/ledger_validate.py --file handoffs/sovereign_decisions/auto-20260628-01.jsonl --enforce
81
+ python scripts/ledger_validate.py --qa-find --orchestrator-run-id auto-20260628-01 --repo .
82
+ """,
83
+ )
84
+ parser.add_argument("--file", type=Path, help="Validate single JSONL ledger file")
85
+ parser.add_argument("--repo", type=Path, help="Validate all ledger files in handoffs/sovereign_decisions/")
86
+ parser.add_argument("--self-test", action="store_true", help="Run library self-test")
87
+ parser.add_argument("--enforce", action="store_true", help="Exit non-zero on any fail-closed code")
88
+ parser.add_argument(
89
+ "--qa-find",
90
+ action="store_true",
91
+ help="Build QA findings block (prints JSON) for ledger; needs --orchestrator-run-id",
92
+ )
93
+ parser.add_argument("--orchestrator-run-id", help="Orchestrator run id for --qa-find / --file resolution")
94
+
95
+ args = parser.parse_args()
96
+
97
+ if args.self_test:
98
+ return 0 if self_test() else 1
99
+
100
+ if args.qa_find:
101
+ if not args.orchestrator_run_id:
102
+ print("[USAGE] --qa-find requires --orchestrator-run-id", file=sys.stderr)
103
+ return 2
104
+ repo_root = Path(args.repo) if args.repo else Path.cwd()
105
+ ledger_path = resolve_ledger_path(args.orchestrator_run_id, repo_root)
106
+ block, blocking = build_qa_findings_block(ledger_path, args.orchestrator_run_id)
107
+ print(json.dumps(block, indent=2, sort_keys=True))
108
+ if blocking is not None:
109
+ return 1 if args.enforce else 0
110
+ return 0
111
+
112
+ all_errors: List[str] = []
113
+ all_codes: List[ReasonCode] = []
114
+
115
+ if args.file:
116
+ ok, errs, codes = validate_single_file(Path(args.file))
117
+ all_errors.extend(errs)
118
+ all_codes.extend(codes)
119
+ elif args.repo:
120
+ sovereign_dir = Path(args.repo) / "handoffs" / "sovereign_decisions"
121
+ if sovereign_dir.exists():
122
+ for ledger_path in sorted(sovereign_dir.glob("*.jsonl")):
123
+ ok, errs, codes = validate_single_file(ledger_path)
124
+ if not ok:
125
+ all_errors.extend([f"{ledger_path}: {e}" for e in errs])
126
+ all_codes.extend(codes)
127
+
128
+ if not args.file and not args.repo:
129
+ sovereign_dir = Path.cwd() / "handoffs" / "sovereign_decisions"
130
+ if sovereign_dir.exists():
131
+ for ledger_path in sorted(sovereign_dir.glob("*.jsonl")):
132
+ ok, errs, codes = validate_single_file(ledger_path)
133
+ if not ok:
134
+ all_errors.extend([f"{ledger_path}: {e}" for e in errs])
135
+ all_codes.extend(codes)
136
+
137
+ if all_errors:
138
+ print(f"\n[LEDGER_VALIDATION_FAILED] {len(all_errors)} error(s)", file=sys.stderr)
139
+ for err in all_errors:
140
+ print(f" {err}", file=sys.stderr)
141
+ if args.enforce:
142
+ return 1
143
+ return 1 if any(
144
+ c in (ReasonCode.LEDGER_FILE_MISSING, ReasonCode.LEDGER_SCHEMA_INVALID, ReasonCode.LEDGER_CORRUPT)
145
+ for c in all_codes
146
+ ) else 0
147
+
148
+ print("[LEDGER_VALIDATION_OK]")
149
+ return 0
150
+
151
+
152
+ if __name__ == "__main__":
153
+ raise SystemExit(main())