coding-agent-skills 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +9 -1
  3. package/ROADMAP.md +7 -3
  4. package/bin/coding-agent-skills +14 -0
  5. package/docs/adapters/README.md +39 -0
  6. package/docs/adapters/project-installation.md +26 -0
  7. package/docs/adapters/real-project-adoption.md +2 -1
  8. package/docs/architecture/README.md +5 -3
  9. package/docs/release/README.md +3 -2
  10. package/docs/release/npm-package.md +12 -2
  11. package/docs/safety/README.md +11 -1
  12. package/docs/testing/README.md +16 -0
  13. package/docs/usage/README.md +25 -5
  14. package/examples/command-policies/deployment-preflight.json +70 -0
  15. package/examples/command-policies/github-handoff.json +74 -0
  16. package/examples/evidence-packs/deployment-preflight.json +60 -0
  17. package/examples/evidence-packs/github-handoff.json +67 -0
  18. package/examples/manifests/deployment-preflight.json +14 -0
  19. package/examples/manifests/github-handoff.json +14 -0
  20. package/examples/workflows/deployment-preflight.md +8 -0
  21. package/examples/workflows/github-handoff.md +5 -0
  22. package/package.json +3 -1
  23. package/runs/skill-runs.md +35 -0
  24. package/schemas/project-adapter-installation.schema.json +4 -0
  25. package/schemas/project-adapter.schema.json +4 -0
  26. package/scripts/lib/deployment-preflight.mjs +655 -0
  27. package/scripts/lib/github-handoff.mjs +446 -0
  28. package/scripts/lib/pack-rules.mjs +20 -2
  29. package/scripts/render-deployment-preflight.mjs +9 -0
  30. package/scripts/render-github-handoff.mjs +7 -0
  31. package/scripts/test-pack.mjs +148 -1
  32. package/scripts/validate-pack.mjs +8 -2
  33. package/skills/deployment-preflight/SKILL.md +89 -0
  34. package/skills/deployment-preflight/adapter-interface.md +17 -0
  35. package/skills/deployment-preflight/agents/openai.yaml +3 -0
  36. package/skills/deployment-preflight/checklist.md +7 -0
  37. package/skills/deployment-preflight/evidence-template.md +19 -0
  38. package/skills/deployment-preflight/examples.md +11 -0
  39. package/skills/deployment-preflight/failure-modes.md +11 -0
  40. package/skills/github-handoff/SKILL.md +95 -0
  41. package/skills/github-handoff/adapter-interface.md +18 -0
  42. package/skills/github-handoff/agents/openai.yaml +3 -0
  43. package/skills/github-handoff/checklist.md +10 -0
  44. package/skills/github-handoff/evidence-template.md +16 -0
  45. package/skills/github-handoff/examples.md +19 -0
  46. package/skills/github-handoff/failure-modes.md +8 -0
  47. package/tests/fixtures/deployment-preflight/adapter-project/.coding-agent/adapters/deployment-preflight-fixture/adapter.json +56 -0
  48. package/tests/fixtures/deployment-preflight/adapter-project/.coding-agent/skills.json +23 -0
  49. package/tests/fixtures/deployment-preflight/adapter-project/README.md +3 -0
  50. package/tests/fixtures/deployment-preflight/adapter-project/deploy/netlify.toml +3 -0
  51. package/tests/fixtures/deployment-preflight/adapter-project/ignored/render.yaml +3 -0
  52. package/tests/fixtures/deployment-preflight/adapter-project/package.json +5 -0
  53. package/tests/fixtures/deployment-preflight/static-project/Dockerfile +2 -0
  54. package/tests/fixtures/deployment-preflight/static-project/README.md +3 -0
  55. package/tests/fixtures/deployment-preflight/static-project/docs/deployment.md +4 -0
  56. package/tests/fixtures/deployment-preflight/static-project/package.json +6 -0
  57. package/tests/fixtures/deployment-preflight/static-project/src/index.js +1 -0
  58. package/tests/fixtures/deployment-preflight/static-project/wrangler.toml +3 -0
  59. package/tests/fixtures/github-handoff/adapter-project/.coding-agent/adapters/github-handoff-fixture/adapter.json +56 -0
  60. package/tests/fixtures/github-handoff/adapter-project/.coding-agent/skills.json +23 -0
  61. package/tests/fixtures/github-handoff/adapter-project/README.md +3 -0
  62. package/tests/fixtures/github-handoff/adapter-project/package.json +4 -0
  63. package/tests/fixtures/github-handoff/adapter-project/src/index.js +1 -0
  64. package/tests/fixtures/github-handoff/static-project/README.md +3 -0
  65. package/tests/fixtures/github-handoff/static-project/package.json +4 -0
  66. package/tests/fixtures/github-handoff/static-project/src/index.js +1 -0
  67. package/tests/fixtures/triggers/cases.json +26 -2
  68. package/tests/trigger/README.md +4 -0
  69. package/work-ledger.md +28 -6
@@ -67,6 +67,16 @@ import {
67
67
  migrationReviewCliResult,
68
68
  renderMigrationReviewReport,
69
69
  } from "./lib/migration-review.mjs";
70
+ import {
71
+ buildGithubHandoffReport,
72
+ githubHandoffCliResult,
73
+ renderGithubHandoffReport,
74
+ } from "./lib/github-handoff.mjs";
75
+ import {
76
+ buildDeploymentPreflightReport,
77
+ deploymentPreflightCliResult,
78
+ renderDeploymentPreflightReport,
79
+ } from "./lib/deployment-preflight.mjs";
70
80
  import {
71
81
  adapterUpgradeCliResult,
72
82
  checkAdapterUpgrade,
@@ -133,6 +143,27 @@ function readJson(relativePath) {
133
143
  return JSON.parse(read(relativePath));
134
144
  }
135
145
 
146
+ function runGitFixtureCommand(cwd, args) {
147
+ const result = spawnSync("git", args, {
148
+ cwd,
149
+ encoding: "utf8",
150
+ stdio: "pipe",
151
+ });
152
+ assert.equal(result.status, 0, `git ${args.join(" ")}\n${result.stderr}`);
153
+ return result.stdout.trim();
154
+ }
155
+
156
+ function createGitFixture(sourceRelativePath) {
157
+ const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "github-handoff-fixture-"));
158
+ fs.cpSync(path.join(root, sourceRelativePath), temporary, { recursive: true });
159
+ runGitFixtureCommand(temporary, ["init", "-b", "main"]);
160
+ runGitFixtureCommand(temporary, ["config", "user.name", "Fixture User"]);
161
+ runGitFixtureCommand(temporary, ["config", "user.email", "fixture@example.invalid"]);
162
+ runGitFixtureCommand(temporary, ["add", "."]);
163
+ runGitFixtureCommand(temporary, ["commit", "-m", "initial fixture commit"]);
164
+ return temporary;
165
+ }
166
+
136
167
  function walk(directory, output = []) {
137
168
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
138
169
  if ([".git", "node_modules", "validation-output"].includes(entry.name)) continue;
@@ -286,10 +317,17 @@ test("local CLI maps approved commands to existing safe scripts", () => {
286
317
  assert.ok(cliText.includes("scripts/render-secret-audit.mjs"));
287
318
  assert.ok(cliText.includes("scripts/render-api-contract-audit.mjs"));
288
319
  assert.ok(cliText.includes("scripts/render-migration-review.mjs"));
320
+ assert.ok(cliText.includes("scripts/render-github-handoff.mjs"));
321
+ assert.ok(cliText.includes("scripts/render-deployment-preflight.mjs"));
289
322
  assert.ok(cliText.includes("scripts/validate-adapters.mjs"));
290
323
  assert.ok(!cliText.includes(".env"));
291
324
 
292
325
  const fixtureRoot = path.join(root, "tests", "fixtures");
326
+ const githubHandoffFixture = createGitFixture(
327
+ path.join("tests", "fixtures", "github-handoff", "static-project"),
328
+ );
329
+ fs.appendFileSync(path.join(githubHandoffFixture, "README.md"), "\nLocal handoff change.\n");
330
+
293
331
  const commands = [
294
332
  [["validate-pack"], /pilot pack valid/],
295
333
  [
@@ -327,6 +365,14 @@ test("local CLI maps approved commands to existing safe scripts", () => {
327
365
  ["migration-review", path.join(fixtureRoot, "migration-review", "static-project")],
328
366
  /# Migration Review Report/,
329
367
  ],
368
+ [
369
+ ["github-handoff", githubHandoffFixture],
370
+ /# GitHub Handoff Report/,
371
+ ],
372
+ [
373
+ ["deployment-preflight", path.join(fixtureRoot, "deployment-preflight", "static-project")],
374
+ /# Deployment Preflight Report/,
375
+ ],
330
376
  ];
331
377
 
332
378
  for (const [args, expected] of commands) {
@@ -351,7 +397,7 @@ test("local CLI maps approved commands to existing safe scripts", () => {
351
397
  test("npm package metadata is public-ready and dependency-free", () => {
352
398
  const packageJson = readJson("package.json");
353
399
  assert.equal(packageJson.name, "coding-agent-skills");
354
- assert.equal(packageJson.version, "0.2.13");
400
+ assert.equal(packageJson.version, "0.2.15");
355
401
  assert.equal(
356
402
  packageJson.description,
357
403
  "Evidence-first, read-only coding-agent skills and project adapter tooling.",
@@ -368,6 +414,8 @@ test("npm package metadata is public-ready and dependency-free", () => {
368
414
  "secret-audit",
369
415
  "api-contract-audit",
370
416
  "migration-review",
417
+ "github-handoff",
418
+ "deployment-preflight",
371
419
  "project-adapters",
372
420
  "code-validation",
373
421
  "cli",
@@ -708,6 +756,105 @@ test("migration-review does not broaden a repo-map-only project adapter", () =>
708
756
  assert.match(renderMigrationReviewReport(result), /migration-review is not enabled/);
709
757
  });
710
758
 
759
+ test("github-handoff summarizes local git state without mutating remotes", () => {
760
+ const fixture = createGitFixture(path.join("tests", "fixtures", "github-handoff", "static-project"));
761
+ runGitFixtureCommand(fixture, ["tag", "v0.0.0"]);
762
+ fs.appendFileSync(path.join(fixture, "README.md"), "\nChanged for handoff.\n");
763
+ fs.writeFileSync(path.join(fixture, "src", "new-file.js"), "export const handoff = true;\n");
764
+
765
+ const result = buildGithubHandoffReport(fixture, { coreRoot: root });
766
+
767
+ assert.equal(result.status, "complete");
768
+ assert.equal(result.git.branch, "main");
769
+ assert.ok(result.git.head);
770
+ assert.ok(result.git.tagsAtHead.includes("v0.0.0"));
771
+ assert.equal(result.changeSummary.total, 2);
772
+ assert.equal(result.changeSummary.modified, 1);
773
+ assert.equal(result.changeSummary.untracked, 1);
774
+ assert.ok(result.changedFiles.some((record) => record.path === "README.md"));
775
+ assert.ok(result.changedFiles.some((record) => record.path === "src/new-file.js"));
776
+ assert.match(renderGithubHandoffReport(result), /No commit, push, tag/);
777
+ });
778
+
779
+ test("github-handoff respects adapter-declared handoff metadata", () => {
780
+ const fixture = createGitFixture(path.join("tests", "fixtures", "github-handoff", "adapter-project"));
781
+ fs.appendFileSync(path.join(fixture, "src", "index.js"), "\nexport const changed = true;\n");
782
+
783
+ const result = buildGithubHandoffReport(fixture, { coreRoot: root });
784
+
785
+ assert.equal(result.status, "complete");
786
+ assert.equal(result.adapter.enabled, true);
787
+ assert.ok(result.requiredEvidence.includes("handoff summary"));
788
+ assert.ok(result.ignoredPaths.includes("tmp"));
789
+ assert.equal(result.changeSummary.modified, 1);
790
+ assert.ok(result.warnings.includes("github-handoff used adapter-declared handoff evidence metadata"));
791
+ const cli = githubHandoffCliResult(fixture, { coreRoot: root });
792
+ assert.equal(cli.exitCode, 0);
793
+ assert.match(cli.lines.join("\n"), /Github-handoff enabled: yes/);
794
+ });
795
+
796
+ test("github-handoff does not broaden a repo-map-only project adapter", () => {
797
+ const fixture = createGitFixture(
798
+ path.join("tests", "fixtures", "project-adapter-installation", "valid-exact-pin"),
799
+ );
800
+ fs.appendFileSync(path.join(fixture, "README.md"), "\nShould not be listed.\n");
801
+
802
+ const result = buildGithubHandoffReport(fixture, { coreRoot: root });
803
+
804
+ assert.equal(result.status, "partial");
805
+ assert.equal(result.changedFiles.length, 0);
806
+ assert.equal(result.changeSummary.total, 0);
807
+ assert.match(renderGithubHandoffReport(result), /github-handoff is not enabled/);
808
+ });
809
+
810
+ test("deployment-preflight maps static deployment surfaces without deployment behavior", () => {
811
+ const result = buildDeploymentPreflightReport(
812
+ path.join(root, "tests", "fixtures", "deployment-preflight", "static-project"),
813
+ { coreRoot: root },
814
+ );
815
+
816
+ assert.equal(result.status, "complete");
817
+ assert.ok(result.configFiles.some((record) => record.path === "wrangler.toml"));
818
+ assert.ok(result.configFiles.some((record) => record.path === "Dockerfile"));
819
+ assert.ok(result.deploymentDocs.some((record) => record.path === "docs/deployment.md"));
820
+ assert.ok(result.packageScriptKeys.some((record) => record.key === "deploy"));
821
+ assert.ok(result.platformIndicators.some((record) => record.platform === "cloudflare"));
822
+ assert.ok(result.riskIndicators.some((record) => record.type === "production-reference"));
823
+ assert.match(renderDeploymentPreflightReport(result), /No deployment, cloud provider API call/);
824
+ });
825
+
826
+ test("deployment-preflight respects adapter-declared scope", () => {
827
+ const result = buildDeploymentPreflightReport(
828
+ path.join(root, "tests", "fixtures", "deployment-preflight", "adapter-project"),
829
+ { coreRoot: root },
830
+ );
831
+
832
+ assert.equal(result.status, "complete");
833
+ assert.equal(result.adapter.enabled, true);
834
+ assert.deepEqual(result.scopePaths, ["deploy"]);
835
+ assert.deepEqual(result.filesScanned, ["deploy/netlify.toml"]);
836
+ assert.ok(result.configFiles.some((record) => record.path === "deploy/netlify.toml"));
837
+ assert.ok(result.warnings.includes("deployment-preflight used adapter-declared safe read paths only"));
838
+ const cli = deploymentPreflightCliResult(
839
+ path.join(root, "tests", "fixtures", "deployment-preflight", "adapter-project"),
840
+ { coreRoot: root },
841
+ );
842
+ assert.equal(cli.exitCode, 0);
843
+ assert.match(cli.lines.join("\n"), /Deployment-preflight enabled: yes/);
844
+ });
845
+
846
+ test("deployment-preflight does not broaden a repo-map-only project adapter", () => {
847
+ const result = buildDeploymentPreflightReport(
848
+ path.join(root, "tests", "fixtures", "project-adapter-installation", "valid-exact-pin"),
849
+ { coreRoot: root },
850
+ );
851
+
852
+ assert.equal(result.status, "partial");
853
+ assert.equal(result.filesScanned.length, 0);
854
+ assert.equal(result.configFiles.length, 0);
855
+ assert.match(renderDeploymentPreflightReport(result), /deployment-preflight is not enabled/);
856
+ });
857
+
711
858
  test("validate-pack accepts installed package trees without source-only gitignore", () => {
712
859
  const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), "installed-package-"));
713
860
  const installedRoot = path.join(temporaryRoot, "coding-agent-skills");
@@ -100,6 +100,8 @@ const requiredRootFiles = [
100
100
  "scripts/render-secret-audit.mjs",
101
101
  "scripts/render-api-contract-audit.mjs",
102
102
  "scripts/render-migration-review.mjs",
103
+ "scripts/render-github-handoff.mjs",
104
+ "scripts/render-deployment-preflight.mjs",
103
105
  "scripts/check-adapter-upgrade.mjs",
104
106
  "scripts/check-adapter-upgrade-chain.mjs",
105
107
  "scripts/validate-adapters.mjs",
@@ -110,6 +112,8 @@ const requiredRootFiles = [
110
112
  "scripts/lib/secret-audit.mjs",
111
113
  "scripts/lib/api-contract-audit.mjs",
112
114
  "scripts/lib/migration-review.mjs",
115
+ "scripts/lib/github-handoff.mjs",
116
+ "scripts/lib/deployment-preflight.mjs",
113
117
  "scripts/lib/adapter-upgrade.mjs",
114
118
  "scripts/lib/adapter-upgrade-chain.mjs",
115
119
  "scripts/lib/adapter-discovery.mjs",
@@ -683,8 +687,8 @@ if (packageJson) {
683
687
  if (packageJson.name !== "coding-agent-skills") {
684
688
  failures.push("package.json has unexpected package name");
685
689
  }
686
- if (packageJson.version !== "0.2.13") {
687
- failures.push("package.json version must be 0.2.13 for public package validation");
690
+ if (packageJson.version !== "0.2.15") {
691
+ failures.push("package.json version must be 0.2.15 for public package validation");
688
692
  }
689
693
  if (packageJson.type !== "module") failures.push("package.json must preserve ESM mode");
690
694
  if (packageJson.private !== false) {
@@ -707,6 +711,8 @@ if (packageJson) {
707
711
  "secret-audit",
708
712
  "api-contract-audit",
709
713
  "migration-review",
714
+ "github-handoff",
715
+ "deployment-preflight",
710
716
  "project-adapters",
711
717
  "code-validation",
712
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,95 @@
1
+ ---
2
+ name: github-handoff
3
+ description: Prepare read-only GitHub handoff evidence from local Git metadata. Use when Codex needs to summarize branch state, HEAD, tags at HEAD, remote names, and changed-file status before a separately approved pull request, release, or GitHub workflow handoff without creating commits, pushes, tags, pull requests, API calls, token reads, or file changes.
4
+ ---
5
+
6
+ # GitHub Handoff
7
+
8
+ ## Purpose And Use
9
+
10
+ Use this skill to produce a local, audit-only handoff report before a human or separately approved workflow performs GitHub work.
11
+
12
+ The skill is for local Git evidence only. It does not create pull requests, publish releases, push branches, inspect tokens, or call GitHub APIs.
13
+
14
+ ## Inputs
15
+
16
+ Required:
17
+
18
+ - Project root.
19
+
20
+ Optional:
21
+
22
+ - Project adapter declaration that enables `github-handoff`.
23
+ - Human-provided handoff intent.
24
+
25
+ Do not assume:
26
+
27
+ - GitHub authentication is available.
28
+ - Local commits are pushed.
29
+ - CI status, review status, or PR state is known.
30
+ - Remote URLs are safe to print.
31
+
32
+ ## Procedure
33
+
34
+ 1. Confirm the project root exists.
35
+ 2. Validate the project adapter when one is present.
36
+ 3. If an adapter exists but does not enable `github-handoff`, report `partial` and do not list changed files.
37
+ 4. Inspect local Git metadata only: root, branch state, current branch, HEAD, tags at HEAD, remote names, and status entries.
38
+ 5. Redact secret-bearing changed paths such as `.env`, key files, credential paths, or token paths.
39
+ 6. Summarize changed-file counts by status.
40
+ 7. Record skipped and not-verified GitHub state honestly.
41
+ 8. State refused behavior clearly.
42
+
43
+ ## Evidence, Recovery, And Dependencies
44
+
45
+ Expected evidence:
46
+
47
+ - Git root.
48
+ - Branch state.
49
+ - Current branch.
50
+ - HEAD or short HEAD.
51
+ - Tags at HEAD.
52
+ - Remote names only, not remote URLs.
53
+ - Changed-file summary.
54
+ - Redacted path count when applicable.
55
+
56
+ Recovery:
57
+
58
+ - If the directory is not a Git repository, return `failed` with no mutation.
59
+ - If Git status is unavailable, return a warning and preserve partial evidence.
60
+ - If adapter validation fails, fail closed.
61
+
62
+ Dependencies:
63
+
64
+ - Local Git command-line tool.
65
+ - Node.js 20+ for the packaged renderer.
66
+
67
+ ## Approval Boundary
68
+
69
+ This skill is audit-only.
70
+
71
+ Allowed:
72
+
73
+ - Read local Git metadata.
74
+ - List changed-file paths unless they are secret-bearing.
75
+ - Validate project adapter metadata.
76
+ - Render a handoff report.
77
+
78
+ Forbidden:
79
+
80
+ - Commit.
81
+ - Push.
82
+ - Tag.
83
+ - Checkout, reset, rebase, merge, stash, restore, or clean.
84
+ - Create pull requests.
85
+ - Create releases.
86
+ - Call GitHub APIs.
87
+ - Read tokens, `.env`, `.env.*`, `.npmrc`, keys, or credential files.
88
+ - Print remote URLs.
89
+ - Change project files.
90
+
91
+ ## Completion
92
+
93
+ Complete only after a report states what was verified, what was skipped, and what was not verified.
94
+
95
+ The completion boundary must say that no commit, push, tag, branch change, pull request creation, GitHub API mutation, token read, secret-file read, or project write occurred.
@@ -0,0 +1,18 @@
1
+ # GitHub Handoff Adapter Interface
2
+
3
+ Adapters may enable `github-handoff` as an audit-only skill.
4
+
5
+ Adapters may narrow:
6
+
7
+ - Required evidence labels.
8
+ - Ignored path labels.
9
+ - Documentation precedence used as human context.
10
+
11
+ Adapters must not:
12
+
13
+ - Permit commits, pushes, tags, pull request creation, release creation, or GitHub API mutation.
14
+ - Permit token reads.
15
+ - Permit secret-file reads.
16
+ - Suppress warnings or failures.
17
+ - Redefine completion.
18
+ - Escalate the skill out of audit-only mode.
@@ -0,0 +1,3 @@
1
+ display_name: GitHub Handoff
2
+ short_description: Prepare local Git handoff evidence without GitHub mutation.
3
+ default_prompt: Prepare a GitHub handoff report as an audit-only pass without modifying files, committing, pushing, tagging, creating pull requests, reading tokens, or calling GitHub APIs.
@@ -0,0 +1,10 @@
1
+ # GitHub Handoff Checklist
2
+
3
+ - Confirm the project root.
4
+ - Validate adapter metadata if present.
5
+ - Inspect local Git state only.
6
+ - Summarize changed files without reading file contents.
7
+ - Redact secret-bearing paths.
8
+ - Do not print remote URLs.
9
+ - Report not-verified GitHub state.
10
+ - Confirm no mutation occurred.
@@ -0,0 +1,16 @@
1
+ # GitHub Handoff Evidence Template
2
+
3
+ - Skill: `github-handoff`
4
+ - Status: `complete`, `partial`, or `failed`
5
+ - Project root:
6
+ - Git root:
7
+ - Branch state:
8
+ - HEAD:
9
+ - Tags at HEAD:
10
+ - Remote names:
11
+ - Changed-file summary:
12
+ - Redacted path count:
13
+ - Skipped:
14
+ - Not verified:
15
+ - Refused behavior:
16
+ - Changed state: no project, Git, GitHub, dependency, runtime, service, or remote state changed.
@@ -0,0 +1,19 @@
1
+ # GitHub Handoff Examples
2
+
3
+ ## Safe Examples
4
+
5
+ ```bash
6
+ coding-agent-skills github-handoff /path/to/project
7
+ ```
8
+
9
+ ```bash
10
+ node scripts/render-github-handoff.mjs /path/to/project
11
+ ```
12
+
13
+ ## Unsafe Examples
14
+
15
+ - Create a pull request.
16
+ - Push the current branch.
17
+ - Tag the release.
18
+ - Read GitHub tokens.
19
+ - Print configured remote URLs.
@@ -0,0 +1,8 @@
1
+ # GitHub Handoff Failure Modes
2
+
3
+ - Project root is not a Git repository.
4
+ - Adapter exists but does not enable `github-handoff`.
5
+ - Adapter validation fails.
6
+ - Git status is unavailable.
7
+ - Secret-bearing changed paths are present and must be redacted.
8
+ - Remote PR, CI, and review state cannot be verified without separately approved GitHub access.
@@ -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,3 @@
1
+ # Deployment Preflight Adapter Fixture
2
+
3
+ Synthetic adapter-scoped deployment preflight fixture.