actions-warden 0.2.0 → 0.3.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/AGENTS.md +189 -0
- package/CONTRIBUTING.md +109 -0
- package/README.md +272 -224
- package/RELEASING.md +338 -0
- package/SECURITY.md +25 -3
- package/docs/AI-AGENTS.md +458 -0
- package/docs/CLI.md +421 -0
- package/docs/CONFIGURATION.md +340 -0
- package/docs/DEVELOPMENT.md +350 -0
- package/docs/GITHUB-ACTION.md +281 -0
- package/docs/JAVASCRIPT-API.md +355 -0
- package/docs/OUTPUTS.md +409 -0
- package/docs/README.md +27 -0
- package/examples/org-scan.yml +42 -0
- package/examples/upgrade-pr.yml +57 -0
- package/llms.txt +38 -0
- package/package.json +32 -10
- package/skills/actions-warden/SKILL.md +140 -38
- package/src/action.js +317 -0
- package/src/cli.js +267 -22
- package/src/commands/audit.js +189 -36
- package/src/commands/org-scan.js +549 -0
- package/src/commands/pin.js +59 -56
- package/src/commands/report.js +122 -10
- package/src/commands/upgrade.js +102 -62
- package/src/commands/verify.js +193 -0
- package/src/index.js +21 -4
- package/src/lib/action-status.js +27 -0
- package/src/lib/agent-mode.js +175 -0
- package/src/lib/annotations.js +250 -0
- package/src/lib/baseline.js +103 -0
- package/src/lib/cache.js +47 -10
- package/src/lib/concurrency.js +27 -0
- package/src/lib/config.js +185 -0
- package/src/lib/execution.js +71 -0
- package/src/lib/formatter.js +127 -8
- package/src/lib/github-org.js +374 -0
- package/src/lib/identity.js +62 -0
- package/src/lib/ignore.js +7 -6
- package/src/lib/org-checkpoint.js +378 -0
- package/src/lib/org-progress.js +60 -0
- package/src/lib/parser.js +326 -52
- package/src/lib/patcher.js +199 -0
- package/src/lib/paths.js +35 -12
- package/src/lib/redact.js +65 -4
- package/src/lib/resolver.js +225 -43
- package/src/lib/targets.js +28 -0
- package/src/lib/triggers.js +12 -0
- package/src/lib/writer.js +45 -8
- package/src/rules/excessive-permissions.js +24 -33
- package/src/rules/index.js +19 -1
- package/src/rules/pull-request-target-checkout.js +149 -18
- package/src/rules/reusable-workflow-secrets.js +32 -0
- package/src/rules/script-injection.js +77 -12
- package/src/rules/secrets-in-env.js +101 -18
- package/src/rules/unpinned-action.js +3 -2
- package/src/rules/unpinned-container-image.js +39 -0
- package/src/rules/unpinned-docker-action.js +30 -0
- package/src/rules/untrusted-self-hosted-runner.js +109 -0
- package/src/rules/workflow-run-artifact-execution.js +122 -0
- package/src/rules/workflow-structure.js +396 -0
- package/src/version.js +3 -0
package/docs/CLI.md
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
This reference describes the public `actions-warden` command-line interface.
|
|
4
|
+
The command's own help is authoritative for the installed version:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
actions-warden --help
|
|
8
|
+
actions-warden audit --help
|
|
9
|
+
actions-warden org-scan --help
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Install and authenticate
|
|
13
|
+
|
|
14
|
+
Node.js 20 or newer is required.
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm install --global actions-warden
|
|
18
|
+
actions-warden --version
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For reproducible one-off automation, invoke an exact package version:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npx --yes actions-warden@0.3.0 audit
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Network-backed commands resolve credentials in this order:
|
|
28
|
+
|
|
29
|
+
1. `--token <token>`
|
|
30
|
+
2. `GITHUB_TOKEN`
|
|
31
|
+
3. `GH_TOKEN`
|
|
32
|
+
4. anonymous GitHub API access
|
|
33
|
+
|
|
34
|
+
Prefer an environment variable over `--token` because command-line arguments
|
|
35
|
+
may be visible to other local processes. Give the token only the repository
|
|
36
|
+
metadata and contents read access needed for the requested scope.
|
|
37
|
+
|
|
38
|
+
## Target and output options
|
|
39
|
+
|
|
40
|
+
The repository commands (`audit`, `pin`, `verify`, `upgrade`, and `report`)
|
|
41
|
+
share these options:
|
|
42
|
+
|
|
43
|
+
| option | default | behavior |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `-w, --workflow <pattern...>` | discovery | One or more files, directories, or globs |
|
|
46
|
+
| `--cwd <dir>` | current directory | Repository and path-safety root |
|
|
47
|
+
| `--token <token>` | environment | GitHub API credential for network-backed work |
|
|
48
|
+
| `--format <format>` | `toon` | `toon`, `json`, `text`, or `sarif` |
|
|
49
|
+
| `--output <destination>` | `stdout` | `stdout` or `file` |
|
|
50
|
+
| `--output-path <path>` | none | Required with `--output=file`; resolved inside `--cwd` |
|
|
51
|
+
|
|
52
|
+
Without `--workflow`, actions-warden discovers:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
.github/workflows/*.yml
|
|
56
|
+
.github/workflows/*.yaml
|
|
57
|
+
action.yml
|
|
58
|
+
action.yaml
|
|
59
|
+
**/action.yml
|
|
60
|
+
**/action.yaml
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Paths and directories may be absolute or relative to `--cwd`. Quote globs so
|
|
64
|
+
actions-warden, not the shell, expands them. An explicit file, directory, or
|
|
65
|
+
glob that resolves to no workflow files is an error.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
actions-warden audit -w .github/workflows/release.yml
|
|
69
|
+
actions-warden audit -w '.github/workflows/*.yml'
|
|
70
|
+
actions-warden audit -w .github/workflows .github/actions
|
|
71
|
+
actions-warden audit --cwd ../service
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Output files are created atomically and must remain within the real working
|
|
75
|
+
directory after symlinks are resolved:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
actions-warden audit \
|
|
79
|
+
--format=sarif \
|
|
80
|
+
--output=file \
|
|
81
|
+
--output-path=reports/actions-warden.sarif
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## `audit`
|
|
85
|
+
|
|
86
|
+
Scan local workflows and composite actions without making network calls or
|
|
87
|
+
changing files.
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
actions-warden audit \
|
|
91
|
+
[--severity=low|medium|high|critical] \
|
|
92
|
+
[--explain] \
|
|
93
|
+
[--config=<path> | --ignore-config] \
|
|
94
|
+
[--baseline=<path>]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The default includes every severity. `--severity` keeps findings at or above
|
|
98
|
+
the selected threshold; parse errors always remain visible. `--explain` adds a
|
|
99
|
+
plain-language remediation field.
|
|
100
|
+
|
|
101
|
+
Create a reviewed baseline from all current findings:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
actions-warden audit \
|
|
105
|
+
--create-baseline=.actions-warden-baseline.json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`--create-baseline` cannot be combined with `--baseline`. Parser failures are
|
|
109
|
+
never written into the baseline. See [configuration and baselines](./CONFIGURATION.md).
|
|
110
|
+
|
|
111
|
+
Exit code `0` means no unsuppressed findings; `1` means findings were reported;
|
|
112
|
+
`2` means the scan could not be invoked safely or correctly.
|
|
113
|
+
|
|
114
|
+
## `pin`
|
|
115
|
+
|
|
116
|
+
Resolve mutable external action and reusable-workflow refs to full commit SHAs.
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
actions-warden pin [--dry-run] [--write] [--fix=<id>]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Dry-run is the default. A planned rewrite looks like:
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # actions-warden-ref: v5
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The metadata preserves the readable version for `verify` and `upgrade`.
|
|
129
|
+
Existing comments and scalar quoting are preserved. The target commit is
|
|
130
|
+
verified as belonging to the referenced repository before a plan is accepted.
|
|
131
|
+
|
|
132
|
+
Review the dry-run output, then either apply the whole plan:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
actions-warden pin --write
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
or one exact stable ID:
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
actions-warden pin --fix=18b82e86d7c14fe2 --write
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`--write` and `--dry-run` together are rejected.
|
|
145
|
+
|
|
146
|
+
## `verify`
|
|
147
|
+
|
|
148
|
+
Verify action and reusable-workflow pins against GitHub.
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
actions-warden verify
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
For every external reference, verification checks that:
|
|
155
|
+
|
|
156
|
+
1. the ref is a full 40-character commit SHA;
|
|
157
|
+
2. the commit belongs to the referenced repository; and
|
|
158
|
+
3. `actions-warden-ref` metadata, when present, resolves to that SHA.
|
|
159
|
+
|
|
160
|
+
A valid SHA without version metadata produces a warning. An unpinned,
|
|
161
|
+
unverifiable, or metadata-mismatched reference is an error and returns status
|
|
162
|
+
`FAIL`.
|
|
163
|
+
|
|
164
|
+
## `upgrade`
|
|
165
|
+
|
|
166
|
+
Plan or apply newer action versions while preserving immutable SHA pins.
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
actions-warden upgrade \
|
|
170
|
+
[--mode=major|minor|patch] \
|
|
171
|
+
[--min-age=<days>] \
|
|
172
|
+
[--dry-run] [--write] [--fix=<id>]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Defaults are `--mode=minor --min-age=7` and dry-run. Tag discovery is paginated;
|
|
176
|
+
prereleases and downgrades are excluded. A candidate tag must be older than the
|
|
177
|
+
cooldown. The age comes from GitHub release publication data when available,
|
|
178
|
+
then from locally recorded first-seen evidence for the exact tag-to-SHA mapping.
|
|
179
|
+
Missing evidence fails closed.
|
|
180
|
+
|
|
181
|
+
SHA-pinned references need `actions-warden-ref` metadata to establish the
|
|
182
|
+
current semantic version. Legacy plain-semver comments remain readable.
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
# Review every eligible minor update
|
|
186
|
+
actions-warden upgrade --mode=minor --min-age=14 --format=json
|
|
187
|
+
|
|
188
|
+
# Apply one reviewed change
|
|
189
|
+
actions-warden upgrade --fix=<ID> --write
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## `report`
|
|
193
|
+
|
|
194
|
+
Produce one non-writing view of audit findings, pin plans, and upgrade plans.
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
actions-warden report \
|
|
198
|
+
[--severity=low|medium|high|critical] \
|
|
199
|
+
[--explain] \
|
|
200
|
+
[--mode=major|minor|patch] \
|
|
201
|
+
[--min-age=<days>] \
|
|
202
|
+
[--offline] \
|
|
203
|
+
[--config=<path> | --ignore-config] \
|
|
204
|
+
[--baseline=<path>]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The audit determines the target set; pin and upgrade use exactly that same
|
|
208
|
+
scope. A location with an upgrade is not duplicated as a pin proposal.
|
|
209
|
+
`--offline` skips both network-backed planning phases and returns only the
|
|
210
|
+
local audit.
|
|
211
|
+
|
|
212
|
+
Use report for review, issue generation, or an AI planning step. It never
|
|
213
|
+
accepts `--write`.
|
|
214
|
+
|
|
215
|
+
## `org-scan`
|
|
216
|
+
|
|
217
|
+
Audit workflow security across repositories visible to a GitHub token.
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
actions-warden org-scan <organization> \
|
|
221
|
+
[--repository <pattern...>] \
|
|
222
|
+
[--visibility=all|public|private|internal] \
|
|
223
|
+
[--include-archived] [--include-disabled] [--include-forks] \
|
|
224
|
+
[--max-repos=<count>] [--concurrency=<1-16>] \
|
|
225
|
+
[--severity=low|medium|high|critical] [--explain] \
|
|
226
|
+
[--config=<path> | --ignore-config] [--baseline=<path>] \
|
|
227
|
+
[--checkpoint=<path> | --resume=<path>] \
|
|
228
|
+
[--progress=auto|always|never] \
|
|
229
|
+
[--agent-mode | --no-agent-mode] \
|
|
230
|
+
[--format=toon|json|text|sarif] \
|
|
231
|
+
[--output=stdout|file] [--output-path=<path>]
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Defaults:
|
|
235
|
+
|
|
236
|
+
- visibility: `all`;
|
|
237
|
+
- archived, disabled, and forked repositories: excluded;
|
|
238
|
+
- repository concurrency: `4`;
|
|
239
|
+
- repository count: every eligible repository;
|
|
240
|
+
- audit severity: every level;
|
|
241
|
+
- progress: `auto` (stderr only when attached to an interactive terminal);
|
|
242
|
+
- agent mode: disabled unless explicitly selected or enabled by the
|
|
243
|
+
environment.
|
|
244
|
+
|
|
245
|
+
Repository patterns match either `name` or `owner/name`, case-insensitively.
|
|
246
|
+
An explicit pattern set that matches no eligible repository is an error.
|
|
247
|
+
Selection is stable before `--max-repos` is applied.
|
|
248
|
+
|
|
249
|
+
```sh
|
|
250
|
+
actions-warden org-scan my-org \
|
|
251
|
+
--repository 'service-*' 'my-org/platform-*' \
|
|
252
|
+
--visibility=private \
|
|
253
|
+
--severity=high \
|
|
254
|
+
--format=json \
|
|
255
|
+
--output=file \
|
|
256
|
+
--output-path=reports/org.json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The result includes discovered, eligible, selected, scanned, skipped, failed,
|
|
260
|
+
and workflow-bearing repository counts. Per-repository operational errors make
|
|
261
|
+
the overall status `FAIL`; they do not abort reporting for repositories that
|
|
262
|
+
can still be scanned.
|
|
263
|
+
|
|
264
|
+
### Agent mode
|
|
265
|
+
|
|
266
|
+
There is no reliable cross-agent process or environment signal. Agent callers
|
|
267
|
+
opt in explicitly:
|
|
268
|
+
|
|
269
|
+
```sh
|
|
270
|
+
actions-warden org-scan my-org --agent-mode
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
An integration can instead set the mode once:
|
|
274
|
+
|
|
275
|
+
```sh
|
|
276
|
+
export ACTIONS_WARDEN_MODE=agent
|
|
277
|
+
actions-warden org-scan my-org
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
When the corresponding options were not explicitly supplied, agent mode sets:
|
|
281
|
+
|
|
282
|
+
- `--format=json`;
|
|
283
|
+
- `--output=file` with a guarded scope-keyed report path;
|
|
284
|
+
- `--progress=never`;
|
|
285
|
+
- a guarded scope-keyed checkpoint path, creating it when absent and resuming
|
|
286
|
+
it when present.
|
|
287
|
+
|
|
288
|
+
The artifact key includes the organization, repository filters, inclusion
|
|
289
|
+
flags, repository limit, severity, explanation setting, normalized policy,
|
|
290
|
+
baseline contents, package version, and rule catalog. A scope or security
|
|
291
|
+
control change therefore selects a different checkpoint rather than
|
|
292
|
+
overwriting incompatible state. Generated paths have these shapes:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
.actions-warden-agent.<scope-key>.report.json
|
|
296
|
+
.actions-warden-agent.<scope-key>.checkpoint.json
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
An explicitly selected report format changes the report extension. Generated
|
|
300
|
+
files are mode `0600` when first created and may reveal private security
|
|
301
|
+
posture; protect them and ignore `.actions-warden-agent.*` in consuming
|
|
302
|
+
repositories when appropriate.
|
|
303
|
+
|
|
304
|
+
After writing the full report, stdout contains only a bounded JSON receipt:
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
{
|
|
308
|
+
schemaVersion: '1.0',
|
|
309
|
+
kind: 'actions-warden-agent-receipt',
|
|
310
|
+
command: 'org-scan',
|
|
311
|
+
organization: string,
|
|
312
|
+
status: 'OK' | 'FAIL',
|
|
313
|
+
summary: object,
|
|
314
|
+
report: { path: string, format: 'toon' | 'json' | 'text' | 'sarif' },
|
|
315
|
+
checkpoint: { path: string, resumed: boolean }
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The process still exits `0` for `OK`, `1` for a completed `FAIL`, and `2` for
|
|
320
|
+
an invocation error. Explicit `--format`, `--output`, `--output-path`,
|
|
321
|
+
`--progress`, `--checkpoint`, and `--resume` choices override agent defaults.
|
|
322
|
+
With explicit `--output=stdout`, stdout is the complete selected report and no
|
|
323
|
+
receipt is added. Use `--no-agent-mode` to override an inherited environment
|
|
324
|
+
marker. `ACTIONS_WARDEN_MODE` must be exactly `agent` when set.
|
|
325
|
+
|
|
326
|
+
### Progress and resume
|
|
327
|
+
|
|
328
|
+
Progress is independent of the report format and is written only to stderr.
|
|
329
|
+
This keeps stdout valid JSON, SARIF, TOON, or text. Select `always` for CI or a
|
|
330
|
+
redirected terminal log, and `never` when a caller wants no progress channel:
|
|
331
|
+
|
|
332
|
+
```sh
|
|
333
|
+
actions-warden org-scan my-org --format=json --progress=always > report.json
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Create an atomic checkpoint after each completed repository:
|
|
337
|
+
|
|
338
|
+
```sh
|
|
339
|
+
actions-warden org-scan my-org \
|
|
340
|
+
--severity=high \
|
|
341
|
+
--checkpoint=.actions-warden-org-checkpoint.json \
|
|
342
|
+
--format=json \
|
|
343
|
+
--output=file \
|
|
344
|
+
--output-path=reports/org.json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Resume with the same organization, filters, inclusion flags, repository limit,
|
|
348
|
+
severity, explanation setting, configuration, baseline, tool version, and rule
|
|
349
|
+
catalog:
|
|
350
|
+
|
|
351
|
+
```sh
|
|
352
|
+
actions-warden org-scan my-org \
|
|
353
|
+
--severity=high \
|
|
354
|
+
--resume=.actions-warden-org-checkpoint.json \
|
|
355
|
+
--format=json \
|
|
356
|
+
--output=file \
|
|
357
|
+
--output-path=reports/org.json
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The token, concurrency, output format, progress mode, and report destination do
|
|
361
|
+
not affect checkpoint compatibility. A resumed scan always lists repositories
|
|
362
|
+
again and fetches a fresh default-branch tree for each selected repository.
|
|
363
|
+
An error-free result is reused only when repository identity, default branch,
|
|
364
|
+
and tree SHA still match. Changed repositories and any checkpointed result with
|
|
365
|
+
an operational error are scanned again.
|
|
366
|
+
|
|
367
|
+
`--checkpoint` starts a new checkpoint and replaces an existing file at that
|
|
368
|
+
path. `--resume` requires a valid existing checkpoint and updates it. The
|
|
369
|
+
checkpoint and report paths must differ, remain inside `--cwd`, and have an
|
|
370
|
+
existing parent directory. A checkpoint cannot replace the active config or
|
|
371
|
+
baseline. Checkpoints contain redacted report evidence and revision metadata,
|
|
372
|
+
not the token or raw YAML, but can still reveal private repository names,
|
|
373
|
+
paths, findings, and security posture; protect and retain them accordingly.
|
|
374
|
+
Checkpoint reads and writes are capped at 256 MiB.
|
|
375
|
+
|
|
376
|
+
The scanner reads the default-branch Git tree and YAML blobs in memory. It
|
|
377
|
+
never clones, checks out, or executes remote content. It fails closed on
|
|
378
|
+
truncated trees and enforces these bounds per repository:
|
|
379
|
+
|
|
380
|
+
- 1,000 workflow and composite-action files;
|
|
381
|
+
- 2 MiB per YAML file;
|
|
382
|
+
- 32 MiB of YAML source in total.
|
|
383
|
+
|
|
384
|
+
Remote organization listings, trees, and blobs bypass the general disk cache so
|
|
385
|
+
a report uses a fresh branch view and raw private workflow content is not
|
|
386
|
+
persisted. An explicitly requested checkpoint stores only redacted report data
|
|
387
|
+
and validated revision metadata.
|
|
388
|
+
See [the scheduled Action example](../examples/org-scan.yml).
|
|
389
|
+
|
|
390
|
+
## `rules`
|
|
391
|
+
|
|
392
|
+
Print the rule catalog compiled into the installed version:
|
|
393
|
+
|
|
394
|
+
```sh
|
|
395
|
+
actions-warden rules
|
|
396
|
+
actions-warden rules --format=json
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
This command has no repository or network dependency.
|
|
400
|
+
|
|
401
|
+
## Cache and network behavior
|
|
402
|
+
|
|
403
|
+
Local `pin`, `verify`, `upgrade`, and online `report` work caches successful
|
|
404
|
+
GitHub API responses for one hour. The cache root is selected in this order:
|
|
405
|
+
|
|
406
|
+
1. `ACTIONS_WARDEN_CACHE_DIR`
|
|
407
|
+
2. `$XDG_CACHE_HOME/actions-warden`
|
|
408
|
+
3. `~/.cache/actions-warden`
|
|
409
|
+
|
|
410
|
+
Cache keys include a hash of the authentication identity, so authenticated
|
|
411
|
+
responses are not shared with anonymous or different-token calls. Requests
|
|
412
|
+
have timeouts, bounded retries, in-flight deduplication, and ETag revalidation
|
|
413
|
+
where available. Resolver failures are returned as errors; the CLI does not
|
|
414
|
+
silently substitute an unverified value.
|
|
415
|
+
|
|
416
|
+
## Related guides
|
|
417
|
+
|
|
418
|
+
- [Configuration](./CONFIGURATION.md)
|
|
419
|
+
- [Output contracts](./OUTPUTS.md)
|
|
420
|
+
- [GitHub Action](./GITHUB-ACTION.md)
|
|
421
|
+
- [AI and coding agents](./AI-AGENTS.md)
|