@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.
- package/README.md +144 -4
- package/dist/adapters/agents/agent-integration.js +26 -3
- package/dist/cli/commands/guard.d.ts +2 -0
- package/dist/cli/commands/guard.js +77 -11
- package/dist/cli/index.js +2 -0
- package/dist/core/guard.d.ts +28 -1
- package/dist/core/guard.js +37 -0
- package/dist/core/history/runs.d.ts +64 -1
- package/dist/core/history/runs.js +109 -0
- package/dist/core/output/attestation.d.ts +17 -0
- package/dist/core/output/attestation.js +22 -0
- package/dist/core/policy/schemas.d.ts +47 -0
- package/dist/core/policy/schemas.js +67 -0
- package/dist/core/verification/github-actions.d.ts +25 -0
- package/dist/core/verification/github-actions.js +397 -0
- package/dist/core/verification/github-context.d.ts +8 -0
- package/dist/core/verification/github-context.js +41 -0
- package/dist/core/verification/verify.d.ts +23 -4
- package/dist/core/verification/verify.js +601 -47
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp/prompts.js +7 -4
- package/dist/mcp/tools/guard.js +9 -3
- package/docs/extensions.md +79 -0
- package/docs/guard-agent-integration.md +51 -0
- package/docs/guard-ci.yml +202 -0
- package/docs/guard-fixtures.md +127 -0
- package/docs/guard-trusted-pr-attestation.yml +213 -0
- package/docs/guard.md +1125 -0
- package/docs/integrations/README.md +38 -0
- package/docs/integrations/claude-code.md +92 -0
- package/docs/integrations/codex.md +58 -0
- package/docs/integrations/cursor.md +116 -0
- package/docs/integrations/gemini-cli.md +47 -0
- package/docs/integrations/generic.md +41 -0
- package/docs/integrations/github-copilot.md +72 -0
- package/docs/policy-mutations.md +75 -0
- package/docs/releasing.md +58 -0
- package/docs/verify-guard-attestation.mjs +166 -0
- 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.
|