coding-agent-skills 0.2.14 → 0.2.16
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/CHANGELOG.md +42 -0
- package/README.md +31 -1
- package/ROADMAP.md +7 -2
- package/bin/coding-agent-skills +340 -2
- package/docs/adapters/README.md +21 -0
- package/docs/adapters/project-installation.md +14 -0
- package/docs/adapters/real-project-adoption.md +2 -2
- package/docs/architecture/README.md +3 -2
- package/docs/release/README.md +13 -10
- package/docs/release/npm-package.md +27 -2
- package/docs/safety/README.md +6 -1
- package/docs/testing/README.md +16 -0
- package/docs/usage/README.md +59 -5
- package/examples/command-policies/deployment-preflight.json +70 -0
- package/examples/evidence-packs/deployment-preflight.json +60 -0
- package/examples/manifests/deployment-preflight.json +14 -0
- package/examples/workflows/deployment-preflight.md +8 -0
- package/package.json +2 -1
- package/runs/skill-runs.md +36 -0
- package/schemas/project-adapter-installation.schema.json +2 -0
- package/schemas/project-adapter.schema.json +2 -0
- package/scripts/lib/deployment-preflight.mjs +655 -0
- package/scripts/lib/pack-rules.mjs +11 -2
- package/scripts/render-deployment-preflight.mjs +9 -0
- package/scripts/test-pack.mjs +151 -1
- package/scripts/validate-pack.mjs +5 -2
- package/skills/deployment-preflight/SKILL.md +89 -0
- package/skills/deployment-preflight/adapter-interface.md +17 -0
- package/skills/deployment-preflight/agents/openai.yaml +3 -0
- package/skills/deployment-preflight/checklist.md +7 -0
- package/skills/deployment-preflight/evidence-template.md +19 -0
- package/skills/deployment-preflight/examples.md +11 -0
- package/skills/deployment-preflight/failure-modes.md +11 -0
- package/tests/fixtures/deployment-preflight/adapter-project/.coding-agent/adapters/deployment-preflight-fixture/adapter.json +56 -0
- package/tests/fixtures/deployment-preflight/adapter-project/.coding-agent/skills.json +23 -0
- package/tests/fixtures/deployment-preflight/adapter-project/README.md +3 -0
- package/tests/fixtures/deployment-preflight/adapter-project/deploy/netlify.toml +3 -0
- package/tests/fixtures/deployment-preflight/adapter-project/ignored/render.yaml +3 -0
- package/tests/fixtures/deployment-preflight/adapter-project/package.json +5 -0
- package/tests/fixtures/deployment-preflight/static-project/Dockerfile +2 -0
- package/tests/fixtures/deployment-preflight/static-project/README.md +3 -0
- package/tests/fixtures/deployment-preflight/static-project/docs/deployment.md +4 -0
- package/tests/fixtures/deployment-preflight/static-project/package.json +6 -0
- package/tests/fixtures/deployment-preflight/static-project/src/index.js +1 -0
- package/tests/fixtures/deployment-preflight/static-project/wrangler.toml +3 -0
- package/tests/fixtures/triggers/cases.json +13 -1
- package/tests/trigger/README.md +2 -0
- package/work-ledger.md +33 -8
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
deploymentPreflightCliResult,
|
|
4
|
+
} from "./lib/deployment-preflight.mjs";
|
|
5
|
+
|
|
6
|
+
const result = deploymentPreflightCliResult(process.argv[2]);
|
|
7
|
+
const stream = result.stream === "stderr" ? process.stderr : process.stdout;
|
|
8
|
+
stream.write(`${result.lines.join("\n")}\n`);
|
|
9
|
+
process.exitCode = result.exitCode;
|
package/scripts/test-pack.mjs
CHANGED
|
@@ -72,6 +72,11 @@ import {
|
|
|
72
72
|
githubHandoffCliResult,
|
|
73
73
|
renderGithubHandoffReport,
|
|
74
74
|
} from "./lib/github-handoff.mjs";
|
|
75
|
+
import {
|
|
76
|
+
buildDeploymentPreflightReport,
|
|
77
|
+
deploymentPreflightCliResult,
|
|
78
|
+
renderDeploymentPreflightReport,
|
|
79
|
+
} from "./lib/deployment-preflight.mjs";
|
|
75
80
|
import {
|
|
76
81
|
adapterUpgradeCliResult,
|
|
77
82
|
checkAdapterUpgrade,
|
|
@@ -216,6 +221,39 @@ function snapshotAbsoluteDirectory(directory) {
|
|
|
216
221
|
return digest.digest("hex");
|
|
217
222
|
}
|
|
218
223
|
|
|
224
|
+
function assertOpenClawJsonContract(value, command, packageVersion = "0.2.16") {
|
|
225
|
+
assert.equal(value.tool, "coding-agent-skills");
|
|
226
|
+
assert.equal(value.command, command);
|
|
227
|
+
assert.equal(value.packageVersion, packageVersion);
|
|
228
|
+
assert.equal(value.success, true);
|
|
229
|
+
assert.match(value.status, /^(complete|partial|blocked|failed|empty)$/);
|
|
230
|
+
assert.equal(value.changedState, false);
|
|
231
|
+
assert.equal(value.safety?.readOnly, true);
|
|
232
|
+
assert.equal(value.safety?.secretsRead, false);
|
|
233
|
+
assert.equal(value.safety?.targetCommandsRun, false);
|
|
234
|
+
assert.equal(value.safety?.mutationsPerformed, false);
|
|
235
|
+
assert.equal(value.exitCode, 0);
|
|
236
|
+
assert.equal(value.exitCodeMeaning, "handled");
|
|
237
|
+
assert.ok(value.recommendedNextAction);
|
|
238
|
+
assert.equal(typeof value.recommendedNextAction.label, "string");
|
|
239
|
+
assert.equal(typeof value.recommendedNextAction.reason, "string");
|
|
240
|
+
assert.equal(typeof value.recommendedNextAction.requiresApproval, "boolean");
|
|
241
|
+
for (const key of [
|
|
242
|
+
"summary",
|
|
243
|
+
"findings",
|
|
244
|
+
"warnings",
|
|
245
|
+
"risks",
|
|
246
|
+
"skipped",
|
|
247
|
+
"notVerified",
|
|
248
|
+
"refusedBehavior",
|
|
249
|
+
]) {
|
|
250
|
+
assert.ok(Array.isArray(value[key]), `${command}.${key} must be an array`);
|
|
251
|
+
}
|
|
252
|
+
const encoded = JSON.stringify(value);
|
|
253
|
+
assert.doesNotMatch(encoded, /github_pat_|ghp_|Authorization:\s*Bearer|BEGIN .*PRIVATE KEY/i);
|
|
254
|
+
assert.doesNotMatch(encoded, /\/home\/oneclickwebsitedesignfactory\//);
|
|
255
|
+
}
|
|
256
|
+
|
|
219
257
|
const manifestSchema = readJson("schemas/skill-manifest.schema.json");
|
|
220
258
|
const policySchema = readJson("schemas/command-policy.schema.json");
|
|
221
259
|
const adapterSchema = readJson("schemas/project-adapter.schema.json");
|
|
@@ -313,6 +351,7 @@ test("local CLI maps approved commands to existing safe scripts", () => {
|
|
|
313
351
|
assert.ok(cliText.includes("scripts/render-api-contract-audit.mjs"));
|
|
314
352
|
assert.ok(cliText.includes("scripts/render-migration-review.mjs"));
|
|
315
353
|
assert.ok(cliText.includes("scripts/render-github-handoff.mjs"));
|
|
354
|
+
assert.ok(cliText.includes("scripts/render-deployment-preflight.mjs"));
|
|
316
355
|
assert.ok(cliText.includes("scripts/validate-adapters.mjs"));
|
|
317
356
|
assert.ok(!cliText.includes(".env"));
|
|
318
357
|
|
|
@@ -363,6 +402,10 @@ test("local CLI maps approved commands to existing safe scripts", () => {
|
|
|
363
402
|
["github-handoff", githubHandoffFixture],
|
|
364
403
|
/# GitHub Handoff Report/,
|
|
365
404
|
],
|
|
405
|
+
[
|
|
406
|
+
["deployment-preflight", path.join(fixtureRoot, "deployment-preflight", "static-project")],
|
|
407
|
+
/# Deployment Preflight Report/,
|
|
408
|
+
],
|
|
366
409
|
];
|
|
367
410
|
|
|
368
411
|
for (const [args, expected] of commands) {
|
|
@@ -384,10 +427,68 @@ test("local CLI maps approved commands to existing safe scripts", () => {
|
|
|
384
427
|
assert.match(unknown.stderr, /unknown command: deploy/);
|
|
385
428
|
});
|
|
386
429
|
|
|
430
|
+
test("local CLI emits OpenClaw-compatible JSON for public commands", () => {
|
|
431
|
+
const cliPath = path.join(root, "bin", "coding-agent-skills");
|
|
432
|
+
const fixtureRoot = path.join(root, "tests", "fixtures");
|
|
433
|
+
const githubHandoffFixture = createGitFixture(
|
|
434
|
+
path.join("tests", "fixtures", "github-handoff", "static-project"),
|
|
435
|
+
);
|
|
436
|
+
fs.appendFileSync(path.join(githubHandoffFixture, "README.md"), "\nLocal handoff change.\n");
|
|
437
|
+
|
|
438
|
+
const commands = [
|
|
439
|
+
["validate-pack"],
|
|
440
|
+
["validate-adapters", path.join(fixtureRoot, "external-adapters", "valid-basic")],
|
|
441
|
+
[
|
|
442
|
+
"validate-project",
|
|
443
|
+
path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin"),
|
|
444
|
+
],
|
|
445
|
+
["repo-map", path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin")],
|
|
446
|
+
["route-trace", path.join(fixtureRoot, "route-trace", "static-project")],
|
|
447
|
+
["env-audit", path.join(fixtureRoot, "env-audit", "static-project")],
|
|
448
|
+
["secret-audit", path.join(fixtureRoot, "secret-audit", "static-project")],
|
|
449
|
+
["api-contract-audit", path.join(fixtureRoot, "api-contract-audit", "static-project")],
|
|
450
|
+
["migration-review", path.join(fixtureRoot, "migration-review", "static-project")],
|
|
451
|
+
["github-handoff", githubHandoffFixture],
|
|
452
|
+
["deployment-preflight", path.join(fixtureRoot, "deployment-preflight", "static-project")],
|
|
453
|
+
];
|
|
454
|
+
|
|
455
|
+
for (const args of commands) {
|
|
456
|
+
const result = spawnSync(cliPath, [...args, "--json"], {
|
|
457
|
+
cwd: root,
|
|
458
|
+
encoding: "utf8",
|
|
459
|
+
stdio: "pipe",
|
|
460
|
+
});
|
|
461
|
+
assert.equal(result.status, 0, `${args.join(" ")}\n${result.stderr}`);
|
|
462
|
+
assert.equal(result.stderr, "");
|
|
463
|
+
const parsed = JSON.parse(result.stdout);
|
|
464
|
+
assertOpenClawJsonContract(parsed, args[0]);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const partial = spawnSync(
|
|
468
|
+
cliPath,
|
|
469
|
+
[
|
|
470
|
+
"deployment-preflight",
|
|
471
|
+
path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin"),
|
|
472
|
+
"--json",
|
|
473
|
+
],
|
|
474
|
+
{
|
|
475
|
+
cwd: root,
|
|
476
|
+
encoding: "utf8",
|
|
477
|
+
stdio: "pipe",
|
|
478
|
+
},
|
|
479
|
+
);
|
|
480
|
+
assert.equal(partial.status, 0);
|
|
481
|
+
const parsedPartial = JSON.parse(partial.stdout);
|
|
482
|
+
assertOpenClawJsonContract(parsedPartial, "deployment-preflight");
|
|
483
|
+
assert.equal(parsedPartial.status, "partial");
|
|
484
|
+
assert.ok(parsedPartial.skipped.length > 0);
|
|
485
|
+
assert.ok(parsedPartial.refusedBehavior.includes("no deployments"));
|
|
486
|
+
});
|
|
487
|
+
|
|
387
488
|
test("npm package metadata is public-ready and dependency-free", () => {
|
|
388
489
|
const packageJson = readJson("package.json");
|
|
389
490
|
assert.equal(packageJson.name, "coding-agent-skills");
|
|
390
|
-
assert.equal(packageJson.version, "0.2.
|
|
491
|
+
assert.equal(packageJson.version, "0.2.16");
|
|
391
492
|
assert.equal(
|
|
392
493
|
packageJson.description,
|
|
393
494
|
"Evidence-first, read-only coding-agent skills and project adapter tooling.",
|
|
@@ -405,6 +506,7 @@ test("npm package metadata is public-ready and dependency-free", () => {
|
|
|
405
506
|
"api-contract-audit",
|
|
406
507
|
"migration-review",
|
|
407
508
|
"github-handoff",
|
|
509
|
+
"deployment-preflight",
|
|
408
510
|
"project-adapters",
|
|
409
511
|
"code-validation",
|
|
410
512
|
"cli",
|
|
@@ -796,6 +898,54 @@ test("github-handoff does not broaden a repo-map-only project adapter", () => {
|
|
|
796
898
|
assert.match(renderGithubHandoffReport(result), /github-handoff is not enabled/);
|
|
797
899
|
});
|
|
798
900
|
|
|
901
|
+
test("deployment-preflight maps static deployment surfaces without deployment behavior", () => {
|
|
902
|
+
const result = buildDeploymentPreflightReport(
|
|
903
|
+
path.join(root, "tests", "fixtures", "deployment-preflight", "static-project"),
|
|
904
|
+
{ coreRoot: root },
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
assert.equal(result.status, "complete");
|
|
908
|
+
assert.ok(result.configFiles.some((record) => record.path === "wrangler.toml"));
|
|
909
|
+
assert.ok(result.configFiles.some((record) => record.path === "Dockerfile"));
|
|
910
|
+
assert.ok(result.deploymentDocs.some((record) => record.path === "docs/deployment.md"));
|
|
911
|
+
assert.ok(result.packageScriptKeys.some((record) => record.key === "deploy"));
|
|
912
|
+
assert.ok(result.platformIndicators.some((record) => record.platform === "cloudflare"));
|
|
913
|
+
assert.ok(result.riskIndicators.some((record) => record.type === "production-reference"));
|
|
914
|
+
assert.match(renderDeploymentPreflightReport(result), /No deployment, cloud provider API call/);
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
test("deployment-preflight respects adapter-declared scope", () => {
|
|
918
|
+
const result = buildDeploymentPreflightReport(
|
|
919
|
+
path.join(root, "tests", "fixtures", "deployment-preflight", "adapter-project"),
|
|
920
|
+
{ coreRoot: root },
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
assert.equal(result.status, "complete");
|
|
924
|
+
assert.equal(result.adapter.enabled, true);
|
|
925
|
+
assert.deepEqual(result.scopePaths, ["deploy"]);
|
|
926
|
+
assert.deepEqual(result.filesScanned, ["deploy/netlify.toml"]);
|
|
927
|
+
assert.ok(result.configFiles.some((record) => record.path === "deploy/netlify.toml"));
|
|
928
|
+
assert.ok(result.warnings.includes("deployment-preflight used adapter-declared safe read paths only"));
|
|
929
|
+
const cli = deploymentPreflightCliResult(
|
|
930
|
+
path.join(root, "tests", "fixtures", "deployment-preflight", "adapter-project"),
|
|
931
|
+
{ coreRoot: root },
|
|
932
|
+
);
|
|
933
|
+
assert.equal(cli.exitCode, 0);
|
|
934
|
+
assert.match(cli.lines.join("\n"), /Deployment-preflight enabled: yes/);
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
test("deployment-preflight does not broaden a repo-map-only project adapter", () => {
|
|
938
|
+
const result = buildDeploymentPreflightReport(
|
|
939
|
+
path.join(root, "tests", "fixtures", "project-adapter-installation", "valid-exact-pin"),
|
|
940
|
+
{ coreRoot: root },
|
|
941
|
+
);
|
|
942
|
+
|
|
943
|
+
assert.equal(result.status, "partial");
|
|
944
|
+
assert.equal(result.filesScanned.length, 0);
|
|
945
|
+
assert.equal(result.configFiles.length, 0);
|
|
946
|
+
assert.match(renderDeploymentPreflightReport(result), /deployment-preflight is not enabled/);
|
|
947
|
+
});
|
|
948
|
+
|
|
799
949
|
test("validate-pack accepts installed package trees without source-only gitignore", () => {
|
|
800
950
|
const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), "installed-package-"));
|
|
801
951
|
const installedRoot = path.join(temporaryRoot, "coding-agent-skills");
|
|
@@ -101,6 +101,7 @@ const requiredRootFiles = [
|
|
|
101
101
|
"scripts/render-api-contract-audit.mjs",
|
|
102
102
|
"scripts/render-migration-review.mjs",
|
|
103
103
|
"scripts/render-github-handoff.mjs",
|
|
104
|
+
"scripts/render-deployment-preflight.mjs",
|
|
104
105
|
"scripts/check-adapter-upgrade.mjs",
|
|
105
106
|
"scripts/check-adapter-upgrade-chain.mjs",
|
|
106
107
|
"scripts/validate-adapters.mjs",
|
|
@@ -112,6 +113,7 @@ const requiredRootFiles = [
|
|
|
112
113
|
"scripts/lib/api-contract-audit.mjs",
|
|
113
114
|
"scripts/lib/migration-review.mjs",
|
|
114
115
|
"scripts/lib/github-handoff.mjs",
|
|
116
|
+
"scripts/lib/deployment-preflight.mjs",
|
|
115
117
|
"scripts/lib/adapter-upgrade.mjs",
|
|
116
118
|
"scripts/lib/adapter-upgrade-chain.mjs",
|
|
117
119
|
"scripts/lib/adapter-discovery.mjs",
|
|
@@ -685,8 +687,8 @@ if (packageJson) {
|
|
|
685
687
|
if (packageJson.name !== "coding-agent-skills") {
|
|
686
688
|
failures.push("package.json has unexpected package name");
|
|
687
689
|
}
|
|
688
|
-
if (packageJson.version !== "0.2.
|
|
689
|
-
failures.push("package.json version must be 0.2.
|
|
690
|
+
if (packageJson.version !== "0.2.16") {
|
|
691
|
+
failures.push("package.json version must be 0.2.16 for public package validation");
|
|
690
692
|
}
|
|
691
693
|
if (packageJson.type !== "module") failures.push("package.json must preserve ESM mode");
|
|
692
694
|
if (packageJson.private !== false) {
|
|
@@ -710,6 +712,7 @@ if (packageJson) {
|
|
|
710
712
|
"api-contract-audit",
|
|
711
713
|
"migration-review",
|
|
712
714
|
"github-handoff",
|
|
715
|
+
"deployment-preflight",
|
|
713
716
|
"project-adapters",
|
|
714
717
|
"code-validation",
|
|
715
718
|
"cli",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deployment-preflight
|
|
3
|
+
description: Map statically visible deployment readiness evidence without deploying, calling provider APIs, installing packages, building, testing, reading secrets, or mutating project/runtime state. Use when Codex needs a bounded pre-deploy orientation report from config files, docs, package script keys, and static platform indicators before separately approved deployment work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deployment Preflight
|
|
7
|
+
|
|
8
|
+
Map deployment-related evidence that is already visible in the repository. Remain
|
|
9
|
+
audit-only and avoid turning preflight discovery into deployment, cloud, runtime, build, or
|
|
10
|
+
secret work.
|
|
11
|
+
|
|
12
|
+
This skill must not change project files, Git state, dependencies, runtime state, services,
|
|
13
|
+
databases, cloud provider state, remotes, deployment targets, or generated outputs.
|
|
14
|
+
|
|
15
|
+
## Purpose And Use
|
|
16
|
+
|
|
17
|
+
Use this skill before deployment planning, release handoff, or platform-specific work when
|
|
18
|
+
the agent needs to understand visible deployment config, deployment docs, platform hints,
|
|
19
|
+
and static readiness risks.
|
|
20
|
+
|
|
21
|
+
Do not use it as proof of deployability, provider CLI behavior, cloud API state, domain
|
|
22
|
+
validity, environment values, build outcomes, test outcomes, service runtime, deployment
|
|
23
|
+
publication, database migration state, or secret content.
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
Require a project root or starting path. Optionally accept a project adapter, intended scan
|
|
28
|
+
area, documentation precedence, deployment config hints, or known platform boundaries.
|
|
29
|
+
|
|
30
|
+
Do not assume a missing deployment config means no deployment exists, package script keys are
|
|
31
|
+
safe to run, provider credentials are present, remote state matches repository state, or a
|
|
32
|
+
project adapter enables this skill unless validation proves it.
|
|
33
|
+
|
|
34
|
+
## Procedure
|
|
35
|
+
|
|
36
|
+
1. Record user intent, project root, declared scope, adapter state, and safety boundary.
|
|
37
|
+
2. Validate a project adapter when present before reading adapter-declared metadata.
|
|
38
|
+
3. If an adapter is present but does not enable `deployment-preflight`, stop static file
|
|
39
|
+
reading and report the adapter-limited skip.
|
|
40
|
+
4. Build scan scope from adapter safe read paths when available; otherwise use a bounded
|
|
41
|
+
generic static scan.
|
|
42
|
+
5. Exclude `.env`, secret-bearing files, generated output, dependency paths, build output,
|
|
43
|
+
runtime output, and oversized files before reading.
|
|
44
|
+
6. Identify deployment config files and platform indicators.
|
|
45
|
+
7. Identify deployment documentation and runbook references.
|
|
46
|
+
8. Identify package script keys that mention deployment tooling without printing command
|
|
47
|
+
values.
|
|
48
|
+
9. Identify static risk indicators without judging runtime or provider safety.
|
|
49
|
+
10. Emit the shared evidence pack or deployment preflight report before claiming completion.
|
|
50
|
+
|
|
51
|
+
Use [checklist.md](checklist.md). Consult [failure-modes.md](failure-modes.md),
|
|
52
|
+
[adapter-interface.md](adapter-interface.md), and [examples.md](examples.md). Format findings
|
|
53
|
+
with [evidence-template.md](evidence-template.md).
|
|
54
|
+
|
|
55
|
+
## Evidence, Recovery, And Dependencies
|
|
56
|
+
|
|
57
|
+
Emit repository identity, adapter state, scan scope, ignored paths, files scanned, deployment
|
|
58
|
+
config files, deployment docs, package script keys, platform indicators, risk indicators,
|
|
59
|
+
skipped items, not-verified areas, warnings, and changed-state declaration through the
|
|
60
|
+
shared evidence-pack contract.
|
|
61
|
+
|
|
62
|
+
Recover from missing configs, ambiguous platform hints, unreadable files, or adapter limits
|
|
63
|
+
by reporting uncertainty. Never recover by deploying, running provider CLIs, calling cloud
|
|
64
|
+
APIs, installing dependencies, building, testing, starting services, broadening adapter
|
|
65
|
+
scope, or reading `.env`.
|
|
66
|
+
|
|
67
|
+
This skill depends on the evidence-pack contract and may consume validated project adapters.
|
|
68
|
+
Adapters may add safe paths, ignored paths, documentation precedence, and evidence
|
|
69
|
+
requirements, but cannot weaken policy or turn this skill into deployment work.
|
|
70
|
+
|
|
71
|
+
## Approval Boundary
|
|
72
|
+
|
|
73
|
+
Explicit approval may permit one named non-secret static file read outside normal source
|
|
74
|
+
paths. Approval does not permit `.env` or secret-file reads, provider API calls, provider CLI
|
|
75
|
+
execution, package installation, builds, tests, runtime checks, service mutation,
|
|
76
|
+
deployments, migrations, Git mutation, or project writes.
|
|
77
|
+
|
|
78
|
+
## Completion
|
|
79
|
+
|
|
80
|
+
Claim `complete` only when the declared static scan scope was inspected, visible deployment
|
|
81
|
+
surfaces are reported, skipped and not-verified areas are explicit, adapter limitations are
|
|
82
|
+
clear, and no project, Git, dependency, runtime, service, database, cloud provider, remote,
|
|
83
|
+
deployment, or generated-output state changed.
|
|
84
|
+
|
|
85
|
+
Report `partial`, `failed`, or `blocked` when adapter scope prevents scanning, requested
|
|
86
|
+
evidence requires deployment/runtime/provider behavior, the project root cannot be
|
|
87
|
+
established, or safety exclusions prevent the requested conclusion.
|
|
88
|
+
|
|
89
|
+
These conditions are both the acceptance criteria and definition of done.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Deployment Preflight Adapter Interface
|
|
2
|
+
|
|
3
|
+
Adapters may narrow the static scan by declaring:
|
|
4
|
+
|
|
5
|
+
- `extensions.safeReadPaths`
|
|
6
|
+
- `extensions.ignoredPaths`
|
|
7
|
+
- `extensions.documentationPrecedence`
|
|
8
|
+
- `extensions.requiredEvidence`
|
|
9
|
+
- `extensions.expectedPackageManagers`
|
|
10
|
+
|
|
11
|
+
Adapters must declare `deployment-preflight` with `declaredMode: "audit-only"` and
|
|
12
|
+
compatible core versions. They cannot allow deployments, provider API calls, package
|
|
13
|
+
installs, builds, tests, runtime checks, migrations, secret reads, project writes, failure
|
|
14
|
+
suppression, completion overrides, or scope expansion without approval.
|
|
15
|
+
|
|
16
|
+
If a project adapter is present but does not enable `deployment-preflight`, the skill reports
|
|
17
|
+
`partial` and does not read target files.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
display_name: Deployment Preflight
|
|
2
|
+
short_description: Map static deployment readiness evidence without deploying or calling provider APIs.
|
|
3
|
+
default_prompt: Review this repository's static deployment readiness evidence as an audit-only pass without modifying files, deploying, calling provider APIs, installing packages, building, testing, mutating services, or reading secrets.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Deployment Preflight Checklist
|
|
2
|
+
|
|
3
|
+
- Confirm the project root, branch state, adapter state, and declared scan scope.
|
|
4
|
+
- Validate the project adapter before consuming adapter-declared paths.
|
|
5
|
+
- Exclude `.env`, secret-bearing, generated, dependency, build, runtime-output, and oversized files.
|
|
6
|
+
- Report deployment config files, deployment docs, package script keys, platform indicators, risk indicators, skipped items, and not-verified areas.
|
|
7
|
+
- Confirm no deployment, provider API call, package install, build, test, runtime check, migration, secret read, project write, or Git mutation occurred.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Deployment Preflight Evidence Template
|
|
2
|
+
|
|
3
|
+
- Status:
|
|
4
|
+
- Project root:
|
|
5
|
+
- Branch state:
|
|
6
|
+
- Adapter present/enabled:
|
|
7
|
+
- Scope paths:
|
|
8
|
+
- Ignored paths:
|
|
9
|
+
- Files scanned:
|
|
10
|
+
- Deployment config files:
|
|
11
|
+
- Deployment docs:
|
|
12
|
+
- Package script keys:
|
|
13
|
+
- Platform indicators:
|
|
14
|
+
- Risk indicators:
|
|
15
|
+
- Skipped items:
|
|
16
|
+
- Not verified:
|
|
17
|
+
- Refused behavior:
|
|
18
|
+
- Changed-state declaration:
|
|
19
|
+
- Recommended next action:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Deployment Preflight Examples
|
|
2
|
+
|
|
3
|
+
**Safe:** `coding-agent-skills deployment-preflight /workspace/project`
|
|
4
|
+
|
|
5
|
+
**Safe:** `node scripts/render-deployment-preflight.mjs /workspace/project`
|
|
6
|
+
|
|
7
|
+
**Unsafe and denied:** provider deployment commands, package deploy scripts, and production
|
|
8
|
+
publish commands.
|
|
9
|
+
|
|
10
|
+
Use the report to orient future deployment planning. Do not treat static evidence as proof
|
|
11
|
+
that credentials, cloud resources, domains, builds, or deployed services are valid.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Deployment Preflight Failure Modes
|
|
2
|
+
|
|
3
|
+
- The project root cannot be established.
|
|
4
|
+
- A project adapter is present but invalid or does not enable `deployment-preflight`.
|
|
5
|
+
- Deployment config is absent, generated, or outside the approved scan scope.
|
|
6
|
+
- Files are skipped because they are secret-bearing, oversized, symlinked, generated, or ignored.
|
|
7
|
+
- A request asks for provider state, deployment execution, runtime health, credential checks, or build verification.
|
|
8
|
+
|
|
9
|
+
Recover by reporting partial evidence and clear uncertainty. Do not recover by deploying,
|
|
10
|
+
calling provider APIs, installing packages, building, testing, running services, widening
|
|
11
|
+
scope, or reading secrets.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adapterId": "deployment-preflight-fixture",
|
|
3
|
+
"adapterVersion": "1.0.0",
|
|
4
|
+
"project": {
|
|
5
|
+
"id": "fixture-deployment-preflight",
|
|
6
|
+
"detection": {
|
|
7
|
+
"rootMarkers": [
|
|
8
|
+
{"kind": "file", "path": "package.json"},
|
|
9
|
+
{"kind": "file", "path": "README.md"}
|
|
10
|
+
],
|
|
11
|
+
"maximumDepth": 1,
|
|
12
|
+
"scope": "declared-project-root",
|
|
13
|
+
"requireApprovalOutsideScope": true
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"supportedSkills": [
|
|
17
|
+
{
|
|
18
|
+
"id": "deployment-preflight",
|
|
19
|
+
"compatibleVersions": ["0.2.3", "0.2.x"],
|
|
20
|
+
"declaredMode": "audit-only"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"extensions": {
|
|
24
|
+
"safeReadPaths": ["deploy"],
|
|
25
|
+
"ignoredPaths": ["ignored", "node_modules", "dist", "build"],
|
|
26
|
+
"documentationPrecedence": ["README.md"],
|
|
27
|
+
"commandAliases": [],
|
|
28
|
+
"safeStatusCommands": [],
|
|
29
|
+
"requiredEvidence": ["project root", "adapter scope", "deployment config", "not-verified provider areas"],
|
|
30
|
+
"expectedRuntimeManagers": [],
|
|
31
|
+
"expectedPackageManagers": ["npm"]
|
|
32
|
+
},
|
|
33
|
+
"approvalRequirements": [],
|
|
34
|
+
"inheritance": {
|
|
35
|
+
"sharedRestrictions": "required",
|
|
36
|
+
"deniedOperationCategories": [
|
|
37
|
+
"file-write",
|
|
38
|
+
"package-install",
|
|
39
|
+
"deployment",
|
|
40
|
+
"git-mutation",
|
|
41
|
+
"unrestricted-scan",
|
|
42
|
+
"secret-read",
|
|
43
|
+
"process-mutation",
|
|
44
|
+
"service-mutation",
|
|
45
|
+
"migration-apply",
|
|
46
|
+
"privileged-api"
|
|
47
|
+
],
|
|
48
|
+
"allowRestrictionRemoval": false,
|
|
49
|
+
"allowModeOverride": false,
|
|
50
|
+
"allowFailureSuppression": false,
|
|
51
|
+
"allowCompletionOverride": false,
|
|
52
|
+
"allowSecretExposure": false,
|
|
53
|
+
"allowRequiredEvidenceRemoval": false,
|
|
54
|
+
"allowScopeExpansionWithoutApproval": false
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"declarationVersion": "1.0.0",
|
|
3
|
+
"projectId": "fixture-deployment-preflight",
|
|
4
|
+
"adapterRoot": ".coding-agent/adapters",
|
|
5
|
+
"adapterSchemaVersion": "1.0.0",
|
|
6
|
+
"core": {
|
|
7
|
+
"id": "coding-agent-skills",
|
|
8
|
+
"expectedVersion": "0.2.3",
|
|
9
|
+
"versionPin": ">=0.2.3 <0.3.0"
|
|
10
|
+
},
|
|
11
|
+
"compatibleSkillIds": ["deployment-preflight"],
|
|
12
|
+
"adapters": [
|
|
13
|
+
{
|
|
14
|
+
"id": "deployment-preflight-fixture",
|
|
15
|
+
"version": "1.0.0",
|
|
16
|
+
"skillIds": ["deployment-preflight"]
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"validationCommand": "node <shared-core>/scripts/validate-project-adapters.mjs <project-root>",
|
|
20
|
+
"evidenceOutput": ".coding-agent/evidence",
|
|
21
|
+
"approvalPolicyReference": ".coding-agent/approval-policy.md",
|
|
22
|
+
"noSecrets": true
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const handler = () => "ok";
|
|
@@ -91,6 +91,18 @@
|
|
|
91
91
|
"expectedSkill": "github-handoff",
|
|
92
92
|
"notSkills": ["runtime-truth", "deployment-preflight"]
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
"id": "deployment-preflight-static",
|
|
96
|
+
"prompt": "Run a deployment preflight and map static deployment config, docs, and package script keys without deploying.",
|
|
97
|
+
"expectedSkill": "deployment-preflight",
|
|
98
|
+
"notSkills": ["runtime-truth", "build-verify"]
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "deployment-preflight-readiness",
|
|
102
|
+
"prompt": "Map deployment readiness evidence before release, but do not call provider APIs or run builds.",
|
|
103
|
+
"expectedSkill": "deployment-preflight",
|
|
104
|
+
"notSkills": ["github-handoff", "migration-review"]
|
|
105
|
+
},
|
|
94
106
|
{
|
|
95
107
|
"id": "build-after-implementation",
|
|
96
108
|
"prompt": "The implementation is finished. Run the existing typecheck, tests, and build.",
|
|
@@ -143,7 +155,7 @@
|
|
|
143
155
|
"id": "negative-deploy",
|
|
144
156
|
"prompt": "Deploy this application to production.",
|
|
145
157
|
"expectedSkill": null,
|
|
146
|
-
"notSkills": ["repo-map", "route-trace", "env-audit", "secret-audit", "api-contract-audit", "migration-review", "github-handoff", "build-verify", "git-preflight", "runtime-truth", "llm-drift-control"]
|
|
158
|
+
"notSkills": ["repo-map", "route-trace", "env-audit", "secret-audit", "api-contract-audit", "migration-review", "github-handoff", "deployment-preflight", "build-verify", "git-preflight", "runtime-truth", "llm-drift-control"]
|
|
147
159
|
},
|
|
148
160
|
{
|
|
149
161
|
"id": "negative-install",
|
package/tests/trigger/README.md
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
deployment, or migration execution.
|
|
15
15
|
- Local GitHub handoff evidence must trigger `github-handoff`, not publication,
|
|
16
16
|
pull request creation, or Git mutation.
|
|
17
|
+
- Static deployment readiness mapping must trigger `deployment-preflight`, not deployment,
|
|
18
|
+
provider API calls, or runtime mutation.
|
|
17
19
|
- Local validation must trigger `build-verify` only when project-native checks are requested.
|
|
18
20
|
- Git readiness must trigger `git-preflight`, not publication.
|
|
19
21
|
- Process/listener/health questions must trigger `runtime-truth`, not restart behavior.
|