system-spec-ref 0.1.0__py3-none-any.whl

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 (52) hide show
  1. system_spec_ref/__init__.py +1 -0
  2. system_spec_ref/cli.py +117 -0
  3. system_spec_ref/metamodel.py +614 -0
  4. system_spec_ref/toolkit/.github/skills/alloy/SKILL.md +49 -0
  5. system_spec_ref/toolkit/.github/skills/modelable/SKILL.md +61 -0
  6. system_spec_ref/toolkit/.github/skills/tla/SKILL.md +49 -0
  7. system_spec_ref/toolkit/.github/workflows/metamodel.yml +51 -0
  8. system_spec_ref/toolkit/BROWNFIELD.md +81 -0
  9. system_spec_ref/toolkit/CONSTITUTION.md +205 -0
  10. system_spec_ref/toolkit/GREENFIELD.md +86 -0
  11. system_spec_ref/toolkit/LICENSE +21 -0
  12. system_spec_ref/toolkit/PACKAGING.md +120 -0
  13. system_spec_ref/toolkit/PLAN.md +85 -0
  14. system_spec_ref/toolkit/README.md +77 -0
  15. system_spec_ref/toolkit/WIRING.md +49 -0
  16. system_spec_ref/toolkit/archive/BENCHMARK.md +67 -0
  17. system_spec_ref/toolkit/archive/README.md +8 -0
  18. system_spec_ref/toolkit/archive/REVIEW.md +321 -0
  19. system_spec_ref/toolkit/archive/feedback/modelable-onboarding.md +119 -0
  20. system_spec_ref/toolkit/archive/feedback/observable-onboarding.md +52 -0
  21. system_spec_ref/toolkit/examples/brownfield/README.md +93 -0
  22. system_spec_ref/toolkit/examples/brownfield/level0.yaml +12 -0
  23. system_spec_ref/toolkit/examples/brownfield/level1.yaml +58 -0
  24. system_spec_ref/toolkit/examples/brownfield/old.yaml +65 -0
  25. system_spec_ref/toolkit/examples/brownfield/spec.yaml +85 -0
  26. system_spec_ref/toolkit/examples/greenfield/Inventory.als +72 -0
  27. system_spec_ref/toolkit/examples/greenfield/Inventory.cfg +7 -0
  28. system_spec_ref/toolkit/examples/greenfield/Inventory.tla +49 -0
  29. system_spec_ref/toolkit/examples/greenfield/README.md +79 -0
  30. system_spec_ref/toolkit/examples/greenfield/spec.yaml +91 -0
  31. system_spec_ref/toolkit/packaging.yaml +294 -0
  32. system_spec_ref/toolkit/reference-implementation/.dockerignore +3 -0
  33. system_spec_ref/toolkit/reference-implementation/.gitignore +3 -0
  34. system_spec_ref/toolkit/reference-implementation/Dockerfile +7 -0
  35. system_spec_ref/toolkit/reference-implementation/README.md +44 -0
  36. system_spec_ref/toolkit/reference-implementation/corpus.yaml +86 -0
  37. system_spec_ref/toolkit/reference-implementation/example.yaml +89 -0
  38. system_spec_ref/toolkit/reference-implementation/metamodel.als +133 -0
  39. system_spec_ref/toolkit/reference-implementation/metamodel.py +614 -0
  40. system_spec_ref/toolkit/reference-implementation/old.yaml +63 -0
  41. system_spec_ref/toolkit/reference-implementation/pyproject.toml +16 -0
  42. system_spec_ref/toolkit/reference-implementation/schema.json +1087 -0
  43. system_spec_ref/toolkit/reference-implementation/test_metamodel.py +251 -0
  44. system_spec_ref/toolkit/reference-implementation/test_onboarding.py +142 -0
  45. system_spec_ref/toolkit/reference-implementation/uv.lock +284 -0
  46. system_spec_ref/toolkit/spec.md +299 -0
  47. system_spec_ref/toolkit/templates/BROWNFIELD-INTAKE.md +109 -0
  48. system_spec_ref-0.1.0.dist-info/METADATA +35 -0
  49. system_spec_ref-0.1.0.dist-info/RECORD +52 -0
  50. system_spec_ref-0.1.0.dist-info/WHEEL +4 -0
  51. system_spec_ref-0.1.0.dist-info/entry_points.txt +2 -0
  52. system_spec_ref-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
system_spec_ref/cli.py ADDED
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+ import argparse, importlib.resources, os, shutil, sys, tempfile
3
+ from pathlib import Path
4
+
5
+ from . import metamodel
6
+
7
+ PACKAGE = "system_spec_ref"
8
+ DIST_NAME = "system-spec-ref"
9
+
10
+
11
+ class ExportError(Exception):
12
+ pass
13
+
14
+
15
+ def _iter_resource_files(root, prefix: str = ""):
16
+ for entry in sorted(root.iterdir(), key=lambda e: e.name):
17
+ rel = f"{prefix}{entry.name}"
18
+ if entry.is_dir():
19
+ yield from _iter_resource_files(entry, rel + "/")
20
+ else:
21
+ yield rel, entry
22
+
23
+
24
+ def _validate_entry(rel: str) -> None:
25
+ if rel.startswith("/") or Path(rel).is_absolute():
26
+ raise ExportError(f"unsafe resource entry (absolute path): {rel}")
27
+ if ".." in Path(rel).parts:
28
+ raise ExportError(f"unsafe resource entry (parent traversal): {rel}")
29
+
30
+
31
+ def _cleanup_stage(stage: Path) -> None:
32
+ try:
33
+ shutil.rmtree(stage)
34
+ except OSError as e:
35
+ print(f"warning: failed to clean up staging directory {stage}: {e}", file=sys.stderr)
36
+
37
+
38
+ def export_toolkit(destination: str | Path, *, package: str = PACKAGE) -> Path:
39
+ dest = Path(destination)
40
+ if not dest.is_absolute():
41
+ dest = Path.cwd() / dest
42
+ if dest.is_symlink() or dest.exists():
43
+ raise ExportError(f"destination already exists: {dest}")
44
+ parent = dest.parent
45
+ if not parent.is_dir():
46
+ raise ExportError(f"parent directory does not exist: {parent}")
47
+
48
+ toolkit_root = importlib.resources.files(package) / "toolkit"
49
+ entries = []
50
+ for rel, entry in _iter_resource_files(toolkit_root):
51
+ if hasattr(entry, "is_symlink") and entry.is_symlink():
52
+ raise ExportError(f"unsafe resource entry (symlink): {rel}")
53
+ _validate_entry(rel)
54
+ entries.append((rel, entry))
55
+
56
+ stage = Path(tempfile.mkdtemp(prefix=f".{dest.name}.staging-", dir=parent))
57
+ stage_resolved = str(stage.resolve())
58
+ try:
59
+ for rel, entry in entries:
60
+ dest_path = stage / rel
61
+ if not str(dest_path.resolve()).startswith(stage_resolved + os.sep):
62
+ raise ExportError(f"unsafe resource entry escapes staging area: {rel}")
63
+ dest_path.parent.mkdir(parents=True, exist_ok=True)
64
+ with entry.open("rb") as src, open(dest_path, "wb") as out:
65
+ shutil.copyfileobj(src, out)
66
+ except Exception as e:
67
+ _cleanup_stage(stage)
68
+ raise ExportError(str(e)) from e
69
+
70
+ if dest.is_symlink() or dest.exists():
71
+ _cleanup_stage(stage)
72
+ raise ExportError(f"destination already exists: {dest}")
73
+ try:
74
+ os.mkdir(dest)
75
+ except OSError as e:
76
+ _cleanup_stage(stage)
77
+ raise ExportError(f"destination already exists: {dest}") from e
78
+
79
+ try:
80
+ for child in stage.iterdir():
81
+ shutil.move(str(child), str(dest / child.name))
82
+ stage.rmdir()
83
+ except Exception as e:
84
+ raise ExportError(f"publish failed after claiming destination {dest}: {e}") from e
85
+ return dest
86
+
87
+
88
+ def _run_export(argv: list[str]) -> int:
89
+ ap = argparse.ArgumentParser(prog="system-spec export", description="Export an offline toolkit snapshot.")
90
+ ap.add_argument("destination")
91
+ a = ap.parse_args(argv)
92
+ try:
93
+ dest = export_toolkit(a.destination)
94
+ except ExportError as e:
95
+ print(f"export failed: {e}", file=sys.stderr)
96
+ return 1
97
+ print(f"exported toolkit {metamodel.package_version(DIST_NAME)} to {dest}")
98
+ print(f"next: read {dest / 'WIRING.md'} to wire it into your project and agents")
99
+ return 0
100
+
101
+
102
+ def _run_validate(argv: list[str]) -> int:
103
+ version = metamodel.package_version(DIST_NAME)
104
+ resource = importlib.resources.files(PACKAGE) / "toolkit" / "reference-implementation" / "example.yaml"
105
+ with importlib.resources.as_file(resource) as default_path:
106
+ return metamodel.main(argv, default_spec=default_path, version=version)
107
+
108
+
109
+ def run(argv: list[str] | None = None) -> int:
110
+ argv = list(sys.argv[1:] if argv is None else argv)
111
+ if argv and argv[0] == "export":
112
+ return _run_export(argv[1:])
113
+ return _run_validate(argv)
114
+
115
+
116
+ if __name__ == "__main__":
117
+ sys.exit(run())