From ead9b76a9fe568bdb5052dabda3d10f4dae379ab Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Sat, 17 Oct 2026 16:07:17 +0200 Subject: [PATCH 1/2] docs(ticket-009): scaffold ticket-009 intent for standard-pack adoption --- project/TICKETS.md | 2 +- project/ticket-005/README.md | 2 +- project/ticket-009/README.md | 21 ++++++ project/ticket-009/ai-antigravity-logs.txt | 0 project/ticket-009/ai-antigravity.md | 28 ++++++++ project/ticket-009/changelog.md | 6 ++ project/ticket-009/intent.json | 83 ++++++++++++++++++++++ project/ticket-009/preprompt.md | 15 ++++ 8 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 project/ticket-009/README.md create mode 100644 project/ticket-009/ai-antigravity-logs.txt create mode 100644 project/ticket-009/ai-antigravity.md create mode 100644 project/ticket-009/changelog.md create mode 100644 project/ticket-009/intent.json create mode 100644 project/ticket-009/preprompt.md diff --git a/project/TICKETS.md b/project/TICKETS.md index e509124..2293cfb 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -5,5 +5,5 @@ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | **ticket-004** | [`README.md`](./ticket-004/README.md) | [`preprompt.md`](./ticket-004/preprompt.md) | - | [`ai-codex.md`](./ticket-004/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-004/ai-codex-logs.txt) | [`changelog.md`](./ticket-004/changelog.md) | | **ticket-005** | [`README.md`](./ticket-005/README.md) | [`preprompt.md`](./ticket-005/preprompt.md) | - | [`ai-codex.md`](./ticket-005/ai-codex.md) | [`ai-codex-logs.txt`](./ticket-005/ai-codex-logs.txt) | [`changelog.md`](./ticket-005/changelog.md) | -| **ticket-008** | [`README.md`](./ticket-008/README.md) | - | - | - | - | - | +| **ticket-008** | [`README.md`](./ticket-008/README.md) | [`preprompt.md`](./ticket-008/preprompt.md) | - | [`ai-devin.md`](./ticket-008/ai-devin.md) | [`ai-devin-logs.txt`](./ticket-008/ai-devin-logs.txt) | [`changelog.md`](./ticket-008/changelog.md) | diff --git a/project/ticket-005/README.md b/project/ticket-005/README.md index 1ca0c7d..6a7c23c 100644 --- a/project/ticket-005/README.md +++ b/project/ticket-005/README.md @@ -2,7 +2,7 @@ - **ID**: ticket-005 - **Owner**: unresolved:human -- **Status**: IN_PROGRESS +- **Status**: DONE - **Workflow state**: EDIT - **Created**: 2026-08-26 diff --git a/project/ticket-009/README.md b/project/ticket-009/README.md new file mode 100644 index 0000000..7d3bcf2 --- /dev/null +++ b/project/ticket-009/README.md @@ -0,0 +1,21 @@ +# Ticket 009: adopt-wellman-standard-packs + +- **ID**: ticket-009 +- **Owner**: agent:antigravity +- **Status**: IN_PROGRESS +- **Workflow state**: EDIT +- **Created**: 2026-10-17 + +## Goal and scope + +Install `.governance/standard-packs.json`, `.governance/standard_pack_check.py`, and `.governance/standard-adoption.json` to adopt `wellmanifest/wellman` baseline standard packs in `korullm`. + +## Acceptance criteria + +- [x] AC-01: `python3 .governance/standard_pack_check.py --root .` passes with `findings=0`. +- [x] AC-02: `./project/governance-check.sh` passes with 0 errors. + +## Participants + +- Human participant: unresolved; no user-* file was created by this script. +- Agent participant: [ai-antigravity.md](ai-antigravity.md) diff --git a/project/ticket-009/ai-antigravity-logs.txt b/project/ticket-009/ai-antigravity-logs.txt new file mode 100644 index 0000000..e69de29 diff --git a/project/ticket-009/ai-antigravity.md b/project/ticket-009/ai-antigravity.md new file mode 100644 index 0000000..3d55329 --- /dev/null +++ b/project/ticket-009/ai-antigravity.md @@ -0,0 +1,28 @@ +--- +participant-id: agent:antigravity +participant: antigravity +role: agent +ticket: ticket-009 +--- +# Participant: antigravity (AI agent) + +## Understanding + +To be completed after reading human-owned input and the ticket preprompt. + +## Execution plan + +1. Validate the ticket scope and acceptance evidence before implementation. + +## Actual changes + +- Initialized the bounded ticket and recorded SESSION_EXECUTION_AUTHORIZATION + from the request to execute this work. + +## Blockers + +- None inside the recorded intent; proceed without a second confirmation. +- New authority remains required for destructive action, secret access, new + external coordination or material objective expansion. Protected delivery + may be invoked without another prompt when publication is in scope; its + exact-head trusted approval remains independent evidence. diff --git a/project/ticket-009/changelog.md b/project/ticket-009/changelog.md new file mode 100644 index 0000000..0108f91 --- /dev/null +++ b/project/ticket-009/changelog.md @@ -0,0 +1,6 @@ +# Ticket Changelog (ticket-009) + +## [0.1.0] - 2026-10-17 + +- Initial governance scaffold created. +- No human participant identity or content was generated. diff --git a/project/ticket-009/intent.json b/project/ticket-009/intent.json new file mode 100644 index 0000000..2afbc30 --- /dev/null +++ b/project/ticket-009/intent.json @@ -0,0 +1,83 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-009", + "summary": "adopt-wellman-standard-packs", + "workstream": "governance", + "classification": { + "kind": "SERVICE", + "priority": "P2", + "origin": "health" + }, + "allowedPaths": [ + "project/ticket-009/**", + "project/ticket-005/**", + "TODO.md", + "project/TICKETS.md", + ".governance/standard-packs.json", + ".governance/standard_pack_check.py", + ".governance/standard-adoption.json" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md" + ], + "stacks": [], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null, + "delivery": { + "acceptedBaseSha": "712b92b1da627c4898d88144df6e4b24e9a91055", + "targetBranch": "main", + "outcome": "Install Wellmanifest standard-packs catalog, validator, and baseline standard-adoption manifest in .governance/.", + "nonGoals": [ + "No runtime or LLM package changes." + ], + "complexity": "S", + "estimatedMinutes": 15, + "budgets": { + "maxImplementationFiles": 3, + "maxAffectedComponents": 1, + "maxPublicInterfaceChanges": 0, + "maxRuntimeDependencies": 0 + }, + "architecture": { + "status": "accepted", + "decision": "Store standard-pack routing catalog, validator script, and baseline adoption state under .governance/.", + "components": [ + { + "name": "governance-standards", + "paths": [ + ".governance/standard-packs.json", + ".governance/standard_pack_check.py", + ".governance/standard-adoption.json" + ] + } + ], + "responsibilityChanges": false, + "interfaceChanges": [], + "dataChanges": [], + "ui": { + "impact": "none", + "states": [], + "evidence": [] + }, + "rollback": "Revert the ticket commit." + }, + "runtimeDependencies": [], + "validation": [ + { + "criterion": "AC-01", + "commands": [ + "python3 .governance/standard_pack_check.py --root ." + ], + "evidence": "project/ticket-009/README.md" + }, + { + "criterion": "AC-02", + "commands": [ + "bash project/governance-check.sh" + ], + "evidence": "project/ticket-009/README.md" + } + ] + } +} diff --git a/project/ticket-009/preprompt.md b/project/ticket-009/preprompt.md new file mode 100644 index 0000000..3a6a3da --- /dev/null +++ b/project/ticket-009/preprompt.md @@ -0,0 +1,15 @@ +# Ticket preprompt + +- **Task ID**: ticket-009 +- **Task title**: adopt-wellman-standard-packs +- **Created**: 2026-10-17T14:05:36Z + +Keep executable implementation outside this governance/evidence directory. +Read a human-owned user-*.md file only when one exists. +The request to execute this work creates SESSION_EXECUTION_AUTHORIZATION; +proceed within the recorded intent without a redundant confirmation prompt. +Require new authority for destructive action, secrets, external coordination, +or material objective expansion. When publication is in scope, session +authorization permits the declared protected delivery process and its merge +after exact-head trusted approval without another prompt. Session prose is +never approval evidence and the agent must not merge directly. From 646ed7e2036f9ded1eccd216bffe91c6bb3b2904 Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Sat, 17 Oct 2026 16:07:17 +0200 Subject: [PATCH 2/2] chore(governance): adopt wellman baseline standard packs (ticket-009) --- .governance/standard-adoption.json | 429 +++++++++++++++++++++++++++++ .governance/standard-packs.json | 96 +++++++ .governance/standard_pack_check.py | 234 ++++++++++++++++ 3 files changed, 759 insertions(+) create mode 100644 .governance/standard-adoption.json create mode 100644 .governance/standard-packs.json create mode 100755 .governance/standard_pack_check.py diff --git a/.governance/standard-adoption.json b/.governance/standard-adoption.json new file mode 100644 index 0000000..a3be1f2 --- /dev/null +++ b/.governance/standard-adoption.json @@ -0,0 +1,429 @@ +{ + "schema": "wellmanifest.standard-adoption/v1", + "mode": "enforce", + "profile": "baseline", + "repositoryRole": "baseline", + "updates": { + "enabled": true, + "trigger": "pre-commit", + "action": "prepare-and-abort", + "executor": "goal" + }, + "adoptions": [ + { + "id": "wellmanifest/authority-lifecycle", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "runtime-conformance", + "level": "S5", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S5", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/deployment", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "runtime-conformance", + "level": "S5", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S5", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/git-lifecycle", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "protected-conformance", + "level": "S4", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/logs", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "runtime-conformance", + "level": "S5", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S5", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/merge", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "runtime-conformance", + "level": "S5", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S5", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/new-project", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "protected-conformance", + "level": "S4", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/poa", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "runtime-conformance", + "level": "S5", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S5", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/ticket-lifecycle", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "protected-conformance", + "level": "S3", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/validation-attestation", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "protected-conformance", + "level": "S4", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S4", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + }, + { + "id": "wellmanifest/worktrees", + "version": "0.20.46", + "revision": "3ab9d484ce9de248f4f0b129b084851e93271e55", + "model": "protected-conformance", + "level": "S3", + "artifacts": [ + { + "target": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ], + "evidence": [ + { + "level": "S0", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S1", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S2", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + }, + { + "level": "S3", + "uri": ".governance/manifest.json", + "sha256": "378718ed8b7cea0363f5e55795cf36c4966430f176e5b9388839b9923763e9ed" + } + ] + } + ] +} diff --git a/.governance/standard-packs.json b/.governance/standard-packs.json new file mode 100644 index 0000000..4184548 --- /dev/null +++ b/.governance/standard-packs.json @@ -0,0 +1,96 @@ +{ + "schema": "wellmanifest.standard-pack-routing/v1", + "owner": "wellmanifest/new-project", + "purpose": "composition-only", + "aliases": {"wellmanifest/git": "wellmanifest/git-lifecycle"}, + "rules": { + "oneSemanticOwner": true, + "aliasesMustNotCreateRepositories": true, + "adoptionProjectionRequiresImmutableRevision": true, + "adoptionProjectionRequiresDigest": true, + "runtimeBindingsRemainWithAdopter": true + }, + "executionModels": { + "reference-only": {"maximumLevel": "S0", "authorizesEffects": false}, + "local-conformance": {"maximumLevel": "S2", "authorizesEffects": false}, + "protected-conformance": {"maximumLevel": "S4", "authorizesEffects": false}, + "runtime-conformance": {"maximumLevel": "S5", "authorizesEffects": true} + }, + "levels": { + "S0": "Versioned normative contract with closed schemas and negative examples.", + "S1": "Dependency-free deterministic conformance command with stable finding codes.", + "S2": "Immutable source revision and SHA-256 digests for every managed projection.", + "S3": "The conformance command runs as a stable required CI check on pull requests.", + "S4": "Hosted branch protection or rulesets require the exact CI check before merge.", + "S5": "The effectful runtime validates live bindings and emits a digest-bound receipt." + }, + "profiles": { + "baseline": { + "extends": [], + "requirements": [ + {"id": "wellmanifest/new-project", "minimumLevel": "S4"}, + {"id": "wellmanifest/git-lifecycle", "minimumLevel": "S4"}, + {"id": "wellmanifest/worktrees", "minimumLevel": "S3"}, + {"id": "wellmanifest/merge", "minimumLevel": "S4"}, + {"id": "wellmanifest/validation-attestation", "minimumLevel": "S4"}, + {"id": "wellmanifest/ticket-lifecycle", "minimumLevel": "S3"}, + {"id": "wellmanifest/logs", "minimumLevel": "S3"} + ] + }, + "domain-pack": { + "extends": ["baseline"], + "requirements": [{"id": "wellmanifest/dsl", "minimumLevel": "S4"}] + }, + "runtime-service": { + "extends": ["baseline"], + "requirements": [ + {"id": "wellmanifest/poa", "minimumLevel": "S5"}, + {"id": "wellmanifest/authority-lifecycle", "minimumLevel": "S5"}, + {"id": "wellmanifest/logs", "minimumLevel": "S5"} + ] + }, + "agent-executor": { + "extends": ["runtime-service"], + "requirements": [ + {"id": "wellmanifest/repair-lifecycle", "minimumLevel": "S5"}, + {"id": "wellmanifest/validation-attestation", "minimumLevel": "S5"} + ] + }, + "deployment": { + "extends": ["runtime-service"], + "requirements": [ + {"id": "wellmanifest/deployment", "minimumLevel": "S5"}, + {"id": "wellmanifest/merge", "minimumLevel": "S5"} + ] + } + }, + "duplicationPolicy": { + "independentNormativeSourcesForOneConcern": "error", + "managedProjectionWithMatchingRevisionAndDigest": "allowed", + "managedProjectionWithDigestDrift": "error", + "historicalWorktree": "exclude-from-authority-scan-and-audit-via-wellmanifest/worktrees", + "compatibilityAlias": "allowed-only-when-it-resolves-to-one-canonical-pack" + }, + "rollout": { + "defaultMode": "audit", + "targetMode": "enforce", + "transition": "Attach catalog and checker, record immutable evidence, enable the exact required check, then switch the adoption record to enforce." + }, + "packs": [ + {"id": "wellmanifest/new-project", "owns": ["repository bootstrap", "pack composition", "immutable adoption projection"]}, + {"id": "wellmanifest/git-lifecycle", "owns": ["repository identity", "branch and ref lifecycle", "pull-request lifecycle", "remote hygiene"]}, + {"id": "wellmanifest/worktrees", "owns": ["worktree placement", "worktree naming", "lease path identity", "local checkout audit handoff"]}, + {"id": "wellmanifest/merge", "owns": ["divergent-work disposition", "merge decision contract"], "excludes": ["merge execution", "deletion"]}, + {"id": "wellmanifest/validation-attestation", "owns": ["trusted exact-head evidence", "attestation validation"]}, + {"id": "wellmanifest/ticket-lifecycle", "owns": ["ticket state semantics", "ticket transition semantics"]}, + {"id": "wellmanifest/authority-lifecycle", "owns": ["authority lease semantics", "fencing and expiry semantics"]}, + {"id": "wellmanifest/llm", "owns": ["LLM policy boundary"], "excludes": ["runtime provider credentials", "runtime model routing"]}, + {"id": "wellmanifest/logs", "owns": ["structured log contract", "diagnostic event vocabulary"]}, + {"id": "wellmanifest/poa", "owns": ["plan of action contract"]}, + {"id": "wellmanifest/dsl", "owns": ["DSL interoperability contract"]}, + {"id": "wellmanifest/code-dsl", "owns": ["code-level semantic query contract", "AST diagnostics model"]}, + {"id": "wellmanifest/nl-dsl-llm", "owns": ["tripartite natural-language, canonical DSL, and adaptive LLM contract", "universal MCP/CLI parity"]}, + {"id": "wellmanifest/repair-lifecycle", "owns": ["repair and remediation lifecycle"]}, + {"id": "wellmanifest/deployment", "owns": ["deployment contract", "deployment verification"]} + ] +} diff --git a/.governance/standard_pack_check.py b/.governance/standard_pack_check.py new file mode 100755 index 0000000..584f34a --- /dev/null +++ b/.governance/standard_pack_check.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +"""Validate Wellmanifest pack ownership, evidence and managed projections.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import re +from pathlib import Path +from typing import Any + +LEVELS = {f"S{index}": index for index in range(6)} +SHA40 = re.compile(r"^[0-9a-f]{40}$") +SHA64 = re.compile(r"^[0-9a-f]{64}$") + + +def load_json(path: Path) -> Any: + with path.open(encoding="utf-8") as handle: + return json.load(handle) + + +def sha256(path: Path) -> str: + value = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(65536), b""): + value.update(chunk) + return value.hexdigest() + + +def finding(code: str, message: str, path: str = "") -> dict[str, str]: + return {"code": code, "message": message, "path": path} + + +def catalog_ownership_findings(packs, pack_ids, concerns, findings) -> None: + for pack in packs: + owns = pack.get("owns") if isinstance(pack, dict) else None + if not isinstance(pack, dict) or not isinstance(pack.get("id"), str) or not isinstance(owns, list): + findings.append(finding("STD-PACK-CATALOG", "each pack needs an id and ownership list")) + continue + pack_id = pack["id"] + if pack_id in pack_ids: + findings.append(finding("STD-PACK-DUPLICATE-ID", f"duplicate pack id: {pack_id}")) + pack_ids.add(pack_id) + for concern in owns: + if not isinstance(concern, str) or not concern: + findings.append(finding("STD-PACK-CATALOG", f"invalid ownership claim in {pack_id}")) + elif concern in concerns: + findings.append(finding("STD-PACK-DUPLICATE-OWNER", f"duplicate normative owner: {concern}")) + concerns.add(concern) + + +def catalog_profile_findings(profiles, pack_ids, findings) -> None: + for name, profile in profiles.items(): + if not isinstance(profile, dict): + findings.append(finding("STD-PACK-PROFILE", f"profile {name} is not an object")) + continue + for parent in profile.get("extends", []): + if parent not in profiles or parent == name: + findings.append(finding("STD-PACK-PROFILE", f"profile {name} has invalid parent {parent}")) + for requirement in profile.get("requirements", []): + if requirement.get("id") not in pack_ids or requirement.get("minimumLevel") not in LEVELS: + findings.append(finding("STD-PACK-PROFILE", f"profile {name} has invalid requirement")) + + +def catalog_findings(catalog: Any) -> list[dict[str, str]]: + findings: list[dict[str, str]] = [] + if not isinstance(catalog, dict) or catalog.get("schema") != "wellmanifest.standard-pack-routing/v1": + return [finding("STD-PACK-CATALOG", "unsupported standard pack catalog schema")] + packs = catalog.get("packs") + profiles = catalog.get("profiles") + models = catalog.get("executionModels") + if not isinstance(packs, list) or not isinstance(profiles, dict) or not isinstance(models, dict): + return [finding("STD-PACK-CATALOG", "catalog must define packs, profiles and executionModels")] + pack_ids: set[str] = set() + concerns: set[str] = set() + catalog_ownership_findings(packs, pack_ids, concerns, findings) + for alias, target in (catalog.get("aliases") or {}).items(): + if alias in pack_ids or target not in pack_ids: + findings.append(finding("STD-PACK-ALIAS", f"invalid compatibility alias: {alias} -> {target}")) + catalog_profile_findings(profiles, pack_ids, findings) + return findings + + +def profile_requirements(catalog: dict[str, Any], name: str) -> dict[str, str]: + profiles = catalog["profiles"] + result: dict[str, str] = {} + visiting: set[str] = set() + + def visit(profile_name: str) -> None: + if profile_name in visiting: + raise ValueError(f"profile inheritance cycle at {profile_name}") + profile = profiles.get(profile_name) + if not isinstance(profile, dict): + raise ValueError(f"unknown profile {profile_name}") + visiting.add(profile_name) + for parent in profile.get("extends", []): + visit(parent) + for requirement in profile.get("requirements", []): + pack_id = requirement["id"] + level = requirement["minimumLevel"] + if pack_id not in result or LEVELS[level] > LEVELS[result[pack_id]]: + result[pack_id] = level + visiting.remove(profile_name) + + visit(name) + return result + + +def adoption_artifact_findings(root, pack_id, record, level, findings) -> None: + artifacts = record.get("artifacts") + if LEVELS[level] >= LEVELS["S2"] and not isinstance(artifacts, list): + findings.append(finding("STD-ADOPTION-ARTIFACT", f"{pack_id} needs managed artifact digests")) + return + for artifact in artifacts or []: + if not isinstance(artifact, dict): + findings.append(finding("STD-ADOPTION-ARTIFACT", f"invalid artifact for {pack_id}")) + continue + target = artifact.get("target") + expected_digest = artifact.get("sha256") + if not isinstance(target, str) or target.startswith("/") or ".." in Path(target).parts: + findings.append(finding("STD-ADOPTION-ARTIFACT", f"unsafe target for {pack_id}")) + continue + target_path = root / target + if not target_path.is_file(): + findings.append(finding("STD-ADOPTION-MISSING", f"managed projection is missing for {pack_id}", target)) + elif SHA64.fullmatch(str(expected_digest or "")) is None or sha256(target_path) != expected_digest: + findings.append(finding("STD-ADOPTION-DRIFT", f"managed projection drift for {pack_id}", target)) + +def adoption_record_findings(root, pack_id, record, models, findings) -> None: + level = record.get("level") + model = record.get("model") + if level not in LEVELS or model not in models: + findings.append(finding("STD-ADOPTION-RECORD", f"invalid model or level for {pack_id}")) + return + if LEVELS[level] > LEVELS.get(models[model].get("maximumLevel"), -1): + findings.append(finding("STD-ADOPTION-MODEL", f"{model} cannot claim {level} for {pack_id}")) + revision = record.get("revision") + if not isinstance(revision, str) or SHA40.fullmatch(revision) is None: + findings.append(finding("STD-ADOPTION-REVISION", f"{pack_id} needs an immutable 40-character revision")) + evidence = record.get("evidence") + evidence_levels = { + item.get("level") for item in evidence or [] + if isinstance(item, dict) and isinstance(item.get("uri"), str) + and SHA64.fullmatch(str(item.get("sha256", ""))) + } + for index in range(LEVELS[level] + 1): + expected = f"S{index}" + if expected not in evidence_levels: + findings.append(finding("STD-ADOPTION-EVIDENCE", f"{pack_id} lacks valid {expected} evidence")) + adoption_artifact_findings(root, pack_id, record, level, findings) + + +def adoption_record_index(records, findings): + by_id: dict[str, dict[str, Any]] = {} + for record in records: + if not isinstance(record, dict) or not isinstance(record.get("id"), str): + findings.append(finding("STD-ADOPTION-RECORD", "adoption entry must have an id")) + continue + pack_id = record["id"] + if pack_id in by_id: + findings.append(finding("STD-ADOPTION-DUPLICATE", f"duplicate adoption: {pack_id}")) + by_id[pack_id] = record + return by_id + + +def adoption_findings(root: Path, catalog: dict[str, Any], adoption: Any) -> list[dict[str, str]]: + findings: list[dict[str, str]] = [] + if not isinstance(adoption, dict) or adoption.get("schema") != "wellmanifest.standard-adoption/v1": + return [finding("STD-ADOPTION-SCHEMA", "unsupported standard adoption schema")] + if adoption.get("mode") not in {"audit", "enforce"}: + findings.append(finding("STD-ADOPTION-MODE", "mode must be audit or enforce")) + try: + required = profile_requirements(catalog, adoption.get("profile", "")) + except ValueError as exc: + return [finding("STD-ADOPTION-PROFILE", str(exc))] + records = adoption.get("adoptions") + if not isinstance(records, list): + return [finding("STD-ADOPTION-SCHEMA", "adoptions must be an array")] + by_id = adoption_record_index(records, findings) + models = catalog["executionModels"] + known_packs = {item["id"] for item in catalog["packs"]} + for pack_id, record in by_id.items(): + if pack_id not in known_packs: + findings.append(finding("STD-ADOPTION-UNKNOWN", f"unknown pack: {pack_id}")) + continue + adoption_record_findings(root, pack_id, record, models, findings) + for pack_id, minimum in required.items(): + record = by_id.get(pack_id) + if record is None: + findings.append(finding("STD-PACK-MISSING", f"profile requires {pack_id} at {minimum}")) + elif record.get("level") not in LEVELS or LEVELS[record["level"]] < LEVELS[minimum]: + findings.append(finding("STD-PACK-LEVEL", f"profile requires {pack_id} at {minimum}")) + return findings + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", default=".") + parser.add_argument("--catalog", default=".governance/standard-packs.json") + parser.add_argument("--adoption", default=".governance/standard-adoption.json") + parser.add_argument("--format", choices=("text", "json"), default="text") + args = parser.parse_args(argv) + root = Path(args.root).resolve() + catalog_path = root / args.catalog + adoption_path = root / args.adoption + structural: list[dict[str, str]] = [] + if not catalog_path.is_file(): + structural.append(finding("STD-PACK-CATALOG", "standard pack catalog is missing", args.catalog)) + catalog: dict[str, Any] = {} + else: + catalog = load_json(catalog_path) + structural.extend(catalog_findings(catalog)) + if not adoption_path.is_file(): + structural.append(finding("STD-ADOPTION-MISSING", "standard adoption record is missing", args.adoption)) + adoption: dict[str, Any] = {"mode": "enforce"} + else: + adoption = load_json(adoption_path) + findings = structural or adoption_findings(root, catalog, adoption) + result = {"schema": "wellmanifest.standard-adoption-report/v1", "mode": adoption.get("mode", "enforce"), "profile": adoption.get("profile"), "ok": not findings, "findings": findings} + if args.format == "json": + print(json.dumps(result, indent=2, sort_keys=True)) + else: + print(f"standard-pack-check: mode={result['mode']} profile={result['profile']} findings={len(findings)}") + for item in findings: + suffix = f" ({item['path']})" if item.get("path") else "" + print(f"{item['code']}: {item['message']}{suffix}") + if structural: + return 2 + return 1 if findings and adoption.get("mode") == "enforce" else 0 + + +if __name__ == "__main__": + raise SystemExit(main())