create-agdf 0.13.7 → 0.14.1

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 (79) hide show
  1. package/README.md +31 -7
  2. package/generated/plugins/agdf/.claude-plugin/plugin.json +1 -1
  3. package/generated/plugins/agdf/.codex-plugin/plugin.json +2 -4
  4. package/generated/plugins/agdf/hooks/copilot-hooks.json +15 -0
  5. package/generated/plugins/agdf/hooks/hooks.json +3 -2
  6. package/generated/plugins/agdf/meta/agdf-plugin.definition.json +44 -2
  7. package/generated/plugins/agdf/plugin.json +22 -0
  8. package/generated/plugins/agdf/runtime/agdf-local.js +1 -1
  9. package/generated/plugins/agdf/runtime/agdf-session-check.js +97 -0
  10. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +44 -2
  11. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/command-registry.js +10 -2
  12. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/parse-args.js +17 -0
  13. package/generated/plugins/agdf/runtime/create-agdf/lib/runtime-check-consent/contract.js +73 -0
  14. package/generated/plugins/agdf/runtime/create-agdf/package.json +1 -1
  15. package/generated/plugins/agdf/runtime/runtime-manifest.json +2 -2
  16. package/generated/plugins/agdf/scripts/check-runtime-integrity.mjs +50 -5
  17. package/generated/plugins/agdf/submission/openai/availability.md +1 -1
  18. package/generated/plugins/agdf/submission/openai/capability-matrix.json +8 -1
  19. package/generated/plugins/agdf/submission/openai/release-notes.md +12 -1
  20. package/generated/plugins/agdf/submission/openai/reviewer-cases.json +23 -1
  21. package/generated/submissions/openai/agdf/.codex-plugin/plugin.json +1 -2
  22. package/generated/submissions/openai/agdf/meta/agdf-plugin.definition.json +44 -2
  23. package/generated/submissions/openai/agdf/submission/openai/availability.md +1 -1
  24. package/generated/submissions/openai/agdf/submission/openai/capability-matrix.json +8 -1
  25. package/generated/submissions/openai/agdf/submission/openai/inventory.json +9 -9
  26. package/generated/submissions/openai/agdf/submission/openai/listing.json +1 -1
  27. package/generated/submissions/openai/agdf/submission/openai/readiness.json +2 -2
  28. package/generated/submissions/openai/agdf/submission/openai/readiness.md +2 -2
  29. package/generated/submissions/openai/agdf/submission/openai/release-notes.md +12 -1
  30. package/generated/submissions/openai/agdf/submission/openai/reviewer-cases.json +23 -1
  31. package/lib/cli/application.js +291 -20
  32. package/lib/cli/command-registry.js +10 -2
  33. package/lib/cli/parse-args.js +17 -0
  34. package/lib/installers/copilot-precedence.js +34 -0
  35. package/lib/installers/copilot-settings.js +84 -0
  36. package/lib/installers/local-marketplace.js +2 -0
  37. package/lib/installers/opencode.js +21 -5
  38. package/lib/installers/plugin-installers.js +155 -4
  39. package/lib/lifecycle/operations.js +3 -0
  40. package/lib/lifecycle/presentation.js +43 -2
  41. package/lib/lifecycle/result.js +10 -0
  42. package/lib/lifecycle/status.js +7 -3
  43. package/lib/public-plugin/manifest.js +34 -2
  44. package/lib/public-plugin/validator.js +1 -1
  45. package/lib/release/version-coherence.js +1 -0
  46. package/lib/runtime-check-consent/adapters.js +42 -0
  47. package/lib/runtime-check-consent/claude-settings.js +71 -0
  48. package/lib/runtime-check-consent/contract.js +73 -0
  49. package/lib/runtime-check-consent/coordinator.js +38 -0
  50. package/lib/runtime-check-consent/service.js +181 -0
  51. package/lib/runtime-check-consent/state.js +90 -0
  52. package/lib/scaffold/plan.js +3 -89
  53. package/lib/scaffold/presentation.js +3 -22
  54. package/opencode-plugin.js +30 -15
  55. package/package.json +6 -3
  56. package/generated/.github/copilot-instructions.md +0 -16
  57. package/generated/.github/instructions/agdf-governance.instructions.md +0 -14
  58. package/generated/.github/skills/README.md +0 -20
  59. package/generated/AGENTS.md +0 -113
  60. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-brownfield-analysis/SKILL.md +0 -0
  61. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-clean-implementation-review/SKILL.md +0 -0
  62. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-code-review/SKILL.md +0 -0
  63. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-delivery-closeout/SKILL.md +0 -0
  64. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-delivery-path-search/SKILL.md +0 -0
  65. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-gate-check/SKILL.md +0 -0
  66. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-interaction-locales.json +0 -0
  67. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-qa-gate/SKILL.md +0 -0
  68. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-release-or/SKILL.md +0 -0
  69. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-runtime-contract.md +0 -0
  70. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-task-plan-review/SKILL.md +0 -0
  71. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/agdf-ux-intent-definition/SKILL.md +0 -0
  72. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/closeout.md +0 -0
  73. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/context-graph.md +0 -0
  74. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/control-scaffold.md +0 -0
  75. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/gate-transition.md +0 -0
  76. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/interaction.md +0 -0
  77. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/modes.md +0 -0
  78. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/quality.md +0 -0
  79. /package/generated/{.github/skills → plugins/agdf/copilot-skills}/contracts/task-target-resolution.md +0 -0
package/README.md CHANGED
@@ -24,11 +24,36 @@ Use a different target when Codex is not your agent surface:
24
24
  | Surface or goal | Start with | What it gives you |
25
25
  |---|---|---|
26
26
  | Claude Code | `npx --yes @agdf/cli@latest claude` | The AGDF plugin for Claude Code. |
27
+ | GitHub Copilot | `npx --yes @agdf/cli@latest copilot` | The AGDF plugin with prefixed skills and a consent-bound session hook. |
27
28
  | OpenCode, user-wide discovery | `npx --yes @agdf/cli@latest opencode` | The npm plugin and global native skills; repository governance remains opt-in. |
28
29
  | OpenCode, one repository | `npx --yes @agdf/cli@latest opencode-repo` | Durable control configuration that activates the once-installed global runtime. |
29
- | GitHub Copilot | `npx --yes @agdf/cli@latest copilot` | Repository instructions, visible skills and control templates. |
30
30
  | Durable control state in an existing setup | `npx --yes @agdf/cli@latest init` | Live `.agdf/control/` state when the repository explicitly needs it. |
31
31
 
32
+ The runtime-bearing `codex`, `claude`, `copilot` and `opencode` installers ask before enabling narrow automatic
33
+ local checks on an interactive terminal. The choices are `enable`, `manual` and `cancel`; enablement
34
+ is never preselected. Every interactive installation or update asks again. A previous choice is
35
+ shown only as intent, never as proof of effective host permission. The prompt shows the target AGDF
36
+ version and the result shows the verified installed version or transition. Matching capability
37
+ identity may preserve host-native trust, but it never
38
+ suppresses the installer choice. Non-interactive installation defaults to manual unless the exact
39
+ option is provided:
40
+
41
+ Interactive terminals accept `1` or `E` for enable, `2` or `M` for manual, `D` for technical
42
+ details and `Esc` for immediate cancel without Enter. The primary choice uses beginner-safe language,
43
+ keeps the material consent facts visible and has no preselected option. Manual mode explains that
44
+ AGDF remains available on request; invalid keys redisplay the valid choices.
45
+
46
+ ```sh
47
+ npx --yes @agdf/cli@latest claude --runtime-checks enable
48
+ npx --yes @agdf/cli@latest runtime-checks status --surface claude --json
49
+ ```
50
+
51
+ The check is argument-free, read-only and offline. Consent is content-bound, reversible and separate
52
+ from AGDF gate approval. A receipt alone never proves effective host permission. Codex native trust,
53
+ Claude deny/ask precedence and all explicit OpenCode permissions remain authoritative. The public
54
+ Skills-only OpenAI candidate has no runtime or hooks and therefore remains manual/external for this
55
+ capability.
56
+
32
57
  For prerequisites, all surface-specific flows and operational boundaries, use the authoritative [installation guide](../INSTALL.md). Do not run `init` merely to ask a fresh question: an agent can first clarify the request and ask for `Approval: UR` when durable control state is needed.
33
58
 
34
59
  ## Command overview
@@ -41,6 +66,7 @@ Installation, activation and explicit lifecycle changes:
41
66
  npx --yes @agdf/cli@latest codex
42
67
  npx --yes @agdf/cli@latest codex-repo
43
68
  npx --yes @agdf/cli@latest claude
69
+ npx --yes @agdf/cli@latest copilot
44
70
  npx --yes @agdf/cli@latest opencode
45
71
  npx --yes @agdf/cli@latest opencode-status
46
72
  npx --yes @agdf/cli@latest opencode-repo
@@ -79,11 +105,9 @@ Backward-compatible scaffold usage:
79
105
  npm create agdf@latest -- codex
80
106
  npm create agdf@latest -- codex-repo
81
107
  npm create agdf@latest -- claude
82
- npm create agdf@latest -- copilot
83
108
  npm create agdf@latest -- opencode
84
109
  npm create agdf@latest -- opencode-status
85
110
  npm create agdf@latest -- opencode-repo
86
- npm create agdf@latest -- both
87
111
  npm create agdf@latest -- init
88
112
  npm create agdf@latest -- config --language en
89
113
  npm create agdf@latest -- doctor
@@ -113,17 +137,17 @@ it does not localize the CLI lifecycle card.
113
137
  - `codex` installs the AGDF plugin globally for Codex
114
138
  - `codex-repo` writes a repository-local Codex marketplace under `.agents/plugins/` and a local AGDF plugin copy under `plugins/agdf/`
115
139
  - `claude` installs the AGDF plugin globally for Claude Code
116
- - `copilot` writes `AGENTS.md`, Copilot custom instructions under `.github/`, visible repository skills under `.github/skills/`, and AGDF control templates under `.agdf/control/`
140
+ - `copilot` registers the AGDF-owned local Marketplace and installs `agdf@agdf` through Copilot CLI; when `copilot` is not on `PATH`, it runs the pinned official `@github/copilot` CLI package through npm, then verifies AGDF in Copilot's own plugin list
117
141
  - `opencode` installs the AGDF npm plugin and ten native skills as a user-wide OpenCode surface
118
142
  - `opencode-status` reports OpenCode global config, package loadability, global native-skill completeness, installed host/plugin-SDK versions, declaration-level support for AGDF's two experimental hooks, durable repository activation, legacy compatibility and observable session signals
119
143
  - `status` reports installation, repository activation and delivery separately without mutating state
144
+ - `runtime-checks status|enable|manual` reports the requested/effective automatic-check state or gives the exact reinstall route needed to change it
120
145
  - `disable` writes a supported repository-local opt-out while retaining global capability and durable control state
121
146
  - `uninstall` previews and, only with `--confirm`, applies a selected global removal through supported native/owned operations
122
147
  - `opencode-repo` writes durable AGDF control configuration and templates under `.agdf/control/`; it does not copy a second OpenCode runtime surface
123
- - `both` writes the Codex repository-local marketplace plus the Copilot-facing repository files
124
148
  - `config` writes or updates only `.agdf/control/config.json` for an already installed plugin or an existing repository
125
149
 
126
- The `codex` and `claude` commands install from the complete plugin built into the released
150
+ The `codex`, `claude` and `copilot` commands install from the complete plugin built into the released
127
151
  `create-agdf` package. They atomically stage it under an AGDF-owned user-data marketplace, register
128
152
  that stable local path through the host CLI and verify the exposed version. Source `plugin/` therefore
129
153
  contains no generated runtime bytes and the source checkout exposes no installable root marketplace.
@@ -133,7 +157,7 @@ checkout, npm cache, PATH or registry. Rerunning either command performs the exp
133
157
  migrates only the exact known legacy AGDF GitHub marketplace; foreign same-name registrations fail
134
158
  closed and failed host operations restore the prior owned stage.
135
159
 
136
- If the target repository already has an `AGENTS.md`, `create-agdf` preserves it and writes `AGENTS.agdf.md` instead of replacing your existing instructions. Merge the AGDF fragment into your current `AGENTS.md` when you want Copilot to load both instruction sets. The generated `.github/copilot-instructions.md` keeps Copilot pointed at `AGENTS.md`, `.github/skills/` and `.agdf/control/` without duplicating the full AGDF rule model. Use `--force` only when you explicitly want to overwrite generated files.
160
+ The Copilot installer does not create, rewrite or remove repository files. Existing `AGENTS.md`, `.github/` and `.agdf/control/` content remains untouched. Use `init` separately when a repository should own surface-neutral durable AGDF control state.
137
161
 
138
162
  Use the `codex-repo` target when AGDF should be available only inside one repository instead of being installed as a personal/global Codex plugin.
139
163
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.13.7",
3
+ "version": "0.14.1",
4
4
  "description": "AI Governance & Delivery Framework (AGDF) is a governance framework for agentic work. Its first implementation provides a control layer for governed AI-assisted software delivery. It combines workflow skills, explicit gates, control templates and machine-readable repository checks to keep work aligned with approved scope and make evidence a prerequisite for consequential gate transitions. Supported workflows include brownfield analysis, task-plan review, QA decisions, durable run state and auditable delivery closeout. AGDF is an independent open-source project, not a security sandbox, compliance certification or autonomous release system.",
5
5
  "keywords": [
6
6
  "agentic",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agdf",
3
- "version": "0.13.7",
3
+ "version": "0.14.1",
4
4
  "description": "Control layer for governed AI-assisted delivery.",
5
5
  "author": {
6
6
  "name": "Arndt Gold",
@@ -30,7 +30,6 @@
30
30
  "websiteURL": "https://agdf.iself.eu",
31
31
  "privacyPolicyURL": "https://agdf.iself.eu/privacy",
32
32
  "termsOfServiceURL": "https://agdf.iself.eu/terms",
33
- "supportURL": "https://agdf.iself.eu/support",
34
33
  "composerIcon": "./assets/agdf-icon.svg",
35
34
  "logo": "./assets/agdf-logo.svg",
36
35
  "defaultPrompt": [
@@ -39,6 +38,5 @@
39
38
  "Close this delivery run with an auditable AGDF report."
40
39
  ],
41
40
  "brandColor": "#14B8A6"
42
- },
43
- "hooks": "./hooks/hooks.json"
41
+ }
44
42
  }
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "sessionStart": [
5
+ {
6
+ "type": "command",
7
+ "command": "node \"${PLUGIN_ROOT}/runtime/agdf-session-check.js\"",
8
+ "env": {
9
+ "AGDF_SURFACE": "copilot"
10
+ },
11
+ "timeoutSec": 10
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -5,8 +5,9 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "bash -lc 'hook=\"${PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-}}/hooks/session-start.sh\"; if [ -f \"$hook\" ]; then exec bash \"$hook\"; fi; hook=\"$PWD/plugins/agdf/hooks/session-start.sh\"; if [ -f \"$hook\" ]; then exec bash \"$hook\"; fi; exit 0'",
9
- "statusMessage": "Loading AGDF..."
8
+ "command": "node \"${PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/runtime/agdf-session-check.js\"",
9
+ "commandWindows": "node \"$([Environment]::GetEnvironmentVariable('PLUGIN_ROOT') + [Environment]::GetEnvironmentVariable('CLAUDE_PLUGIN_ROOT'))\\runtime\\agdf-session-check.js\"",
10
+ "statusMessage": "Checking AGDF runtime state..."
10
11
  }
11
12
  ]
12
13
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.13.7",
4
+ "version": "0.14.1",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "Arndt Gold",
7
7
  "description": "Control layer for governed AI-assisted delivery.",
@@ -50,7 +50,10 @@
50
50
  },
51
51
  "copilot": {
52
52
  "skillPrefix": "agdf-",
53
- "runtimeContractFileName": "agdf-runtime-contract.md"
53
+ "runtimeContractFileName": "agdf-runtime-contract.md",
54
+ "pluginManifest": "plugin.json",
55
+ "skills": "copilot-skills/",
56
+ "hooks": "hooks/copilot-hooks.json"
54
57
  },
55
58
  "opencode": {
56
59
  "skillPrefix": "agdf-",
@@ -68,6 +71,30 @@
68
71
  }
69
72
  }
70
73
  },
74
+ "automaticRuntimeChecks": {
75
+ "schemaVersion": 1,
76
+ "capabilityId": "automatic-runtime-checks",
77
+ "adapterContractVersion": 1,
78
+ "entrypoint": "runtime/agdf-session-check.js",
79
+ "operations": [
80
+ "resolve-local-runtime",
81
+ "inspect-control-state",
82
+ "render-bounded-orientation"
83
+ ],
84
+ "constraints": {
85
+ "arguments": "forbidden",
86
+ "filesystemWrites": "forbidden",
87
+ "network": "forbidden",
88
+ "gateAuthority": "none"
89
+ },
90
+ "surfaces": {
91
+ "codex": "native-hook-review",
92
+ "claude": "exact-command-rule",
93
+ "copilot": "plugin-hook-review",
94
+ "opencode": "plugin-internal",
95
+ "portable-skills": "manual-external-required"
96
+ }
97
+ },
71
98
  "interactions": {
72
99
  "fallback": "exact_text",
73
100
  "localeRegistry": "meta/agdf-interaction-locales.json",
@@ -120,6 +147,21 @@
120
147
  "authorizationPath": "exact_text",
121
148
  "technicalPermissionOwner": "claude_host"
122
149
  },
150
+ "copilot": {
151
+ "questionAdapter": "exact_text",
152
+ "availability": "always",
153
+ "gateSafety": "wait_for_deliberate_user_input",
154
+ "explicitOutcomes": [
155
+ "approve",
156
+ "revise",
157
+ "decline",
158
+ "cancel"
159
+ ],
160
+ "approvalValueTransport": "exact_option_value",
161
+ "waitSafety": "deliberate_no_auto_resolution",
162
+ "authorizationPath": "exact_text",
163
+ "technicalPermissionOwner": "copilot_host"
164
+ },
123
165
  "opencode": {
124
166
  "questionAdapter": "question",
125
167
  "availability": "when_permission_question_allows",
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "agdf",
3
+ "version": "0.14.1",
4
+ "description": "Control layer for governed AI-assisted delivery.",
5
+ "author": {
6
+ "name": "Arndt Gold",
7
+ "url": "https://agdf.iself.eu"
8
+ },
9
+ "homepage": "https://agdf.iself.eu",
10
+ "repository": "https://github.com/arndtgold/ai-native-governance-delivery-framework",
11
+ "license": "Apache-2.0",
12
+ "keywords": [
13
+ "agentic",
14
+ "governance",
15
+ "delivery",
16
+ "ai-native",
17
+ "brownfield"
18
+ ],
19
+ "category": "Productivity",
20
+ "skills": "copilot-skills/",
21
+ "hooks": "hooks/copilot-hooks.json"
22
+ }
@@ -12,7 +12,7 @@ const manifest = JSON.parse(readFileSync(new URL("./runtime-manifest.json", impo
12
12
  process.exitCode = runLocalValidator({
13
13
  runtimeRoot,
14
14
  pluginRoot,
15
- expectedPluginRoot: process.env.CLAUDE_PLUGIN_ROOT || undefined,
15
+ expectedPluginRoot: process.env.CLAUDE_PLUGIN_ROOT || process.env.PLUGIN_ROOT || undefined,
16
16
  expectedVersion: manifest.version,
17
17
  surface: process.env.AGDF_SURFACE || "plugin",
18
18
  }, process.argv.slice(2));
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Generated by create-agdf/scripts/sync-plugin-runtime.js; do not edit.
4
+ import { spawnSync } from "node:child_process";
5
+ import { existsSync, readFileSync } from "node:fs";
6
+ import { homedir } from "node:os";
7
+ import { join } from "node:path";
8
+ import process from "node:process";
9
+ import { fileURLToPath } from "node:url";
10
+ import { digestNormalizedPluginSource } from "./create-agdf/lib/runtime/plugin-provenance.js";
11
+ import { fixedRuntimeCheckCommand, runtimeCheckCapabilityIdentity } from "./create-agdf/lib/runtime-check-consent/contract.js";
12
+
13
+ if (process.argv.length !== 2) {
14
+ console.error("AGDF automatic runtime check accepts no arguments.");
15
+ process.exitCode = 2;
16
+ } else {
17
+ const surface = process.env.AGDF_SURFACE
18
+ || (process.env.CLAUDE_PLUGIN_ROOT ? "claude" : process.env.COPILOT_PLUGIN_DATA ? "copilot" : process.env.PLUGIN_ROOT ? "codex" : "");
19
+ const dataRoot = process.env.AGDF_DATA_DIR
20
+ || (process.platform === "darwin"
21
+ ? join(homedir(), "Library", "Application Support", "agdf")
22
+ : process.platform === "win32"
23
+ ? join(process.env.LOCALAPPDATA || process.env.APPDATA || join(homedir(), "AppData", "Local"), "agdf")
24
+ : join(process.env.XDG_DATA_HOME || join(homedir(), ".local", "share"), "agdf"));
25
+ let consentEnabled = false;
26
+ if (["codex", "claude", "copilot", "opencode"].includes(surface)) {
27
+ try {
28
+ const receipt = JSON.parse(readFileSync(join(dataRoot, "runtime-checks", `${surface}.json`), "utf8"));
29
+ consentEnabled = receipt?.schema_version === 1
30
+ && receipt?.owner === "create-agdf"
31
+ && receipt?.capability_id === "automatic-runtime-checks"
32
+ && receipt?.surface === surface
33
+ && receipt?.requested_state === "enabled";
34
+ if (consentEnabled && ["codex", "claude", "copilot"].includes(surface)) {
35
+ const pluginRoot = fileURLToPath(new URL("../", import.meta.url));
36
+ const manifest = JSON.parse(readFileSync(new URL("./runtime-manifest.json", import.meta.url), "utf8"));
37
+ const definition = JSON.parse(readFileSync(new URL("../meta/agdf-plugin.definition.json", import.meta.url), "utf8"));
38
+ const currentIdentity = runtimeCheckCapabilityIdentity({
39
+ capability: definition.automaticRuntimeChecks,
40
+ surface,
41
+ runtimeDigest: manifest.digest,
42
+ sourceDigest: digestNormalizedPluginSource(pluginRoot, manifest.version),
43
+ command: fixedRuntimeCheckCommand(surface, pluginRoot, process.platform),
44
+ });
45
+ consentEnabled = receipt.capability_identity === currentIdentity;
46
+ }
47
+ } catch {}
48
+ }
49
+ if (!consentEnabled) process.exit(0);
50
+ const validator = fileURLToPath(new URL("./agdf-local.js", import.meta.url));
51
+ const pluginRoot = fileURLToPath(new URL("../", import.meta.url));
52
+ const child = spawnSync(process.execPath, [validator, "doctor", "--all-active", "--json"], {
53
+ cwd: process.cwd(),
54
+ env: { ...process.env, AGDF_SURFACE: process.env.AGDF_SURFACE || "plugin" },
55
+ encoding: "utf8",
56
+ stdio: ["ignore", "pipe", "pipe"],
57
+ timeout: 10000,
58
+ maxBuffer: 1024 * 1024,
59
+ });
60
+ let message = "AGDF automatic runtime check: no governed control state was found; manual validation remains available.";
61
+ try {
62
+ const report = JSON.parse(child.stdout || "{}");
63
+ const status = report.status || "unknown";
64
+ const findings = report.summary?.findings ?? report.reports?.reduce((sum, item) => sum + (item.summary?.findings ?? 0), 0) ?? 0;
65
+ message = `AGDF automatic runtime check: status=${status} findings=${findings}. This is read-only technical evidence and never grants an AGDF approval.`;
66
+ } catch {}
67
+ const configPath = join(process.cwd(), ".agdf", "control", "config.json");
68
+ let configHint = "Project config: .agdf/control/config.json not found. Persist project language only when durable control is needed.";
69
+ if (existsSync(configPath)) {
70
+ try {
71
+ const config = JSON.parse(readFileSync(configPath, "utf8"));
72
+ configHint = `Project config: .agdf/control/config.json (artefacts=${config.artifact_language || "unset"}, chat=${config.chat_language || "unset"}, runtime=${config.runtime_language || "en"}).`;
73
+ } catch {
74
+ configHint = "Project config: .agdf/control/config.json is invalid. Run the surface-local doctor command manually.";
75
+ }
76
+ }
77
+ const additionalContext = [
78
+ "AGDF active.",
79
+ "",
80
+ message,
81
+ configHint,
82
+ "",
83
+ "Use the installed AGDF skills as workflow controls.",
84
+ "For a new build, change, extension, refactor, CLI, app, fix with product semantics, Structured Delivery request, unclear approval, or unclear next step, use gate-check before implementation or later-gate artefacts.",
85
+ "Do not print the full router or constitution unless the user asks for them.",
86
+ "Source of truth:",
87
+ `- ${join(pluginRoot, "meta", "agdf-agent-router.md")}`,
88
+ `- ${join(pluginRoot, "meta", "agdf-constitution.md")}`,
89
+ `- ${join(pluginRoot, "meta", "agdf-runtime-contract.md")}`,
90
+ ].join("\n");
91
+ if (surface === "copilot") {
92
+ console.log(JSON.stringify({ additionalContext }));
93
+ } else {
94
+ console.log(additionalContext);
95
+ }
96
+ process.exitCode = 0;
97
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "id": "agdf",
4
- "version": "0.13.7",
4
+ "version": "0.14.1",
5
5
  "displayName": "AI Governance & Delivery Framework",
6
6
  "developerName": "Arndt Gold",
7
7
  "description": "Control layer for governed AI-assisted delivery.",
@@ -50,7 +50,10 @@
50
50
  },
51
51
  "copilot": {
52
52
  "skillPrefix": "agdf-",
53
- "runtimeContractFileName": "agdf-runtime-contract.md"
53
+ "runtimeContractFileName": "agdf-runtime-contract.md",
54
+ "pluginManifest": "plugin.json",
55
+ "skills": "copilot-skills/",
56
+ "hooks": "hooks/copilot-hooks.json"
54
57
  },
55
58
  "opencode": {
56
59
  "skillPrefix": "agdf-",
@@ -68,6 +71,30 @@
68
71
  }
69
72
  }
70
73
  },
74
+ "automaticRuntimeChecks": {
75
+ "schemaVersion": 1,
76
+ "capabilityId": "automatic-runtime-checks",
77
+ "adapterContractVersion": 1,
78
+ "entrypoint": "runtime/agdf-session-check.js",
79
+ "operations": [
80
+ "resolve-local-runtime",
81
+ "inspect-control-state",
82
+ "render-bounded-orientation"
83
+ ],
84
+ "constraints": {
85
+ "arguments": "forbidden",
86
+ "filesystemWrites": "forbidden",
87
+ "network": "forbidden",
88
+ "gateAuthority": "none"
89
+ },
90
+ "surfaces": {
91
+ "codex": "native-hook-review",
92
+ "claude": "exact-command-rule",
93
+ "copilot": "plugin-hook-review",
94
+ "opencode": "plugin-internal",
95
+ "portable-skills": "manual-external-required"
96
+ }
97
+ },
71
98
  "interactions": {
72
99
  "fallback": "exact_text",
73
100
  "localeRegistry": "meta/agdf-interaction-locales.json",
@@ -120,6 +147,21 @@
120
147
  "authorizationPath": "exact_text",
121
148
  "technicalPermissionOwner": "claude_host"
122
149
  },
150
+ "copilot": {
151
+ "questionAdapter": "exact_text",
152
+ "availability": "always",
153
+ "gateSafety": "wait_for_deliberate_user_input",
154
+ "explicitOutcomes": [
155
+ "approve",
156
+ "revise",
157
+ "decline",
158
+ "cancel"
159
+ ],
160
+ "approvalValueTransport": "exact_option_value",
161
+ "waitSafety": "deliberate_no_auto_resolution",
162
+ "authorizationPath": "exact_text",
163
+ "technicalPermissionOwner": "copilot_host"
164
+ },
123
165
  "opencode": {
124
166
  "questionAdapter": "question",
125
167
  "availability": "when_permission_question_allows",
@@ -13,14 +13,14 @@ export const commandRegistry = Object.freeze([
13
13
  command("codex", { preferred: [""], scaffold: [""] }),
14
14
  command("codex-repo", { preferred: [""], scaffold: [""] }),
15
15
  command("claude", { preferred: [""], scaffold: [""] }),
16
- command("copilot", { preferred: [""], scaffold: [""] }),
16
+ command("copilot", { preferred: [""] }),
17
17
  command("opencode", { preferred: [""], scaffold: [""] }),
18
18
  command("opencode-status", { preferred: [""], scaffold: [""] }),
19
19
  command("status", { preferred: [" [--surface <surface>] [--run <run_id>] [--json]"] }),
20
+ command("runtime-checks", { preferred: [" <status|enable|manual> --surface <codex|claude|copilot|opencode> [--json]"] }),
20
21
  command("disable", { preferred: [" --surface <surface> [--scope repository] [--dir <path>]"] }),
21
22
  command("uninstall", { preferred: [" --surface <surface> --scope global [--confirm]"] }),
22
23
  command("opencode-repo", { preferred: [""], scaffold: [""] }),
23
- command("both", { scaffold: [""] }),
24
24
  command("init", { preferred: [""], scaffold: [""] }),
25
25
  command("config", { scaffold: [" --language de"] }),
26
26
  command("doctor", { local: [""], scaffold: [""], legacy: [" --json"] }),
@@ -65,6 +65,12 @@ export function validateCommandOptions(options) {
65
65
  throw new Error("uninstall requires explicit --scope global");
66
66
  }
67
67
  if (options.confirm && options.target !== "uninstall") throw new Error("--confirm is supported only by uninstall");
68
+ if (options.runtimeChecksDecision && !["codex", "claude", "copilot", "opencode"].includes(options.target)) {
69
+ throw new Error("--runtime-checks is supported only by codex, claude, copilot and opencode installation commands");
70
+ }
71
+ if (options.target === "runtime-checks" && !["codex", "claude", "copilot", "opencode"].includes(options.surface)) {
72
+ throw new Error("runtime-checks requires --surface codex, claude, copilot or opencode");
73
+ }
68
74
  if (options.approvalEnvelope && options.target !== "gate-check") throw new Error("--approval-envelope is supported only by gate-check");
69
75
  if (options.approvalEnvelope && (options.json || options.statusCard || options.allActive)) {
70
76
  throw new Error("--approval-envelope cannot be combined with --json, --status-card or --all-active");
@@ -120,6 +126,8 @@ Options:
120
126
  --scope <repository|global>
121
127
  Select the lifecycle mutation scope
122
128
  --confirm Apply a previously previewed global uninstall plan
129
+ --runtime-checks <enable|manual|cancel>
130
+ Make the installation-time automatic-check decision explicitly; no TTY defaults to manual
123
131
  --fixture <path>
124
132
  Use deterministic evaluator/candidate fixtures instead of a live evaluator
125
133
  --persist Persist the redacted Delivery Path Search result under the current scope
@@ -45,6 +45,8 @@ export function parseArgs(argv, dependencies = {}) {
45
45
  let allActive = false;
46
46
  let scope;
47
47
  let confirm = false;
48
+ let runtimeChecksDecision;
49
+ let runtimeChecksAction;
48
50
 
49
51
  for (let i = 0; i < args.length; i += 1) {
50
52
  const arg = args[i];
@@ -60,6 +62,14 @@ export function parseArgs(argv, dependencies = {}) {
60
62
  if (arg === "--all-active") { allActive = true; continue; }
61
63
  if (arg === "--confirm") { confirm = true; continue; }
62
64
 
65
+ if (arg === "--runtime-checks") {
66
+ const next = requiredValue(args, i, arg);
67
+ if (!["enable", "manual", "cancel"].includes(next)) throw new CliUsageError("--runtime-checks must be enable, manual or cancel.");
68
+ runtimeChecksDecision = next;
69
+ i += 1;
70
+ continue;
71
+ }
72
+
63
73
  if (arg === "--run") {
64
74
  runId = requiredValue(args, i, arg);
65
75
  i += 1;
@@ -119,6 +129,11 @@ export function parseArgs(argv, dependencies = {}) {
119
129
  target = arg;
120
130
  continue;
121
131
  }
132
+ if (!arg.startsWith("-") && target === "runtime-checks" && !runtimeChecksAction) {
133
+ if (!["status", "enable", "manual"].includes(arg)) throw new CliUsageError("runtime-checks action must be status, enable or manual.");
134
+ runtimeChecksAction = arg;
135
+ continue;
136
+ }
122
137
  throw new CliUsageError(`Unknown argument: ${arg}`);
123
138
  }
124
139
 
@@ -147,6 +162,8 @@ export function parseArgs(argv, dependencies = {}) {
147
162
  allActive,
148
163
  scope,
149
164
  confirm,
165
+ runtimeChecksDecision,
166
+ runtimeChecksAction: runtimeChecksAction ?? "status",
150
167
  generatorModel,
151
168
  maxGeneratedCandidates,
152
169
  generationTimeoutMs,
@@ -0,0 +1,73 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ const OPERATIONS = Object.freeze([
4
+ "resolve-local-runtime",
5
+ "inspect-control-state",
6
+ "render-bounded-orientation",
7
+ ]);
8
+
9
+ function stable(value) {
10
+ if (Array.isArray(value)) return value.map(stable);
11
+ if (!value || typeof value !== "object") return value;
12
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, stable(value[key])]));
13
+ }
14
+
15
+ export function validateRuntimeCheckCapability(capability) {
16
+ if (capability?.schemaVersion !== 1 || capability.capabilityId !== "automatic-runtime-checks") {
17
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: schema or capability id");
18
+ }
19
+ if (!Number.isInteger(capability.adapterContractVersion) || capability.adapterContractVersion < 1) {
20
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: adapter contract version");
21
+ }
22
+ if (capability.entrypoint !== "runtime/agdf-session-check.js") {
23
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: fixed entrypoint required");
24
+ }
25
+ if (JSON.stringify(capability.operations) !== JSON.stringify(OPERATIONS)) {
26
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: closed operation vocabulary required");
27
+ }
28
+ const constraints = capability.constraints ?? {};
29
+ if (constraints.arguments !== "forbidden" || constraints.filesystemWrites !== "forbidden"
30
+ || constraints.network !== "forbidden" || constraints.gateAuthority !== "none") {
31
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: read-only constraints required");
32
+ }
33
+ const surfaces = capability.surfaces ?? {};
34
+ if (surfaces.codex !== "native-hook-review" || surfaces.claude !== "exact-command-rule"
35
+ || surfaces.copilot !== "plugin-hook-review"
36
+ || surfaces.opencode !== "plugin-internal"
37
+ || surfaces["portable-skills"] !== "manual-external-required") {
38
+ throw new Error("AGDF_RUNTIME_CHECK_CAPABILITY_INVALID: surface contract");
39
+ }
40
+ return capability;
41
+ }
42
+
43
+ export function runtimeCheckCapabilityIdentity({ capability, surface, runtimeDigest, sourceDigest, command }) {
44
+ validateRuntimeCheckCapability(capability);
45
+ if (!["codex", "claude", "copilot", "opencode"].includes(surface)) throw new Error("AGDF_RUNTIME_CHECK_SURFACE_INVALID");
46
+ for (const [name, value] of Object.entries({ runtimeDigest, sourceDigest })) {
47
+ if (typeof value !== "string" || !/^[a-f0-9]{64}$/.test(value)) throw new Error(`AGDF_RUNTIME_CHECK_IDENTITY_INVALID: ${name}`);
48
+ }
49
+ if (typeof command !== "string" || !command.trim()) throw new Error("AGDF_RUNTIME_CHECK_IDENTITY_INVALID: command");
50
+ const payload = stable({
51
+ schema_version: 1,
52
+ surface,
53
+ capability,
54
+ runtime_digest: runtimeDigest,
55
+ source_digest: sourceDigest,
56
+ command: command.trim(),
57
+ });
58
+ return createHash("sha256").update(JSON.stringify(payload)).digest("hex");
59
+ }
60
+
61
+ export function fixedRuntimeCheckCommand(surface, pluginRoot, platform = process.platform) {
62
+ if (surface === "opencode") return "plugin:agdf:automatic-runtime-checks";
63
+ if (surface === "copilot") return 'node "${PLUGIN_ROOT}/runtime/agdf-session-check.js"';
64
+ if (surface === "codex" || surface === "claude") {
65
+ return platform === "win32"
66
+ ? "node \"$([Environment]::GetEnvironmentVariable('PLUGIN_ROOT') + [Environment]::GetEnvironmentVariable('CLAUDE_PLUGIN_ROOT'))\\runtime\\agdf-session-check.js\""
67
+ : "node \"${PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/runtime/agdf-session-check.js\"";
68
+ }
69
+ const normalizedRoot = platform === "win32" ? pluginRoot.replaceAll("/", "\\") : pluginRoot;
70
+ return `node \"${normalizedRoot}${platform === "win32" ? "\\" : "/"}runtime${platform === "win32" ? "\\" : "/"}agdf-session-check.js\"`;
71
+ }
72
+
73
+ export const runtimeCheckOperations = OPERATIONS;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agdf/local-validator-runtime",
3
- "version": "0.13.7",
3
+ "version": "0.14.1",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -2,7 +2,7 @@
2
2
  "schema_version": "1",
3
3
  "generated": true,
4
4
  "source": "create-agdf/cli",
5
- "version": "0.13.7",
5
+ "version": "0.14.1",
6
6
  "entrypoint": "create-agdf/bin/agdf-validator.js",
7
- "digest": "05afaf9ec478d50900a79cbdda8fcd7c61fa5627f4770ba093b19908fa6df91b"
7
+ "digest": "724174653ad423b30654aa64a34e1699a18cc67037172c10aa249d1d61087116"
8
8
  }