@codapult/guard 0.10.0 → 0.11.0

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 (40) hide show
  1. package/README.md +144 -4
  2. package/dist/adapters/agents/agent-integration.js +26 -3
  3. package/dist/cli/commands/guard.d.ts +2 -0
  4. package/dist/cli/commands/guard.js +77 -11
  5. package/dist/cli/index.js +2 -0
  6. package/dist/core/guard.d.ts +28 -1
  7. package/dist/core/guard.js +37 -0
  8. package/dist/core/history/runs.d.ts +64 -1
  9. package/dist/core/history/runs.js +109 -0
  10. package/dist/core/output/attestation.d.ts +17 -0
  11. package/dist/core/output/attestation.js +22 -0
  12. package/dist/core/policy/schemas.d.ts +47 -0
  13. package/dist/core/policy/schemas.js +67 -0
  14. package/dist/core/verification/github-actions.d.ts +25 -0
  15. package/dist/core/verification/github-actions.js +397 -0
  16. package/dist/core/verification/github-context.d.ts +8 -0
  17. package/dist/core/verification/github-context.js +41 -0
  18. package/dist/core/verification/verify.d.ts +23 -4
  19. package/dist/core/verification/verify.js +601 -47
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +1 -0
  22. package/dist/mcp/prompts.js +7 -4
  23. package/dist/mcp/tools/guard.js +9 -3
  24. package/docs/extensions.md +79 -0
  25. package/docs/guard-agent-integration.md +51 -0
  26. package/docs/guard-ci.yml +202 -0
  27. package/docs/guard-fixtures.md +127 -0
  28. package/docs/guard-trusted-pr-attestation.yml +213 -0
  29. package/docs/guard.md +1125 -0
  30. package/docs/integrations/README.md +38 -0
  31. package/docs/integrations/claude-code.md +92 -0
  32. package/docs/integrations/codex.md +58 -0
  33. package/docs/integrations/cursor.md +116 -0
  34. package/docs/integrations/gemini-cli.md +47 -0
  35. package/docs/integrations/generic.md +41 -0
  36. package/docs/integrations/github-copilot.md +72 -0
  37. package/docs/policy-mutations.md +75 -0
  38. package/docs/releasing.md +58 -0
  39. package/docs/verify-guard-attestation.mjs +166 -0
  40. package/package.json +4 -2
@@ -0,0 +1,38 @@
1
+ # AI Coding Agent Integrations
2
+
3
+ Connect Codapult Guard architecture guardrails to Claude Code, Codex, Cursor, Gemini CLI, GitHub
4
+ Copilot, or another MCP-compatible AI coding agent. These guides cover project instructions, MCP
5
+ setup, and independent verification in CI.
6
+
7
+ The examples use a project-local pnpm installation. Guard requires Node.js `>=20.19.0`; with
8
+ npm, replace `pnpm add -D @codapult/guard` with `npm install --save-dev @codapult/guard` and
9
+ replace `pnpm exec codapult-guard` with `npx --no-install codapult-guard`.
10
+
11
+ These kits keep Guard platform-neutral while giving each host a concrete setup. Each page names
12
+ the host's instruction file, MCP configuration file or command, verification command, and the
13
+ available completion hook surface.
14
+
15
+ - [Codex](codex.md)
16
+ - [Cursor](cursor.md)
17
+ - [Claude Code](claude-code.md)
18
+ - [GitHub Copilot](github-copilot.md)
19
+ - [Gemini CLI](gemini-cli.md)
20
+ - [Generic shell/CI](generic.md)
21
+
22
+ | Host | Project instruction | MCP setup | Local completion automation |
23
+ | ------------------ | ---------------------------------- | ------------------------------------------------------ | ------------------------------------- |
24
+ | Codex CLI | `AGENTS.md` | `codex mcp add` / `~/.codex/config.toml` | Instruction-driven; CI gate |
25
+ | Cursor Agent | `.cursor/rules/codapult-guard.mdc` | `.cursor/mcp.json` | `.cursor/hooks.json` `stop` follow-up |
26
+ | Claude Code | `CLAUDE.md` | project `.mcp.json` | `.claude/settings.json` `Stop` hook |
27
+ | Gemini CLI | `GEMINI.md` | `.gemini/settings.json` | Instruction-driven; CI gate |
28
+ | Copilot Chat / CLI | `.github/copilot-instructions.md` | `.vscode/mcp.json`, `.mcp.json`, or `.github/mcp.json` | Surface-specific; CI gate |
29
+
30
+ All integrations use the same MCP tools and completion-gate contract. None of them grants the
31
+ agent permission to edit files; that remains the user's host configuration. Guard is discoverable
32
+ in the [official MCP Registry](https://registry.modelcontextprotocol.io/?q=io.github.codapult%2Fguard)
33
+ as `io.github.codapult/guard`; Registry publication does not create one universal installer, so
34
+ follow the host-specific setup on the relevant page.
35
+
36
+ The kits are documentation-level adapters, not runtime dependencies. Install the managed
37
+ instruction for a supported host with `codapult-guard install-agent <target>`, configure the MCP
38
+ server in that host, and keep `codapult-guard verify --json` in CI as the independent gate.
@@ -0,0 +1,92 @@
1
+ # Claude Code integration
2
+
3
+ This page targets Claude Code with a project-scoped MCP server and project instructions.
4
+
5
+ ## 1. Install Guard
6
+
7
+ Guard is published in the official MCP Registry as `io.github.codapult/guard`. Search for that identifier in a Registry-aware client and import the npm/stdio entry when supported. Claude Code also accepts the same server directly, so Registry discovery is optional.
8
+
9
+ Install the package:
10
+
11
+ ```bash
12
+ pnpm add -D @codapult/guard
13
+ ```
14
+
15
+ If this project has not been initialized yet, establish its Guard state:
16
+
17
+ ```bash
18
+ pnpm exec codapult-guard init
19
+ ```
20
+
21
+ Register a project-scoped stdio server:
22
+
23
+ ```bash
24
+ claude mcp add --transport stdio codapult-guard --scope project \
25
+ -- pnpm exec codapult-guard mcp-server
26
+ ```
27
+
28
+ This writes the project server to `.mcp.json`. Verify it:
29
+
30
+ ```bash
31
+ claude mcp get codapult-guard
32
+ claude mcp list
33
+ ```
34
+
35
+ Approve the project server when Claude Code asks for workspace trust.
36
+
37
+ ## 2. Add project instructions
38
+
39
+ Run:
40
+
41
+ ```bash
42
+ pnpm exec codapult-guard install-agent claude
43
+ ```
44
+
45
+ This creates or updates the managed block in `CLAUDE.md`. Claude Code reads that file as project instruction context; the MCP registration remains in `.mcp.json`.
46
+
47
+ ## 3. Optional completion hook
48
+
49
+ Claude Code project hooks live in `.claude/settings.json`. To verify at the end of every agent
50
+ turn, create `.claude/hooks/guard-stop.sh`:
51
+
52
+ ```bash
53
+ #!/usr/bin/env bash
54
+ set +e
55
+ cat >/dev/null
56
+ pnpm exec codapult-guard verify --json >&2
57
+ status=$?
58
+ if [ "$status" -ne 0 ]; then
59
+ exit 2
60
+ fi
61
+ exit 0
62
+ ```
63
+
64
+ Make it executable (`chmod +x .claude/hooks/guard-stop.sh`) and add a `Stop` command hook:
65
+
66
+ ```json
67
+ {
68
+ "hooks": {
69
+ "Stop": [
70
+ {
71
+ "hooks": [
72
+ {
73
+ "type": "command",
74
+ "command": ".claude/hooks/guard-stop.sh"
75
+ }
76
+ ]
77
+ }
78
+ ]
79
+ }
80
+ }
81
+ ```
82
+
83
+ Keep CI verification as the independent merge gate. Use `/hooks` to inspect the active hook and `/mcp` to inspect the MCP connection.
84
+
85
+ ## 4. Agent loop
86
+
87
+ The agent should call `codapult_guard_next_action`, then `codapult_guard_context`,
88
+ `codapult_guard_review`, and `codapult_guard_verify`. It fixes reported errors and repeats until
89
+ the configured completion gate passes. Guard returns evidence and deterministic results; Claude
90
+ Code owns the repair loop.
91
+
92
+ References: [Claude Code MCP](https://code.claude.com/docs/en/mcp), [Claude Code hooks](https://code.claude.com/docs/en/hooks).
@@ -0,0 +1,58 @@
1
+ # Codex integration
2
+
3
+ This page targets Codex CLI and Codex-compatible IDE integrations that read `AGENTS.md` and support the Codex MCP configuration.
4
+
5
+ ## 1. Install Guard
6
+
7
+ Guard is published in the official MCP Registry as `io.github.codapult/guard`. Use the Registry entry when a Codex host offers Registry import. Otherwise configure the npm/stdio server directly; the Registry is discovery and does not replace the host's MCP configuration.
8
+
9
+ Install the package:
10
+
11
+ ```bash
12
+ pnpm add -D @codapult/guard
13
+ ```
14
+
15
+ If this project has not been initialized yet, establish its Guard state:
16
+
17
+ ```bash
18
+ pnpm exec codapult-guard init
19
+ ```
20
+
21
+ Register the server with Codex CLI:
22
+
23
+ ```bash
24
+ codex mcp add codapult-guard -- pnpm exec codapult-guard mcp-server
25
+ codex mcp list
26
+ ```
27
+
28
+ The equivalent user configuration is an entry in `~/.codex/config.toml`:
29
+
30
+ ```toml
31
+ [mcp_servers.codapult-guard]
32
+ command = "pnpm"
33
+ args = ["exec", "codapult-guard", "mcp-server"]
34
+ ```
35
+
36
+ Codex stores this MCP registration in its user configuration. Keep the repository's `AGENTS.md`
37
+ and CI gate in version control; configure the MCP server separately on each developer machine.
38
+
39
+ ## 2. Add repository instructions
40
+
41
+ Run:
42
+
43
+ ```bash
44
+ pnpm exec codapult-guard install-agent codex
45
+ ```
46
+
47
+ This creates or updates the managed Guard block in `AGENTS.md`. Codex loads `AGENTS.md` as repository instruction context, while the MCP server remains a separate tool configuration.
48
+
49
+ ## 3. Completion workflow
50
+
51
+ Codex should call `codapult_guard_next_action`, then `codapult_guard_context`,
52
+ `codapult_guard_review`, and `codapult_guard_verify` after a coding task. It repairs errors and
53
+ repeats verification according to `.codapult/guard/agent.json`. Run the same
54
+ `codapult-guard verify --json` command in CI.
55
+
56
+ Guard does not invoke Codex or an LLM. Codex owns task execution and repairs; Guard supplies project facts, policy evidence, and the deterministic gate.
57
+
58
+ References: [Codex MCP configuration example](https://developers.openai.com/learn/docs-mcp), [Codex repository instructions](https://developers.openai.com/cookbook/examples/codex/code_modernization).
@@ -0,0 +1,116 @@
1
+ # Cursor integration
2
+
3
+ This page targets Cursor Agent in a trusted local workspace. Cursor supports project MCP
4
+ configuration in `.cursor/mcp.json`, project rules in `.cursor/rules/`, and project hooks in
5
+ `.cursor/hooks.json`.
6
+
7
+ ## 1. Install Guard
8
+
9
+ Guard is listed in the official MCP Registry as `io.github.codapult/guard`. In a client that can
10
+ import Registry entries, search for that identifier and select the npm/stdio server. Cursor's
11
+ native MCP directory and one-click install are separate from the official MCP Registry; if Guard
12
+ is not offered there, use the project configuration below.
13
+
14
+ Install the package in the repository:
15
+
16
+ ```bash
17
+ pnpm add -D @codapult/guard
18
+ ```
19
+
20
+ If this project has not been initialized yet, establish its Guard state before enabling the hook:
21
+
22
+ ```bash
23
+ pnpm exec codapult-guard init
24
+ ```
25
+
26
+ Create `.cursor/mcp.json`:
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "codapult-guard": {
32
+ "type": "stdio",
33
+ "command": "pnpm",
34
+ "args": ["exec", "codapult-guard", "mcp-server"],
35
+ "cwd": "${workspaceFolder}"
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Reload Cursor and verify that `codapult-guard` appears in the MCP tools list. Keep the project
42
+ configuration in version control only if the team agrees to trust and run the local server for
43
+ every contributor.
44
+
45
+ ## 2. Add the Guard rule
46
+
47
+ Run this from the project root:
48
+
49
+ ```bash
50
+ pnpm exec codapult-guard install-agent cursor
51
+ ```
52
+
53
+ This creates or updates `.cursor/rules/codapult-guard.mdc`. The generated rule tells Agent when
54
+ to call the MCP tools; CI remains the independent enforcement point.
55
+
56
+ ## 3. Run the completion gate automatically
57
+
58
+ Cursor project hooks are command-based processes that receive JSON on stdin. Add
59
+ `.cursor/hooks/guard-stop.mjs`:
60
+
61
+ ```js
62
+ import { spawnSync } from 'node:child_process';
63
+ import { readFileSync } from 'node:fs';
64
+
65
+ const input = JSON.parse(readFileSync(0, 'utf8') || '{}');
66
+ const root = process.env.CURSOR_PROJECT_DIR ?? process.cwd();
67
+
68
+ if (input.status !== 'completed') process.exit(0);
69
+
70
+ const result = spawnSync('pnpm', ['exec', 'codapult-guard', 'verify', '--json'], {
71
+ cwd: root,
72
+ encoding: 'utf8',
73
+ stdio: ['ignore', 'pipe', 'pipe'],
74
+ });
75
+
76
+ if (result.status !== 0) {
77
+ const detail = (result.stdout || result.stderr || '').trim().slice(-2_000);
78
+ process.stdout.write(
79
+ JSON.stringify({
80
+ followup_message: `Guard verification failed. Fix the reported findings, then run Guard again.${detail ? `\n\n${detail}` : ''}`,
81
+ }),
82
+ );
83
+ }
84
+ ```
85
+
86
+ Register it in `.cursor/hooks.json`:
87
+
88
+ ```json
89
+ {
90
+ "version": 1,
91
+ "hooks": {
92
+ "stop": [
93
+ {
94
+ "command": "node .cursor/hooks/guard-stop.mjs",
95
+ "loop_limit": 3,
96
+ "failClosed": true
97
+ }
98
+ ]
99
+ }
100
+ }
101
+ ```
102
+
103
+ `stop` runs when Cursor Agent is completing a task. A failed verification returns Cursor's
104
+ `followup_message`, which starts another agent iteration; `loop_limit` bounds that loop. The hook
105
+ is optional for local work; CI is the merge gate. Do not treat a hook's presence as a replacement
106
+ for CI enforcement.
107
+
108
+ ## 4. Normal agent loop
109
+
110
+ Ask Cursor Agent to call `codapult_guard_next_action`, then
111
+ `codapult_guard_context`, `codapult_guard_review`, and `codapult_guard_verify`. If verification
112
+ reports an error, the agent repairs the change and repeats verification. The deterministic Guard
113
+ gate does not call an LLM.
114
+
115
+ References: [Cursor MCP](https://cursor.com/docs/mcp), [Cursor hooks](https://cursor.com/docs/hooks),
116
+ [Cursor rules](https://cursor.com/docs/context/rules).
@@ -0,0 +1,47 @@
1
+ # Gemini CLI integration
2
+
3
+ This page targets Gemini CLI with project settings and the project `GEMINI.md` context file.
4
+
5
+ ## 1. Install Guard
6
+
7
+ Guard is published in the official MCP Registry as `io.github.codapult/guard`. Search for that identifier in a Registry-aware client and import it when the client supports Registry entries. Gemini CLI can also add the npm/stdio server directly, independently of Registry UI.
8
+
9
+ Install the package:
10
+
11
+ ```bash
12
+ pnpm add -D @codapult/guard
13
+ ```
14
+
15
+ If this project has not been initialized yet, establish its Guard state:
16
+
17
+ ```bash
18
+ pnpm exec codapult-guard init
19
+ ```
20
+
21
+ Add it to the project scope:
22
+
23
+ ```bash
24
+ gemini mcp add --scope project codapult-guard pnpm exec codapult-guard mcp-server
25
+ ```
26
+
27
+ The project configuration is `.gemini/settings.json`. Verify the connection inside Gemini CLI with `/mcp list` or `/mcp desc`.
28
+
29
+ ## 2. Add the project instruction
30
+
31
+ Run:
32
+
33
+ ```bash
34
+ pnpm exec codapult-guard install-agent gemini
35
+ ```
36
+
37
+ This creates or updates the managed block in `GEMINI.md`, which Gemini CLI loads as hierarchical project context.
38
+
39
+ ## 3. Completion behavior
40
+
41
+ Gemini CLI's project settings provide the MCP connection and `GEMINI.md` provides the workflow
42
+ instruction. At the end of a coding task, have the agent call `codapult_guard_next_action`, then
43
+ `codapult_guard_context`, `codapult_guard_review`, and `codapult_guard_verify`. Keep
44
+ `codapult-guard verify --json` in CI; the local agent session is not the final authority for
45
+ merging changes.
46
+
47
+ References: [Gemini CLI MCP](https://geminicli.com/docs/tools/mcp-server/), [Gemini CLI configuration](https://geminicli.com/docs/reference/configuration/), [GEMINI.md context](https://geminicli.com/docs/cli/gemini-md/).
@@ -0,0 +1,41 @@
1
+ # Generic AI agent integration
2
+
3
+ Install Guard and initialize the project before adding an agent instruction:
4
+
5
+ ```bash
6
+ pnpm add -D @codapult/guard
7
+ pnpm exec codapult-guard init
8
+ ```
9
+
10
+ Guard is discoverable in the [official MCP Registry](https://registry.modelcontextprotocol.io/?q=io.github.codapult%2Fguard)
11
+ as `io.github.codapult/guard`. If the host does not import Registry entries, register the local
12
+ stdio command `pnpm exec codapult-guard mcp-server` in its MCP configuration.
13
+
14
+ Add the following to the agent's project instructions:
15
+
16
+ ```text
17
+ After completing a coding task, call codapult_guard_next_action and follow its bounded next step.
18
+ Normally call codapult_guard_context, then codapult_guard_review with the requirement and changed
19
+ diff, then codapult_guard_verify. If the result contains an error, fix it and repeat up to
20
+ completionGate.maxIterations. Do not hide warnings or claim completion without reporting
21
+ unresolved requirements.
22
+ ```
23
+
24
+ The CLI equivalent is:
25
+
26
+ ```bash
27
+ codapult-guard review --requirement docs/acceptance.md
28
+ codapult-guard verify --json
29
+ ```
30
+
31
+ For pull-request CI, verify against the protected base policy. Fetch the base commit before this
32
+ step and pass its SHA (the bundled `docs/guard-ci.yml` does this automatically):
33
+
34
+ ```bash
35
+ codapult-guard verify --policy-base "$BASE_SHA" --json
36
+ ```
37
+
38
+ Use `--fail-on-policy-change` in a separate policy-review gate when changing Guard policy requires
39
+ an explicit protected approval.
40
+
41
+ Use the host's post-task hook to invoke the sequence. Run the same command independently in CI.
@@ -0,0 +1,72 @@
1
+ # GitHub Copilot integration
2
+
3
+ GitHub Copilot has two relevant local surfaces. Use the VS Code instructions for Copilot Chat in Agent mode, or the Copilot CLI instructions for the terminal agent. They do not share the same MCP configuration file.
4
+
5
+ ## Copilot Chat in VS Code
6
+
7
+ Guard is published in the official MCP Registry as `io.github.codapult/guard`. Registry import is client-dependent; if it is not available in your VS Code MCP gallery, configure the server manually.
8
+
9
+ Install the package:
10
+
11
+ ```bash
12
+ pnpm add -D @codapult/guard
13
+ ```
14
+
15
+ If this project has not been initialized yet, establish its Guard state:
16
+
17
+ ```bash
18
+ pnpm exec codapult-guard init
19
+ ```
20
+
21
+ Create `.vscode/mcp.json`:
22
+
23
+ ```json
24
+ {
25
+ "servers": {
26
+ "codapult-guard": {
27
+ "type": "stdio",
28
+ "command": "pnpm",
29
+ "args": ["exec", "codapult-guard", "mcp-server"]
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ Start the server from `.vscode/mcp.json`, open Copilot Chat in Agent mode, and enable Guard in the tools picker. Then run:
36
+
37
+ ```bash
38
+ pnpm exec codapult-guard install-agent copilot
39
+ ```
40
+
41
+ This creates or updates `.github/copilot-instructions.md` with the completion workflow.
42
+
43
+ ## Copilot CLI
44
+
45
+ Copilot CLI uses `~/.copilot/mcp-config.json` for persistent user servers and `.mcp.json` or `.github/mcp.json` for trusted repository/workspace servers. Add Guard to the repository:
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "codapult-guard": {
51
+ "command": "pnpm",
52
+ "args": ["exec", "codapult-guard", "mcp-server"]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ Place the file at `.mcp.json` or `.github/mcp.json`, then verify it with `copilot mcp list`. For one session, use `copilot --additional-mcp-config=@.mcp.json`.
59
+
60
+ The instruction file for Copilot CLI can be generated with the same command; it updates `.github/copilot-instructions.md`:
61
+
62
+ ```bash
63
+ pnpm exec codapult-guard install-agent copilot
64
+ ```
65
+
66
+ Keep CI as the independent final gate. Copilot's editor and CLI surfaces have different lifecycle
67
+ hooks, so this integration relies on project instructions plus `verify` rather than claiming one
68
+ universal completion hook. The instruction tells the agent to call
69
+ `codapult_guard_next_action`, `codapult_guard_context`, `codapult_guard_review`, and
70
+ `codapult_guard_verify`.
71
+
72
+ References: [Copilot MCP in VS Code](https://docs.github.com/en/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp), [Copilot CLI](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference).
@@ -0,0 +1,75 @@
1
+ # Policy mutation control
2
+
3
+ Guard reports and validates policy mutations, but it cannot prove that a process invoking the CLI
4
+ is a human. A shell-capable coding agent can technically execute the same CLI command as a
5
+ developer. Human or independent approval must therefore be enforced by the host or CI system.
6
+
7
+ Inspect the machine-readable mutation contract:
8
+
9
+ ```bash
10
+ codapult-guard policy mutations --json
11
+ ```
12
+
13
+ The contract identifies operations that change policy, including:
14
+
15
+ - `init.force`;
16
+ - `rules.approve` and `contracts.approve|reject`;
17
+ - `baseline.accept|remove`;
18
+ - `waiver.add|renew|remove`;
19
+ - direct edits to `.codapult/guard/*`.
20
+
21
+ Every listed operation has `externalApprovalRequired: true`. This is a declaration for the host;
22
+ it is not an identity or signature mechanism.
23
+
24
+ ## Agent shell policy
25
+
26
+ Use the host's command approval or `PreToolUse` mechanism to reject policy mutations while the
27
+ agent session is running. The exact hook format is host-specific, but the denied command set
28
+ should include:
29
+
30
+ ```text
31
+ codapult-guard init --force
32
+ codapult-guard baseline accept
33
+ codapult-guard baseline remove
34
+ codapult-guard waiver add
35
+ codapult-guard waiver renew
36
+ codapult-guard waiver remove
37
+ codapult-guard rules approve
38
+ codapult-guard contracts approve
39
+ codapult-guard contracts reject
40
+ ```
41
+
42
+ Allow read-only commands such as `context`, `check`, `review`, `verify`, `audit`, `impact`, and
43
+ `policy mutations`. If a policy change is needed, the agent may explain or propose it, but the
44
+ mutation should be performed through a human-approved branch or protected CI job.
45
+
46
+ ## CI policy
47
+
48
+ Keep `.codapult/guard/*` under CODEOWNERS and protected-branch review. For pull requests, verify
49
+ against the base policy rather than the policy changed in the pull request:
50
+
51
+ ```bash
52
+ codapult-guard verify \
53
+ --policy-base "$BASE_SHA" \
54
+ --fail-on-policy-change \
55
+ --json
56
+ ```
57
+
58
+ The bundled [`guard-ci.yml`](guard-ci.yml) shows the complete workflow. A policy-changing pull
59
+ request should require the configured architecture owner; the Guard result alone does not grant
60
+ that approval.
61
+
62
+ ## Adversarial test
63
+
64
+ The relevant failure scenario is:
65
+
66
+ ```text
67
+ agent changes source
68
+ → Guard reports a violation
69
+ → agent attempts waiver/baseline/policy mutation
70
+ → host blocks the mutation
71
+ → agent must repair source or request human review
72
+ ```
73
+
74
+ Guard tests the policy checks and emits the mutation contract. The host or CI layer tests whether
75
+ the attempted command is actually blocked.
@@ -0,0 +1,58 @@
1
+ # Releasing Guard
2
+
3
+ Guard is distributed through npm as `@codapult/guard`. A GitHub Release is used as the reviewed
4
+ release record and triggers publication to npm and, after npm succeeds, the official MCP Registry.
5
+ The GitHub Release is not a second package distribution channel.
6
+
7
+ ## Recommended flow
8
+
9
+ 1. Run `pnpm release` from a clean, up-to-date checkout. `release-it` updates the version and
10
+ changelog, creates the matching tag, pushes it, and creates the GitHub Release.
11
+ 2. The `release.yml` workflow checks out the tag, verifies that the tag and package version match,
12
+ runs the complete release check, validates `server.json`, and publishes the exact package to npm
13
+ with provenance.
14
+ 3. The workflow waits until the exact npm version is visible and contains the expected `mcpName`.
15
+ 4. After npm publication succeeds, the workflow authenticates with GitHub OIDC and publishes the
16
+ matching MCP server metadata to the official Registry.
17
+
18
+ If a release is prepared manually, update `CHANGELOG.md` and `package.json`, run
19
+ `pnpm mcp:sync`, run `pnpm release:check`, push a matching tag such as `v0.1.0`, and publish the
20
+ GitHub Release for that tag.
21
+
22
+ The workflow uses npm trusted publishing through GitHub Actions OIDC. Configure the npm package's
23
+ trusted publisher for this repository and workflow before the first publication. No npm token is
24
+ stored in the repository.
25
+
26
+ ## MCP Registry metadata
27
+
28
+ `server.json` describes the stdio MCP server exposed by the npm package. Its `name` is
29
+ `io.github.codapult/guard` and must match the `mcpName` field in `package.json`; the Registry uses
30
+ that marker to verify npm package ownership. The `mcp:validate` script checks the name, repository,
31
+ package identifier, transport, and versions locally. `release-it` runs `mcp:sync` after bumping the
32
+ package version so the release commit contains matching metadata.
33
+
34
+ The Registry hosts server metadata, not npm artifacts. Therefore Registry publication is deliberately
35
+ a post-npm release step and is not part of ordinary local development. The release job uses GitHub OIDC; configure the workflow's `id-token: write`
36
+ permission and protect the release environment before enabling production publication. The release
37
+ workflow pins and verifies the Linux x64 `mcp-publisher` binary; update its version and checksum
38
+ deliberately when upgrading the publisher.
39
+
40
+ If npm publication succeeds but Registry publication fails because npm propagation is delayed,
41
+ use the workflow's **Run workflow** action with the failed release tag after the package becomes
42
+ visible. The npm step verifies the existing version and continues only when its `mcpName` matches;
43
+ it does not attempt to overwrite an npm version.
44
+
45
+ ## Why use both GitHub Release and npm?
46
+
47
+ They serve different purposes:
48
+
49
+ - npm is where users install `@codapult/guard`;
50
+ - the GitHub Release records the source tag, changelog, release notes, and maintainer decision;
51
+ - the published GitHub Release provides one explicit, auditable trigger for npm publication.
52
+
53
+ A GitHub Release is not technically required to publish to npm. A tag-triggered workflow could
54
+ publish directly, but the reviewed-release trigger makes accidental publication less likely and
55
+ keeps source, changelog, and npm version aligned.
56
+
57
+ Do not publish by running `npm publish` manually unless the release workflow is intentionally being
58
+ replaced. Never reuse an already-published version.