feat(plane): manifest schemas and validation (task 1)

Add openultrasast.plane.manifests: frozen dataclasses and loaders for ax's
Task, Workspace and Model kinds (ax.io/v1alpha1, ax's fields only) and the
Run kind (openultrasast.io/v1alpha1: tasks, dependsOn, inputs, outputs,
budget, serialize). Every violation raises ManifestError naming the kind,
metadata.name and field path: unknown fields at any depth, wrong apiVersion
or kind, a provider outside google/anthropic unless deepseek is declared via
the openultrasast.io/provider-extension annotation, a Run with a dependency
cycle, an input naming no task, and a Run task naming no loaded Task.
load_manifests reads multi-document YAML files and indexes by kind and name.

PyYAML becomes the one declared core dependency; the two zero-dependency
guards now pin exactly that, and the module audit registers the plane
package under the ai-service-plane spec.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-09-29 17:44:31 +02:00
co-authored by Claude Fable 5.1
parent 152728c052
commit c728808316
8 changed files with 989 additions and 8 deletions
+2 -2
View File
@@ -13,9 +13,9 @@ from openultrasast.semantic.extra import grammar_for, has_semantic_extra
from openultrasast.semantic.ir import parse_file
def test_core_dependencies_stay_empty_and_semantic_is_optional() -> None:
def test_core_dependencies_are_pyyaml_only_and_semantic_is_optional() -> None:
payload = tomllib.loads(Path("pyproject.toml").read_text())
assert payload["project"]["dependencies"] == []
assert payload["project"]["dependencies"] == ["pyyaml>=6.0"] # ai-service-plane task 1: manifests are YAML
extra = payload["project"]["optional-dependencies"]["semantic"]
joined = " ".join(extra)
assert "tree-sitter" in joined