@ilbie/capybara-code-darwin-x64 0.1.0-alpha.3
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/LICENSE +201 -0
- package/bin/capy +0 -0
- package/libexec/cbc-runtime +0 -0
- package/manifest.json +100 -0
- package/package.json +31 -0
- package/share/capybara/model-registry.json +109 -0
- package/share/capybara/notices/THIRD-PARTY.md +145 -0
- package/share/capybara/notices/sbom.json +1123 -0
- package/share/capybara/schemas/config/config.schema.json +1249 -0
- package/share/capybara/schemas/events/event.schema.json +461 -0
- package/share/capybara/schemas/protocol/handshake.schema.json +207 -0
- package/share/capybara/schemas/protocol/rpc.schema.json +711 -0
- package/share/capybara/schemas/tools/tool.schema.json +270 -0
- package/share/capybara/skills/code-review/SKILL.md +35 -0
- package/share/capybara/skills/commit-message/SKILL.md +43 -0
- package/share/capybara/skills/dependency-audit-lite/SKILL.md +39 -0
- package/share/capybara/skills/repo-onboarding/SKILL.md +46 -0
- package/share/capybara/skills/test-triage/SKILL.md +43 -0
- package/share/capybara/skills/write-agents-md/SKILL.md +39 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
{
|
|
2
|
+
"x-dialect": "json-schema-draft-2020-12",
|
|
3
|
+
"$id": "cbc:tools/tool",
|
|
4
|
+
"title": "Capybara Code tool contract",
|
|
5
|
+
"description": "PRD 12.2, 12.4, 13.2. Describes a tool definition, the common result envelope, and the P0 native catalog. 12.4's schema rules are asserted structurally here: a tool's own parameter schema must be strict, must reject unknown keys, and a mutation tool must carry either an expected hash or an explicit create policy.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"riskClass": {
|
|
9
|
+
"description": "13.2. R4 through R6 may never receive a session-wide or project-wide allow rule.",
|
|
10
|
+
"type": "string",
|
|
11
|
+
"enum": [
|
|
12
|
+
"R0",
|
|
13
|
+
"R1",
|
|
14
|
+
"R2",
|
|
15
|
+
"R3",
|
|
16
|
+
"R4",
|
|
17
|
+
"R5",
|
|
18
|
+
"R6"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"toolSource": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"enum": [
|
|
24
|
+
"native",
|
|
25
|
+
"skill",
|
|
26
|
+
"mcp"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"toolDefinition": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"required": [
|
|
33
|
+
"id",
|
|
34
|
+
"title",
|
|
35
|
+
"description",
|
|
36
|
+
"source",
|
|
37
|
+
"defaultRisk",
|
|
38
|
+
"maxRisk",
|
|
39
|
+
"parameters",
|
|
40
|
+
"alwaysActive",
|
|
41
|
+
"mutates",
|
|
42
|
+
"network",
|
|
43
|
+
"keywords"
|
|
44
|
+
],
|
|
45
|
+
"properties": {
|
|
46
|
+
"id": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$"
|
|
49
|
+
},
|
|
50
|
+
"title": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"minLength": 1
|
|
53
|
+
},
|
|
54
|
+
"description": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"minLength": 1
|
|
57
|
+
},
|
|
58
|
+
"source": {
|
|
59
|
+
"$ref": "#/$defs/toolSource"
|
|
60
|
+
},
|
|
61
|
+
"defaultRisk": {
|
|
62
|
+
"$ref": "#/$defs/riskClass"
|
|
63
|
+
},
|
|
64
|
+
"maxRisk": {
|
|
65
|
+
"description": "The highest risk this tool can reach once arguments are considered. The classifier may promote up to this, never above it.",
|
|
66
|
+
"$ref": "#/$defs/riskClass"
|
|
67
|
+
},
|
|
68
|
+
"parameters": {
|
|
69
|
+
"$ref": "#/$defs/strictParameterSchema"
|
|
70
|
+
},
|
|
71
|
+
"alwaysActive": {
|
|
72
|
+
"description": "6.9: an always-active tool is offered without discovery and is excluded from the activation budget.",
|
|
73
|
+
"type": "boolean"
|
|
74
|
+
},
|
|
75
|
+
"mutates": {
|
|
76
|
+
"type": "boolean"
|
|
77
|
+
},
|
|
78
|
+
"network": {
|
|
79
|
+
"type": "boolean"
|
|
80
|
+
},
|
|
81
|
+
"keywords": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": {
|
|
84
|
+
"type": "string"
|
|
85
|
+
},
|
|
86
|
+
"minItems": 1
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"strictParameterSchema": {
|
|
91
|
+
"description": "12.4: a tool's argument schema is a strict object that rejects unknown keys, so a hallucinated argument fails validation instead of being silently dropped.",
|
|
92
|
+
"type": "object",
|
|
93
|
+
"required": [
|
|
94
|
+
"type",
|
|
95
|
+
"properties",
|
|
96
|
+
"required",
|
|
97
|
+
"additionalProperties"
|
|
98
|
+
],
|
|
99
|
+
"properties": {
|
|
100
|
+
"type": {
|
|
101
|
+
"const": "object"
|
|
102
|
+
},
|
|
103
|
+
"properties": {
|
|
104
|
+
"type": "object"
|
|
105
|
+
},
|
|
106
|
+
"required": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"items": {
|
|
109
|
+
"type": "string"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"additionalProperties": {
|
|
113
|
+
"const": false
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"artifactRef": {
|
|
118
|
+
"description": "18.17. A handle, never inline content. redaction records what was done to the bytes before they were stored.",
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"required": [
|
|
122
|
+
"id",
|
|
123
|
+
"digest",
|
|
124
|
+
"mediaType",
|
|
125
|
+
"bytes",
|
|
126
|
+
"redaction",
|
|
127
|
+
"retentionClass"
|
|
128
|
+
],
|
|
129
|
+
"properties": {
|
|
130
|
+
"id": {
|
|
131
|
+
"type": "string",
|
|
132
|
+
"minLength": 1
|
|
133
|
+
},
|
|
134
|
+
"digest": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"minLength": 1
|
|
137
|
+
},
|
|
138
|
+
"mediaType": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"minLength": 1
|
|
141
|
+
},
|
|
142
|
+
"bytes": {
|
|
143
|
+
"type": "integer",
|
|
144
|
+
"minimum": 0
|
|
145
|
+
},
|
|
146
|
+
"redaction": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"enum": [
|
|
149
|
+
"raw",
|
|
150
|
+
"redacted",
|
|
151
|
+
"derived"
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"displayName": {
|
|
155
|
+
"type": "string"
|
|
156
|
+
},
|
|
157
|
+
"retentionClass": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"enum": [
|
|
160
|
+
"session",
|
|
161
|
+
"temporary",
|
|
162
|
+
"pinned"
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"toolResult": {
|
|
168
|
+
"description": "12.4's common result envelope. summary is always present so an observation can be rendered even when data is absent.",
|
|
169
|
+
"type": "object",
|
|
170
|
+
"additionalProperties": false,
|
|
171
|
+
"required": [
|
|
172
|
+
"ok",
|
|
173
|
+
"summary"
|
|
174
|
+
],
|
|
175
|
+
"properties": {
|
|
176
|
+
"ok": {
|
|
177
|
+
"type": "boolean"
|
|
178
|
+
},
|
|
179
|
+
"summary": {
|
|
180
|
+
"type": "string"
|
|
181
|
+
},
|
|
182
|
+
"artifacts": {
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": {
|
|
185
|
+
"$ref": "#/$defs/artifactRef"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"warnings": {
|
|
189
|
+
"type": "array",
|
|
190
|
+
"items": {
|
|
191
|
+
"type": "string"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"error": {
|
|
195
|
+
"type": "object",
|
|
196
|
+
"additionalProperties": false,
|
|
197
|
+
"required": [
|
|
198
|
+
"code",
|
|
199
|
+
"message",
|
|
200
|
+
"retryable"
|
|
201
|
+
],
|
|
202
|
+
"properties": {
|
|
203
|
+
"code": {
|
|
204
|
+
"$ref": "cbc:protocol/rpc#/$defs/toolErrorCode"
|
|
205
|
+
},
|
|
206
|
+
"message": {
|
|
207
|
+
"type": "string"
|
|
208
|
+
},
|
|
209
|
+
"retryable": {
|
|
210
|
+
"description": "10.13: a timeout may be retried; a validation or permission failure may not, because the model must observe it and choose differently.",
|
|
211
|
+
"type": "boolean"
|
|
212
|
+
},
|
|
213
|
+
"details": {
|
|
214
|
+
"type": "object"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"data": true
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"nativeToolId": {
|
|
222
|
+
"description": "12.2's P0 catalog, in declaration order.",
|
|
223
|
+
"type": "string",
|
|
224
|
+
"enum": [
|
|
225
|
+
"fs.read",
|
|
226
|
+
"fs.read_many",
|
|
227
|
+
"fs.list",
|
|
228
|
+
"fs.glob",
|
|
229
|
+
"fs.search",
|
|
230
|
+
"fs.apply_patch",
|
|
231
|
+
"fs.write",
|
|
232
|
+
"fs.move",
|
|
233
|
+
"fs.delete",
|
|
234
|
+
"process.run",
|
|
235
|
+
"process.start",
|
|
236
|
+
"process.input",
|
|
237
|
+
"process.stop",
|
|
238
|
+
"shell.run",
|
|
239
|
+
"artifact.read",
|
|
240
|
+
"git.status",
|
|
241
|
+
"git.diff",
|
|
242
|
+
"git.log",
|
|
243
|
+
"git.show",
|
|
244
|
+
"git.checkpoint",
|
|
245
|
+
"user.ask",
|
|
246
|
+
"task.search",
|
|
247
|
+
"task.spawn",
|
|
248
|
+
"task.status",
|
|
249
|
+
"task.cancel",
|
|
250
|
+
"skill.search",
|
|
251
|
+
"skill.load",
|
|
252
|
+
"mcp.search",
|
|
253
|
+
"mcp.call",
|
|
254
|
+
"mcp.read_resource",
|
|
255
|
+
"todo.write",
|
|
256
|
+
"tool.discover",
|
|
257
|
+
"repo.investigate",
|
|
258
|
+
"verification.run_many"
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
"oneOf": [
|
|
263
|
+
{
|
|
264
|
+
"$ref": "#/$defs/toolDefinition"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"$ref": "#/$defs/toolResult"
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review
|
|
3
|
+
description: Review the current diff for correctness, regressions, security, and test gaps.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- git.diff
|
|
7
|
+
- git.status
|
|
8
|
+
- fs.read
|
|
9
|
+
- fs.search
|
|
10
|
+
risk: read
|
|
11
|
+
tags:
|
|
12
|
+
- review
|
|
13
|
+
- diff
|
|
14
|
+
- quality
|
|
15
|
+
- security
|
|
16
|
+
user_invocable: true
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Code review
|
|
20
|
+
|
|
21
|
+
Read the change before judging it. `git.diff` gives you the change; `fs.read` gives you the surrounding code that tells you whether the change is correct in context.
|
|
22
|
+
|
|
23
|
+
## What to look for, in order
|
|
24
|
+
|
|
25
|
+
1. **Correctness.** Does the code do what the diff claims? Check boundary conditions, empty inputs, and error paths — not just the happy path the author was thinking about.
|
|
26
|
+
2. **Regressions.** What else calls this? Use `fs.search` on the changed symbol names. A signature change with one updated call site is a finding.
|
|
27
|
+
3. **Security.** Untrusted input reaching a query, a path, a command, or a deserializer. Credentials or tokens in new code. Authorization checks that moved or disappeared.
|
|
28
|
+
4. **Test gaps.** Does a new behaviour have a test? Does a fixed bug have a regression test? Name the specific case that is missing.
|
|
29
|
+
5. **Data and migrations.** Irreversible operations, lock duration, and rollback.
|
|
30
|
+
|
|
31
|
+
## What to report
|
|
32
|
+
|
|
33
|
+
For each finding: severity, file and line, what goes wrong, and the smallest fix.
|
|
34
|
+
|
|
35
|
+
Do not report formatting, naming preferences, or a restatement of what the code does. If the change is sound, say so plainly and stop — a review that invents findings to look thorough costs the reader more than it gives them.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commit-message
|
|
3
|
+
description: Write a commit message for the current change. Does not commit.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- git.diff
|
|
7
|
+
- git.status
|
|
8
|
+
- fs.read
|
|
9
|
+
risk: read
|
|
10
|
+
tags:
|
|
11
|
+
- git
|
|
12
|
+
- commit
|
|
13
|
+
- message
|
|
14
|
+
user_invocable: true
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Commit message
|
|
18
|
+
|
|
19
|
+
Produce a message for the staged or working-tree change. **Do not commit.** There is no commit tool, and running `git commit` through a shell would need its own approval (§12.2).
|
|
20
|
+
|
|
21
|
+
## Read the change first
|
|
22
|
+
|
|
23
|
+
`git.status` for scope, `git.diff` for content. Write about what the change does, not what the request asked for — those differ more often than you would expect.
|
|
24
|
+
|
|
25
|
+
## Shape
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
<subject: imperative, under 72 characters, no trailing period>
|
|
29
|
+
|
|
30
|
+
<body: why this change, and anything a reader could not infer from the diff>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Match the repository's existing convention. If the log uses Conventional Commits, use it. Check `git.log` rather than guessing.
|
|
34
|
+
|
|
35
|
+
## Subject line
|
|
36
|
+
|
|
37
|
+
Imperative mood: "Fix the parser", not "Fixed" or "Fixes". Name the thing that changed. "Update code" says nothing.
|
|
38
|
+
|
|
39
|
+
## Body
|
|
40
|
+
|
|
41
|
+
Explain the reasoning the diff cannot: why this approach, what was rejected, what a reviewer should look at. Skip the body entirely for a genuinely trivial change rather than padding it.
|
|
42
|
+
|
|
43
|
+
Return the message as text for the user to use. Say explicitly that nothing was committed.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dependency-audit-lite
|
|
3
|
+
description: Review declared dependencies for risk without installing anything.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- fs.read
|
|
7
|
+
- fs.glob
|
|
8
|
+
- fs.search
|
|
9
|
+
risk: read
|
|
10
|
+
tags:
|
|
11
|
+
- dependencies
|
|
12
|
+
- supply-chain
|
|
13
|
+
- audit
|
|
14
|
+
- security
|
|
15
|
+
user_invocable: true
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Dependency audit (lite)
|
|
19
|
+
|
|
20
|
+
A read-only review of what the project declares. Install nothing and run no package-manager command — that would be a network side effect requiring its own approval (§13.2 R3).
|
|
21
|
+
|
|
22
|
+
## Read the manifests and the lockfile
|
|
23
|
+
|
|
24
|
+
Manifests state intent; the lockfile states what is actually resolved. Both matter, and they can disagree.
|
|
25
|
+
|
|
26
|
+
## What to flag
|
|
27
|
+
|
|
28
|
+
- **Unpinned ranges** on anything security-relevant. A caret range on an auth or crypto library is a supply-chain decision made by whoever publishes next.
|
|
29
|
+
- **Typosquat shapes.** A name one character from a popular package, or an unexpected scope.
|
|
30
|
+
- **Abandoned packages.** No release in years, sitting on a critical path.
|
|
31
|
+
- **Duplicated functionality.** Three HTTP clients is three attack surfaces.
|
|
32
|
+
- **Install scripts.** A `postinstall` runs arbitrary code at install time (§T9).
|
|
33
|
+
- **Direct dependencies that should be dev-only**, shipping to production for no reason.
|
|
34
|
+
|
|
35
|
+
## What to report
|
|
36
|
+
|
|
37
|
+
Group by severity. For each item: the package, the version or range, why it is a risk, and the concrete change — pin, replace, or remove.
|
|
38
|
+
|
|
39
|
+
State clearly that this is a static review of declared dependencies, not a vulnerability scan against an advisory database.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: repo-onboarding
|
|
3
|
+
description: Explain an unfamiliar repository's structure, entry points, and how to run it.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- fs.read
|
|
7
|
+
- fs.list
|
|
8
|
+
- fs.glob
|
|
9
|
+
- fs.search
|
|
10
|
+
- git.log
|
|
11
|
+
risk: read
|
|
12
|
+
tags:
|
|
13
|
+
- onboarding
|
|
14
|
+
- explain
|
|
15
|
+
- structure
|
|
16
|
+
- architecture
|
|
17
|
+
user_invocable: true
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Repository onboarding
|
|
21
|
+
|
|
22
|
+
Answer the questions a new contributor actually has, in this order.
|
|
23
|
+
|
|
24
|
+
## 1. What is this?
|
|
25
|
+
|
|
26
|
+
Read the README and the root manifest. State the purpose in one or two sentences.
|
|
27
|
+
|
|
28
|
+
## 2. How is it laid out?
|
|
29
|
+
|
|
30
|
+
Name the top-level directories and what each holds. Skip vendored and generated trees. Do not list every file.
|
|
31
|
+
|
|
32
|
+
## 3. Where does execution start?
|
|
33
|
+
|
|
34
|
+
Find the real entry points: `bin` and `scripts` in a manifest, a `main`, a server bootstrap. Trace one representative request or command end to end so the reader has a spine to hang everything else on.
|
|
35
|
+
|
|
36
|
+
## 4. How do I build, run, and test it?
|
|
37
|
+
|
|
38
|
+
Quote the exact commands from the manifest. If they need a toolchain or a service, say so.
|
|
39
|
+
|
|
40
|
+
## 5. What should I know before changing anything?
|
|
41
|
+
|
|
42
|
+
Conventions from `AGENTS.md` or a contributing guide. Areas that look load-bearing. Recent churn from `git.log`, which tells you where the work is happening.
|
|
43
|
+
|
|
44
|
+
## Be honest about gaps
|
|
45
|
+
|
|
46
|
+
If you could not determine how to run the tests, say that. A confident wrong build command costs more than an admitted gap.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-triage
|
|
3
|
+
description: Run the tests closest to a change and explain each failure.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- fs.read
|
|
7
|
+
- fs.search
|
|
8
|
+
- fs.glob
|
|
9
|
+
- process.run
|
|
10
|
+
- git.diff
|
|
11
|
+
risk: process
|
|
12
|
+
tags:
|
|
13
|
+
- test
|
|
14
|
+
- failure
|
|
15
|
+
- triage
|
|
16
|
+
- debug
|
|
17
|
+
user_invocable: true
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Test triage
|
|
21
|
+
|
|
22
|
+
## Select before you run
|
|
23
|
+
|
|
24
|
+
Find the narrowest command that covers the change. Look for the project's own runner in its manifest — `package.json` scripts, `Cargo.toml`, `pyproject.toml`, `Makefile` — rather than assuming one.
|
|
25
|
+
|
|
26
|
+
Prefer a single file or filtered suite over the whole matrix. A full run that takes ten minutes to tell you the same thing is a worse answer.
|
|
27
|
+
|
|
28
|
+
## Read the failure, not the log
|
|
29
|
+
|
|
30
|
+
For each failing test, report:
|
|
31
|
+
|
|
32
|
+
- the test name and its file
|
|
33
|
+
- what was expected and what actually happened
|
|
34
|
+
- the specific line that raised
|
|
35
|
+
- whether the cause is the change under test or the environment
|
|
36
|
+
|
|
37
|
+
## Distinguish the two failure kinds
|
|
38
|
+
|
|
39
|
+
A **genuine failure** means the code is wrong. An **environment failure** — a missing binary, an absent dependency, no network — means the suite could not answer the question. Say which one you are looking at. "The suite could not run because X" is a useful result; a pass you did not observe is not.
|
|
40
|
+
|
|
41
|
+
## Before concluding
|
|
42
|
+
|
|
43
|
+
If a test fails, confirm it also fails without the change when that is cheap to check. A test that was already red is not evidence about this change.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: write-agents-md
|
|
3
|
+
description: Draft or update an AGENTS.md capturing this project's real conventions.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tools:
|
|
6
|
+
- fs.read
|
|
7
|
+
- fs.list
|
|
8
|
+
- fs.glob
|
|
9
|
+
- fs.search
|
|
10
|
+
- fs.write
|
|
11
|
+
risk: write
|
|
12
|
+
tags:
|
|
13
|
+
- agents
|
|
14
|
+
- conventions
|
|
15
|
+
- documentation
|
|
16
|
+
user_invocable: true
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Writing AGENTS.md
|
|
20
|
+
|
|
21
|
+
`AGENTS.md` tells an agent how to work in *this* repository. It shapes behaviour; it grants no permission (§18.2).
|
|
22
|
+
|
|
23
|
+
## Derive it from the code, not from habit
|
|
24
|
+
|
|
25
|
+
Before writing a rule, confirm the repository follows it. Read the manifest for the real scripts. Read a few source files for the real style. A rule the code contradicts is worse than no rule, because it will be followed.
|
|
26
|
+
|
|
27
|
+
## Cover what an agent actually needs
|
|
28
|
+
|
|
29
|
+
- **Build, test, lint.** The exact commands, copied from the manifest.
|
|
30
|
+
- **Layout.** Where source, tests, and generated output live.
|
|
31
|
+
- **Conventions the code demonstrates.** Formatting, error handling, logging, naming.
|
|
32
|
+
- **Things not to touch.** Generated files, vendored trees, anything with its own pipeline.
|
|
33
|
+
- **Testing expectations.** Where a test goes and what shape it takes.
|
|
34
|
+
|
|
35
|
+
## Keep it short
|
|
36
|
+
|
|
37
|
+
Aim for something a reader finishes. Every line competes for the same context budget as the code. Prefer one accurate command over a paragraph describing it.
|
|
38
|
+
|
|
39
|
+
Write to `AGENTS.md` at the repository root unless a nearer scope is clearly meant.
|