coding-agent-skills 0.2.8 → 0.2.10

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 (78) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +6 -0
  3. package/ROADMAP.md +21 -15
  4. package/bin/coding-agent-skills +15 -1
  5. package/docs/adapters/README.md +34 -0
  6. package/docs/adapters/project-installation.md +25 -1
  7. package/docs/adapters/real-project-adoption.md +3 -2
  8. package/docs/architecture/README.md +5 -1
  9. package/docs/release/README.md +11 -8
  10. package/docs/release/npm-package.md +10 -4
  11. package/docs/safety/README.md +9 -1
  12. package/docs/testing/README.md +15 -0
  13. package/docs/usage/README.md +23 -5
  14. package/examples/command-policies/env-audit.json +73 -0
  15. package/examples/command-policies/route-trace.json +72 -0
  16. package/examples/evidence-packs/env-audit.json +55 -0
  17. package/examples/evidence-packs/route-trace.json +55 -0
  18. package/examples/manifests/env-audit.json +14 -0
  19. package/examples/manifests/route-trace.json +14 -0
  20. package/examples/workflows/env-audit.md +16 -0
  21. package/examples/workflows/route-trace.md +20 -0
  22. package/package.json +3 -1
  23. package/runs/skill-runs.md +37 -0
  24. package/schemas/project-adapter-installation.schema.json +7 -3
  25. package/schemas/project-adapter.schema.json +4 -0
  26. package/scripts/lib/env-audit.mjs +640 -0
  27. package/scripts/lib/pack-rules.mjs +20 -2
  28. package/scripts/lib/route-trace.mjs +785 -0
  29. package/scripts/render-env-audit.mjs +8 -0
  30. package/scripts/render-route-trace.mjs +8 -0
  31. package/scripts/test-pack.mjs +159 -1
  32. package/scripts/validate-pack.mjs +8 -2
  33. package/skills/env-audit/SKILL.md +58 -0
  34. package/skills/env-audit/adapter-interface.md +12 -0
  35. package/skills/env-audit/agents/openai.yaml +4 -0
  36. package/skills/env-audit/checklist.md +7 -0
  37. package/skills/env-audit/evidence-template.md +17 -0
  38. package/skills/env-audit/examples.md +28 -0
  39. package/skills/env-audit/failure-modes.md +5 -0
  40. package/skills/route-trace/SKILL.md +58 -0
  41. package/skills/route-trace/adapter-interface.md +20 -0
  42. package/skills/route-trace/agents/openai.yaml +4 -0
  43. package/skills/route-trace/checklist.md +11 -0
  44. package/skills/route-trace/evidence-template.md +18 -0
  45. package/skills/route-trace/examples.md +32 -0
  46. package/skills/route-trace/failure-modes.md +9 -0
  47. package/tests/fixtures/env-audit/adapter-project/.coding-agent/adapters/env-audit-fixture/adapter.json +56 -0
  48. package/tests/fixtures/env-audit/adapter-project/.coding-agent/skills.json +23 -0
  49. package/tests/fixtures/env-audit/adapter-project/README.md +3 -0
  50. package/tests/fixtures/env-audit/adapter-project/package.json +4 -0
  51. package/tests/fixtures/env-audit/adapter-project/src/config.ts +2 -0
  52. package/tests/fixtures/env-audit/static-project/.env.example +3 -0
  53. package/tests/fixtures/env-audit/static-project/README.md +3 -0
  54. package/tests/fixtures/env-audit/static-project/docs/setup.md +3 -0
  55. package/tests/fixtures/env-audit/static-project/package.json +4 -0
  56. package/tests/fixtures/env-audit/static-project/src/config.ts +4 -0
  57. package/tests/fixtures/env-audit/static-project/src/deno.ts +1 -0
  58. package/tests/fixtures/route-trace/adapter-project/.coding-agent/adapters/route-trace-fixture/adapter.json +59 -0
  59. package/tests/fixtures/route-trace/adapter-project/.coding-agent/skills.json +23 -0
  60. package/tests/fixtures/route-trace/adapter-project/README.md +3 -0
  61. package/tests/fixtures/route-trace/adapter-project/app/api/items/route.ts +3 -0
  62. package/tests/fixtures/route-trace/adapter-project/package.json +5 -0
  63. package/tests/fixtures/route-trace/adapter-project/pages/index.tsx +3 -0
  64. package/tests/fixtures/route-trace/adapter-project/src/routes.ts +3 -0
  65. package/tests/fixtures/route-trace/static-project/.env.example +1 -0
  66. package/tests/fixtures/route-trace/static-project/README.md +3 -0
  67. package/tests/fixtures/route-trace/static-project/app/api/users/route.ts +3 -0
  68. package/tests/fixtures/route-trace/static-project/app/blog/[slug]/page.tsx +3 -0
  69. package/tests/fixtures/route-trace/static-project/app/page.tsx +3 -0
  70. package/tests/fixtures/route-trace/static-project/package.json +5 -0
  71. package/tests/fixtures/route-trace/static-project/pages/about.tsx +3 -0
  72. package/tests/fixtures/route-trace/static-project/pages/api/hello.ts +3 -0
  73. package/tests/fixtures/route-trace/static-project/server/routes.ts +4 -0
  74. package/tests/fixtures/route-trace/static-project/src/route-config.ts +4 -0
  75. package/tests/fixtures/route-trace/static-project/src/router.tsx +10 -0
  76. package/tests/fixtures/triggers/cases.json +25 -1
  77. package/tests/trigger/README.md +3 -0
  78. package/work-ledger.md +35 -10
@@ -0,0 +1,8 @@
1
+ import { envAuditCliResult } from "./lib/env-audit.mjs";
2
+
3
+ const outcome = envAuditCliResult(process.argv[2]);
4
+ for (const line of outcome.lines) {
5
+ if (outcome.stream === "stdout") console.log(line);
6
+ else console.error(line);
7
+ }
8
+ process.exitCode = outcome.exitCode;
@@ -0,0 +1,8 @@
1
+ import { routeTraceCliResult } from "./lib/route-trace.mjs";
2
+
3
+ const outcome = routeTraceCliResult(process.argv[2]);
4
+ for (const line of outcome.lines) {
5
+ if (outcome.stream === "stdout") console.log(line);
6
+ else console.error(line);
7
+ }
8
+ process.exitCode = outcome.exitCode;
@@ -42,6 +42,16 @@ import {
42
42
  buildAdapterRepoMapReport,
43
43
  renderAdapterRepoMapReport,
44
44
  } from "./lib/adapter-repo-map.mjs";
45
+ import {
46
+ buildRouteTraceReport,
47
+ renderRouteTraceReport,
48
+ routeTraceCliResult,
49
+ } from "./lib/route-trace.mjs";
50
+ import {
51
+ buildEnvAuditReport,
52
+ envAuditCliResult,
53
+ renderEnvAuditReport,
54
+ } from "./lib/env-audit.mjs";
45
55
  import {
46
56
  adapterUpgradeCliResult,
47
57
  checkAdapterUpgrade,
@@ -256,6 +266,8 @@ test("local CLI maps approved commands to existing safe scripts", () => {
256
266
  assert.ok(cliText.includes("scripts/validate-pack.mjs"));
257
267
  assert.ok(cliText.includes("scripts/validate-project-adapters.mjs"));
258
268
  assert.ok(cliText.includes("scripts/render-adapter-repo-map.mjs"));
269
+ assert.ok(cliText.includes("scripts/render-route-trace.mjs"));
270
+ assert.ok(cliText.includes("scripts/render-env-audit.mjs"));
259
271
  assert.ok(cliText.includes("scripts/validate-adapters.mjs"));
260
272
  assert.ok(!cliText.includes(".env"));
261
273
 
@@ -277,6 +289,14 @@ test("local CLI maps approved commands to existing safe scripts", () => {
277
289
  ["repo-map", path.join(fixtureRoot, "project-adapter-installation", "valid-exact-pin")],
278
290
  /# Adapter-Aware Repo Map/,
279
291
  ],
292
+ [
293
+ ["route-trace", path.join(fixtureRoot, "route-trace", "static-project")],
294
+ /# Route Trace Report/,
295
+ ],
296
+ [
297
+ ["env-audit", path.join(fixtureRoot, "env-audit", "static-project")],
298
+ /# Env Audit Report/,
299
+ ],
280
300
  ];
281
301
 
282
302
  for (const [args, expected] of commands) {
@@ -301,7 +321,7 @@ test("local CLI maps approved commands to existing safe scripts", () => {
301
321
  test("npm package metadata is public-ready and dependency-free", () => {
302
322
  const packageJson = readJson("package.json");
303
323
  assert.equal(packageJson.name, "coding-agent-skills");
304
- assert.equal(packageJson.version, "0.2.8");
324
+ assert.equal(packageJson.version, "0.2.10");
305
325
  assert.equal(
306
326
  packageJson.description,
307
327
  "Evidence-first, read-only coding-agent skills and project adapter tooling.",
@@ -313,6 +333,8 @@ test("npm package metadata is public-ready and dependency-free", () => {
313
333
  "coding-agent",
314
334
  "agent-skills",
315
335
  "repo-map",
336
+ "route-trace",
337
+ "env-audit",
316
338
  "project-adapters",
317
339
  "code-validation",
318
340
  "cli",
@@ -363,6 +385,142 @@ test("npm package metadata is public-ready and dependency-free", () => {
363
385
  assert.match(read("docs/release/npm-package.md"), /npm install -g coding-agent-skills/);
364
386
  });
365
387
 
388
+ test("route-trace renderer identifies static route files and inferred patterns", () => {
389
+ const result = buildRouteTraceReport(
390
+ path.join(root, "tests", "fixtures", "route-trace", "static-project"),
391
+ { coreRoot: root },
392
+ );
393
+ assert.equal(result.ok, true);
394
+ assert.equal(result.status, "complete");
395
+ assert.equal(result.adapter.present, false);
396
+ assert.ok(
397
+ result.verifiedRouteFiles.some(
398
+ (record) => record.route === "/api/users" && record.file === "app/api/users/route.ts",
399
+ ),
400
+ );
401
+ assert.ok(
402
+ result.verifiedRouteFiles.some(
403
+ (record) => record.route === "/blog/[slug]" && record.file === "app/blog/[slug]/page.tsx",
404
+ ),
405
+ );
406
+ assert.ok(
407
+ result.verifiedRouteFiles.some(
408
+ (record) => record.route === "/api/hello" && record.file === "pages/api/hello.ts",
409
+ ),
410
+ );
411
+ assert.ok(
412
+ result.inferredRoutePatterns.some(
413
+ (record) => record.route === "/dashboard" && record.kind === "react-router-route-declaration",
414
+ ),
415
+ );
416
+ assert.ok(
417
+ result.inferredRoutePatterns.some(
418
+ (record) => record.route === "/health" && record.method === "GET",
419
+ ),
420
+ );
421
+ assert.ok(result.notVerified.includes("runtime-generated routes"));
422
+ assert.ok(renderRouteTraceReport(result).includes("No target project build"));
423
+ });
424
+
425
+ test("route-trace renderer respects adapter-declared scope", () => {
426
+ const result = buildRouteTraceReport(
427
+ path.join(root, "tests", "fixtures", "route-trace", "adapter-project"),
428
+ { coreRoot: root },
429
+ );
430
+ assert.equal(result.ok, true);
431
+ assert.equal(result.status, "complete");
432
+ assert.equal(result.adapter.present, true);
433
+ assert.equal(result.adapter.enabled, true);
434
+ assert.deepEqual(result.adapter.scopePaths, ["app", "pages", "src"]);
435
+ assert.ok(
436
+ result.verifiedRouteFiles.some(
437
+ (record) => record.route === "/api/items" && record.file === "app/api/items/route.ts",
438
+ ),
439
+ );
440
+ assert.ok(
441
+ result.inferredRoutePatterns.some((record) => record.route === "/adapter-health"),
442
+ );
443
+
444
+ const cli = routeTraceCliResult(
445
+ path.join(root, "tests", "fixtures", "route-trace", "adapter-project"),
446
+ { coreRoot: root },
447
+ );
448
+ assert.equal(cli.exitCode, 0);
449
+ assert.match(cli.lines.join("\n"), /route-trace used adapter-declared safe read paths only/);
450
+ });
451
+
452
+ test("route-trace does not broaden a repo-map-only project adapter", () => {
453
+ const result = buildRouteTraceReport(
454
+ path.join(root, "tests", "fixtures", "project-adapter-installation", "valid-exact-pin"),
455
+ { coreRoot: root },
456
+ );
457
+ assert.equal(result.ok, true);
458
+ assert.equal(result.status, "partial");
459
+ assert.equal(result.adapter.present, true);
460
+ assert.equal(result.adapter.enabled, false);
461
+ assert.deepEqual(result.scannedFiles, []);
462
+ assert.match(renderRouteTraceReport(result), /route-trace is not enabled/);
463
+ });
464
+
465
+ test("env-audit identifies variable names without reading .env values", () => {
466
+ const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "env-audit-fixture-"));
467
+ fs.cpSync(path.join(root, "tests", "fixtures", "env-audit", "static-project"), temporary, {
468
+ recursive: true,
469
+ });
470
+ fs.writeFileSync(path.join(temporary, ".env"), "SHOULD_NOT_BE_READ=synthetic-fixture-value\n");
471
+
472
+ const result = buildEnvAuditReport(
473
+ temporary,
474
+ { coreRoot: root },
475
+ );
476
+
477
+ assert.equal(result.status, "complete");
478
+ assert.ok(result.filesScanned.includes(".env.example"));
479
+ assert.ok(!result.filesScanned.includes(".env"));
480
+ assert.ok(result.skipped.some((item) => item.path === ".env"));
481
+ const names = result.variables.map((variable) => variable.name);
482
+ assert.ok(names.includes("DATABASE_URL"));
483
+ assert.ok(names.includes("NEXT_PUBLIC_APP_URL"));
484
+ assert.ok(names.includes("PORT"));
485
+ assert.ok(names.includes("SERVICE_TOKEN"));
486
+ assert.ok(names.includes("DENO_REGION"));
487
+ const rendered = renderEnvAuditReport(result);
488
+ assert.match(rendered, /DATABASE_URL/);
489
+ assert.doesNotMatch(rendered, /synthetic-fixture-value/);
490
+ });
491
+
492
+ test("env-audit respects adapter-declared scope", () => {
493
+ const result = buildEnvAuditReport(
494
+ path.join(root, "tests", "fixtures", "env-audit", "adapter-project"),
495
+ { coreRoot: root },
496
+ );
497
+
498
+ assert.equal(result.status, "complete");
499
+ assert.equal(result.adapter.enabled, true);
500
+ assert.deepEqual(result.scopePaths, ["src"]);
501
+ assert.deepEqual(result.filesScanned, ["src/config.ts"]);
502
+ assert.ok(result.variables.some((variable) => variable.name === "ADAPTER_ONLY_VALUE"));
503
+ assert.ok(result.warnings.includes("env-audit used adapter-declared safe read paths only"));
504
+ const cli = envAuditCliResult(
505
+ path.join(root, "tests", "fixtures", "env-audit", "adapter-project"),
506
+ { coreRoot: root },
507
+ );
508
+ assert.equal(cli.exitCode, 0);
509
+ assert.match(cli.lines.join("\n"), /Env-audit enabled: yes/);
510
+ });
511
+
512
+ test("env-audit does not broaden a repo-map-only project adapter", () => {
513
+ const result = buildEnvAuditReport(
514
+ path.join(root, "tests", "fixtures", "project-adapter-installation", "valid-exact-pin"),
515
+ { coreRoot: root },
516
+ );
517
+
518
+ assert.equal(result.status, "partial");
519
+ assert.equal(result.filesScanned.length, 0);
520
+ assert.equal(result.variables.length, 0);
521
+ assert.match(renderEnvAuditReport(result), /env-audit is not enabled/);
522
+ });
523
+
366
524
  test("validate-pack accepts installed package trees without source-only gitignore", () => {
367
525
  const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), "installed-package-"));
368
526
  const installedRoot = path.join(temporaryRoot, "coding-agent-skills");
@@ -95,11 +95,15 @@ const requiredRootFiles = [
95
95
  "scripts/verify-evidence-bundle.mjs",
96
96
  "scripts/render-evidence-archive-report.mjs",
97
97
  "scripts/render-adapter-repo-map.mjs",
98
+ "scripts/render-route-trace.mjs",
99
+ "scripts/render-env-audit.mjs",
98
100
  "scripts/check-adapter-upgrade.mjs",
99
101
  "scripts/check-adapter-upgrade-chain.mjs",
100
102
  "scripts/validate-adapters.mjs",
101
103
  "scripts/validate-project-adapters.mjs",
102
104
  "scripts/lib/adapter-repo-map.mjs",
105
+ "scripts/lib/route-trace.mjs",
106
+ "scripts/lib/env-audit.mjs",
103
107
  "scripts/lib/adapter-upgrade.mjs",
104
108
  "scripts/lib/adapter-upgrade-chain.mjs",
105
109
  "scripts/lib/adapter-discovery.mjs",
@@ -673,8 +677,8 @@ if (packageJson) {
673
677
  if (packageJson.name !== "coding-agent-skills") {
674
678
  failures.push("package.json has unexpected package name");
675
679
  }
676
- if (packageJson.version !== "0.2.8") {
677
- failures.push("package.json version must be 0.2.8 for public package validation");
680
+ if (packageJson.version !== "0.2.10") {
681
+ failures.push("package.json version must be 0.2.10 for public package validation");
678
682
  }
679
683
  if (packageJson.type !== "module") failures.push("package.json must preserve ESM mode");
680
684
  if (packageJson.private !== false) {
@@ -692,6 +696,8 @@ if (packageJson) {
692
696
  "coding-agent",
693
697
  "agent-skills",
694
698
  "repo-map",
699
+ "route-trace",
700
+ "env-audit",
695
701
  "project-adapters",
696
702
  "code-validation",
697
703
  "cli",
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: env-audit
3
+ description: Identify environment variable names and configuration requirements from static files without reading .env files or printing values. Use when Codex must map required, optional, sample, or inferred environment names before implementation, deployment planning, or handoff; do not use for secret validation, credential testing, API calls, runtime checks, builds, tests, deployments, migrations, or secret-file reads.
4
+ ---
5
+
6
+ # Env Audit
7
+
8
+ Identify environment variable names from bounded static evidence and emit a value-free report. Remain audit-only and fail closed when evidence would require secret files, runtime state, or credential validation.
9
+
10
+ This skill must not change project files, Git state, dependencies, runtime state, services,
11
+ databases, remotes, or deployment state.
12
+
13
+ ## Purpose And Use
14
+
15
+ Use this skill to map statically visible environment variable names, sample declarations, and configuration references before changing code, documenting setup, or preparing handoff. It can classify names as sample, required, optional, or inferred, but it must not claim that any value exists or works.
16
+
17
+ Do not use this skill for secret auditing, credential validation, live service checks, runtime truth claims, deployment readiness, migrations, builds, tests, or package installation.
18
+
19
+ ## Inputs
20
+
21
+ Require a project root or starting path. Optionally accept a project adapter, intended config area, maximum static scan depth, or named framework/config family to prioritize.
22
+
23
+ Do not assume `.env` files may be read, variable values are safe, documented names are complete, sample files are current, runtime-injected variables are visible, or an adapter covers every configuration surface.
24
+
25
+ ## Procedure
26
+
27
+ 1. Record user intent, project root, declared scope, adapter state, and safety boundary.
28
+ 2. Validate a project adapter when present before reading adapter-declared metadata.
29
+ 3. If an adapter is present but does not enable `env-audit`, stop static file reading and report the adapter-limited skip.
30
+ 4. Build the scan scope from adapter safe read paths when available; otherwise use a bounded generic static scan.
31
+ 5. Exclude `.env`, `.env.*` except `.env.example`, secret-bearing paths, generated paths, dependency paths, and oversized files before reading.
32
+ 6. Extract environment variable names from safe static patterns such as `process.env.NAME`, `import.meta.env.NAME`, `Deno.env.get("NAME")`, `env("NAME")`, docs, and `.env.example` declarations.
33
+ 7. Never print values, line contents, tokens, credentials, or raw secret-like matches.
34
+ 8. Label every finding as sample, required, optional, inferred, skipped, or not verified.
35
+ 9. Report skipped files, unverified runtime/secret-store areas, branch state warnings, and safety refusals.
36
+ 10. Emit the shared evidence pack or env-audit report before claiming completion.
37
+
38
+ Use [checklist.md](checklist.md). Consult [failure-modes.md](failure-modes.md), [adapter-interface.md](adapter-interface.md), and [examples.md](examples.md). Format findings with [evidence-template.md](evidence-template.md).
39
+
40
+ ## Evidence, Recovery, And Dependencies
41
+
42
+ Emit repository identity, adapter state, scan scope, ignored paths, variable names, classifications, file references, sample files inspected, skipped items, not-verified areas, warnings, and changed-state declaration through the shared evidence-pack contract.
43
+
44
+ Recover from missing adapters, unreadable files, ambiguous variable names, or secret-bearing paths by narrowing scope and reporting uncertainty. Never recover by reading `.env`, printing values, validating credentials, contacting APIs, installing dependencies, running builds/tests, broadening adapter scope, or mutating files.
45
+
46
+ This skill depends on the evidence-pack contract and may consume validated project adapters. Adapters may add safe paths, ignored paths, documentation precedence, and evidence requirements, but cannot weaken policy or turn this skill into credential validation.
47
+
48
+ ## Approval Boundary
49
+
50
+ Explicit approval may permit one named non-secret static file read outside normal config paths. Approval does not permit `.env` or secret-file reads, value printing, credential validation, API calls, builds, tests, package installation, runtime checks, deployments, migrations, Git mutation, or project writes.
51
+
52
+ ## Completion
53
+
54
+ Claim `complete` only when the declared static scan scope was inspected, variable names are reported without values, skipped and not-verified areas are recorded with consequences, adapter limitations are explicit, and no project, Git, dependency, runtime, service, or remote state changed.
55
+
56
+ Report `partial`, `failed`, or `blocked` when adapter scope prevents env scanning, requested evidence requires secret files or runtime state, the project root cannot be established, or safety exclusions prevent a requested conclusion. Never claim credential presence or validity from static findings.
57
+
58
+ These conditions are both the acceptance criteria and definition of done.
@@ -0,0 +1,12 @@
1
+ Adapters may enable `env-audit` by declaring the skill ID with unchanged `audit-only`
2
+ mode and compatible version `0.2.3` or `0.2.x`.
3
+
4
+ Useful extension fields:
5
+
6
+ - `safeReadPaths`: source, docs, sample, and config paths that may contain env names.
7
+ - `ignoredPaths`: generated, dependency, runtime-output, and secret-bearing paths to skip.
8
+ - `documentationPrecedence`: docs that may explain required or optional env names.
9
+ - `requiredEvidence`: evidence the report must include before completion.
10
+
11
+ Adapters must not add `.env`, `.env.*` except `.env.example`, credentials, secret stores,
12
+ runtime checks, API calls, builds, tests, deployments, migrations, or project writes.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Env Audit"
3
+ short_description: "Map env variable names without reading values"
4
+ default_prompt: "Audit the statically visible environment variable names in this repository without changing project state. Do not read .env files or print values."
@@ -0,0 +1,7 @@
1
+ - Confirm project root, branch state, and adapter state.
2
+ - Validate adapter before consuming any adapter-declared paths.
3
+ - Refuse `.env`, `.env.*` except `.env.example`, secret-bearing paths, and generated outputs.
4
+ - Scan only bounded static source, docs, sample, and config files.
5
+ - Record variable names, classifications, and file references without values.
6
+ - Record skipped files and runtime/secret-store areas that were not verified.
7
+ - Confirm no files, dependencies, runtime state, services, remotes, or databases changed.
@@ -0,0 +1,17 @@
1
+ ## Env Audit Evidence
2
+
3
+ - Repository root:
4
+ - Branch state:
5
+ - Adapter state:
6
+ - Scan scope:
7
+ - Ignored paths:
8
+ - Static files scanned:
9
+ - Sample files inspected:
10
+ - Variable names found:
11
+ - Required names:
12
+ - Optional names:
13
+ - Inferred names:
14
+ - Skipped items:
15
+ - Not verified:
16
+ - Safety refusals:
17
+ - Changed state: none
@@ -0,0 +1,28 @@
1
+ ## Safe
2
+
3
+ ```bash
4
+ coding-agent-skills env-audit /workspace/app
5
+ ```
6
+
7
+ Produces a value-free list of names such as `DATABASE_URL`, `NEXT_PUBLIC_API_URL`, and
8
+ `PORT`, with file references and classifications.
9
+
10
+ ```bash
11
+ node scripts/render-env-audit.mjs tests/fixtures/env-audit/static-project
12
+ ```
13
+
14
+ Runs the synthetic fixture scanner without reading `.env` files or contacting services.
15
+
16
+ ## Unsafe
17
+
18
+ ```bash
19
+ cat .env
20
+ ```
21
+
22
+ Secret-file reads are forbidden.
23
+
24
+ ```bash
25
+ npm run dev
26
+ ```
27
+
28
+ Runtime checks are outside this skill.
@@ -0,0 +1,5 @@
1
+ - **Adapter not enabled:** report `partial` and do not broaden target-project scanning.
2
+ - **Secret-bearing path requested:** skip the file and record the safety exclusion.
3
+ - **Dynamic variable names:** report as not verified instead of guessing.
4
+ - **Large or unreadable files:** skip with consequence and continue bounded scanning.
5
+ - **Credential validation requested:** refuse and explain that only names are in scope.
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: route-trace
3
+ description: Trace statically visible application route surfaces without executing project code or changing state. Use when Codex must identify Next.js, API, React Router, Express/Fastify/Hono, or route-config surfaces from files before editing, reviewing, or planning route work; do not use for runtime URL probing, server execution, builds, tests, deployment checks, migrations, or runtime truth claims.
4
+ ---
5
+
6
+ # Route Trace
7
+
8
+ Identify route surfaces from static project files and emit an evidence-backed report. Remain audit-only and fail closed when route evidence would require execution or secret-bearing configuration.
9
+
10
+ This skill must not change project files, Git state, dependencies, runtime state, services,
11
+ databases, remotes, or deployment state.
12
+
13
+ ## Purpose And Use
14
+
15
+ Use this skill to locate and classify statically visible routes before changing application code, reviewing API surfaces, or planning route-level work. It can identify verified route files and inferred route declarations, but it must not claim that a route works at runtime.
16
+
17
+ Do not use this skill for live endpoint checks, server startup, browser tests, build verification, deployment readiness, migrations, database inspection, or secret auditing.
18
+
19
+ ## Inputs
20
+
21
+ Require a project root or starting path. Optionally accept a project adapter, intended route area, maximum static scan depth, or named route framework to prioritize.
22
+
23
+ Do not assume every route is statically discoverable, every route file is reachable in production, framework conventions are current, an adapter covers all route surfaces, or documentation route lists are authoritative.
24
+
25
+ ## Procedure
26
+
27
+ 1. Record user intent, project root, declared scope, adapter state, and safety boundary.
28
+ 2. Validate a project adapter when present before reading adapter-declared metadata.
29
+ 3. If an adapter is present but does not enable `route-trace`, stop static file reading and report the adapter-limited skip.
30
+ 4. Build the scan scope from adapter safe read paths when available; otherwise use a bounded generic static scan.
31
+ 5. Apply ignored paths and secret-file exclusions before reading any file.
32
+ 6. Identify verified route files from static conventions such as Next.js `app/` and `pages/` route files.
33
+ 7. Identify inferred route patterns from visible declarations such as React Router paths, Express/Fastify/Hono registrations, and route config objects.
34
+ 8. Label every finding as verified, inferred, skipped, not verified, or adapter-limited.
35
+ 9. Report skipped files, unverified runtime-dependent areas, branch state warnings, and safety refusals.
36
+ 10. Emit the shared evidence pack or route-trace report before claiming completion.
37
+
38
+ Use [checklist.md](checklist.md). Consult [failure-modes.md](failure-modes.md), [adapter-interface.md](adapter-interface.md), and [examples.md](examples.md). Format findings with [evidence-template.md](evidence-template.md).
39
+
40
+ ## Evidence, Recovery, And Dependencies
41
+
42
+ Emit repository identity, adapter state, scan scope, ignored paths, verified route files, inferred route patterns, skipped items, not-verified route classes, warnings, and changed-state declaration through the shared evidence-pack contract.
43
+
44
+ Recover from missing adapters, unsupported frameworks, unreadable files, or ambiguous route declarations by narrowing scope and reporting uncertainty. Never recover by installing dependencies, running app code, starting servers, hitting URLs, broadening adapter scope, reading `.env`, or mutating files.
45
+
46
+ This skill depends on the evidence-pack contract and may consume validated project adapters. Adapters may add safe paths, ignored paths, documentation precedence, and evidence requirements, but cannot weaken policy or turn this skill into runtime verification.
47
+
48
+ ## Approval Boundary
49
+
50
+ Explicit approval may permit one named non-secret static file read outside normal route paths. Approval does not permit package installation, builds, tests, runtime checks, server startup, URL probing, database inspection, migrations, deployments, Git mutation, or secret-file reads.
51
+
52
+ ## Completion
53
+
54
+ Claim `complete` only when the declared static scan scope was inspected, route findings are labeled by evidence type, skipped and not-verified areas are recorded with consequences, adapter limitations are explicit, and no project, Git, dependency, runtime, service, or remote state changed.
55
+
56
+ Report `partial`, `failed`, or `blocked` when adapter scope prevents route scanning, route evidence requires execution, the project root cannot be established, or safety exclusions prevent a requested conclusion. Never claim runtime availability or route correctness from static findings alone.
57
+
58
+ These conditions are both the acceptance criteria and definition of done.
@@ -0,0 +1,20 @@
1
+ # Route Trace Adapter Interface
2
+
3
+ Project adapters may enable `route-trace` only as an audit-only static inspection skill.
4
+
5
+ Adapters may provide:
6
+
7
+ - `safeReadPaths` for route-bearing source and route config files.
8
+ - `ignoredPaths` for generated output, dependency folders, and non-route surfaces.
9
+ - `documentationPrecedence` for route documentation that should be reviewed separately.
10
+ - `requiredEvidence` such as route files inspected, adapter scope, skipped paths, and not-verified runtime classes.
11
+ - `expectedPackageManagers` as metadata only.
12
+
13
+ Adapters must not:
14
+
15
+ - Add commands for `route-trace`.
16
+ - Permit builds, tests, package installs, server startup, URL probing, deployment, migration, database inspection, or secret reads.
17
+ - Remove inherited restrictions.
18
+ - Change `route-trace` from `audit-only` to action-capable.
19
+ - Expand scanning outside the declared project root without named approval.
20
+ - Suppress skipped checks, warnings, uncertainty, or completion requirements.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Route Trace"
3
+ short_description: "Trace static route surfaces without changing the project"
4
+ default_prompt: "Trace the statically visible route surfaces in this repository without modifying project, runtime, dependency, or external state."
@@ -0,0 +1,11 @@
1
+ # Route Trace Checklist
2
+
3
+ - Confirm project root and declared scope.
4
+ - Validate any project adapter before consuming adapter metadata.
5
+ - If the adapter is present but does not enable `route-trace`, stop and report the adapter-limited skip.
6
+ - Build a bounded static scan scope from adapter safe paths or generic repository-local defaults.
7
+ - Exclude `.env`, secret-bearing files, generated output, dependencies, and ignored paths.
8
+ - Identify verified route files separately from inferred route declarations.
9
+ - Record skipped paths and not-verified runtime-dependent route classes.
10
+ - State that no server, build, test, runtime check, deployment, migration, package install, or secret read was performed.
11
+ - Emit an evidence pack or route-trace report before claiming completion.
@@ -0,0 +1,18 @@
1
+ # Route Trace Evidence Template
2
+
3
+ Use the shared evidence-pack contract and include:
4
+
5
+ - Skill: `route-trace`
6
+ - Repository root, branch, HEAD, and working-tree state
7
+ - User intent and declared route scope
8
+ - Project adapter ID or `null`
9
+ - Static scan scope and ignored paths
10
+ - Verified route files with file paths and route patterns
11
+ - Inferred route declarations with evidence file paths
12
+ - Skipped paths with reasons and consequences
13
+ - Not-verified runtime-dependent route classes
14
+ - Safety refusals
15
+ - Changed state: `false`
16
+ - Recommended next action
17
+
18
+ Completion requires evidence for both findings and boundaries. A static route trace is not runtime truth.
@@ -0,0 +1,32 @@
1
+ # Route Trace Examples
2
+
3
+ ## Safe
4
+
5
+ - Inspect a repository for statically visible Next.js `app/` and `pages/` routes.
6
+ - Trace route declarations in React Router config without running the app.
7
+ - Identify Express, Fastify, or Hono-style route registrations from visible source files.
8
+ - Report that a project adapter prevents route scanning because `route-trace` is not enabled.
9
+
10
+ ## Unsafe
11
+
12
+ - Start a dev server to see which URLs respond.
13
+ - Run browser tests or fetch live endpoints.
14
+ - Read `.env` to determine route prefixes.
15
+ - Run migrations, seed databases, deploy, or inspect production infrastructure.
16
+ - Claim that a static route finding proves runtime availability.
17
+
18
+ ## Example Output Shape
19
+
20
+ ```text
21
+ # Route Trace Report
22
+ Status: complete
23
+
24
+ ## Verified Route Files
25
+ - /api/users (next-app-api-route-file) in app/api/users/route.ts
26
+
27
+ ## Inferred Route Patterns
28
+ - GET /health (express-style-route-registration) in server/routes.ts
29
+
30
+ ## Not Verified
31
+ - runtime-generated routes
32
+ ```
@@ -0,0 +1,9 @@
1
+ # Route Trace Failure Modes
2
+
3
+ - **No project root**: stop with `failed`; do not search outside the declared scope.
4
+ - **Malformed adapter**: stop with adapter validation failure; do not fall back to broader scanning.
5
+ - **Adapter present but not enabled**: report `partial` with adapter-limited scope and no target-file reads.
6
+ - **Unreadable or large files**: skip and record the consequence.
7
+ - **Secret-bearing path**: skip; do not request contents unless the user gives a named-file approval and the file is non-secret.
8
+ - **Runtime-dependent routing**: mark as not verified instead of running the app.
9
+ - **Ambiguous route declaration**: label as inferred or unresolved; do not upgrade it to verified.
@@ -0,0 +1,56 @@
1
+ {
2
+ "adapterId": "env-audit-fixture",
3
+ "adapterVersion": "1.0.0",
4
+ "project": {
5
+ "id": "env-audit-fixture",
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": "env-audit",
19
+ "compatibleVersions": ["0.2.3", "0.2.x"],
20
+ "declaredMode": "audit-only"
21
+ }
22
+ ],
23
+ "extensions": {
24
+ "safeReadPaths": ["src"],
25
+ "ignoredPaths": ["dist", "build"],
26
+ "documentationPrecedence": ["README.md"],
27
+ "commandAliases": [],
28
+ "safeStatusCommands": [],
29
+ "requiredEvidence": ["project root", "adapter scope", "env names", "skipped secret paths"],
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": "env-audit-fixture",
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": ["env-audit"],
12
+ "adapters": [
13
+ {
14
+ "id": "env-audit-fixture",
15
+ "version": "1.0.0",
16
+ "skillIds": ["env-audit"]
17
+ }
18
+ ],
19
+ "validationCommand": "node <shared-core>/scripts/validate-project-adapters.mjs <project-root>",
20
+ "evidenceOutput": "validation-output/project-adapters.json",
21
+ "approvalPolicyReference": "docs/coding-agent-approval-policy.md",
22
+ "noSecrets": true
23
+ }
@@ -0,0 +1,3 @@
1
+ # Env Audit Adapter Fixture
2
+
3
+ This fixture narrows env scanning to `src`.
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "fixture-env-audit-adapter",
3
+ "type": "module"
4
+ }