@event4u/agent-config 14.6.0 → 14.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +255 -145
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze/inbox.md +264 -10
  5. package/dist/agent-src/commands/analyze.md +1 -1
  6. package/dist/agent-src/commands/evals/git-pr-merge.json +13 -0
  7. package/dist/agent-src/commands/evals/roadmap.json +17 -1
  8. package/dist/agent-src/commands/pr/create.md +14 -2
  9. package/dist/agent-src/commands/pr/merge.md +379 -0
  10. package/dist/agent-src/commands/roadmap/process-full.md +272 -32
  11. package/dist/agent-src/commands/roadmap.md +1 -1
  12. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +46 -36
  13. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +37 -2
  14. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +95 -2
  15. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +289 -106
  16. package/dist/agent-src/rules/artifact-drafting-protocol.md +5 -1
  17. package/dist/agent-src/rules/context-hygiene.md +2 -0
  18. package/dist/agent-src/rules/decision-revisit-gate.md +67 -32
  19. package/dist/agent-src/rules/fix-what-you-see.md +108 -0
  20. package/dist/agent-src/rules/no-roadmap-references.md +0 -5
  21. package/dist/agent-src/rules/recurring-criticism.md +110 -0
  22. package/dist/agent-src/rules/roadmap-progress-sync.md +20 -1
  23. package/dist/agent-src/rules/rule-type-governance.md +0 -2
  24. package/dist/agent-src/rules/self-repair-loop.md +17 -0
  25. package/dist/agent-src/rules/skill-quality.md +0 -2
  26. package/dist/agent-src/rules/source-confidentiality.md +37 -7
  27. package/dist/agent-src/scripts/archival_sweep.ts +117 -0
  28. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
  29. package/dist/agent-src/scripts/dashboard_mode.ts +212 -0
  30. package/dist/agent-src/scripts/gate_budget.ts +282 -0
  31. package/dist/agent-src/scripts/gate_execute.ts +72 -31
  32. package/dist/agent-src/scripts/roadmap_gates.ts +74 -3
  33. package/dist/agent-src/scripts/update_roadmap_progress.ts +296 -53
  34. package/dist/agent-src/skills/adr-create/SKILL.md +124 -5
  35. package/dist/agent-src/skills/ai-council/SKILL.md +48 -807
  36. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +320 -0
  37. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +99 -0
  38. package/dist/agent-src/skills/ai-council/references/execution-modes.md +162 -0
  39. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +125 -0
  40. package/dist/agent-src/skills/ai-council/references/procedure.md +143 -0
  41. package/dist/agent-src/skills/decision-record/SKILL.md +61 -3
  42. package/dist/agent-src/skills/decision-review/SKILL.md +65 -0
  43. package/dist/agent-src/skills/merge-conflicts/SKILL.md +26 -0
  44. package/dist/agent-src/skills/quality-tools/SKILL.md +34 -326
  45. package/dist/agent-src/skills/quality-tools/references/js-ts-tools.md +113 -0
  46. package/dist/agent-src/skills/quality-tools/references/php-tools.md +222 -0
  47. package/dist/agent-src/skills/roadmap-management/SKILL.md +15 -409
  48. package/dist/agent-src/skills/roadmap-management/references/archival.md +226 -0
  49. package/dist/agent-src/skills/roadmap-management/references/authoring.md +107 -0
  50. package/dist/agent-src/skills/roadmap-management/references/dashboard.md +47 -0
  51. package/dist/agent-src/skills/roadmap-management/references/lifecycle.md +58 -0
  52. package/dist/agent-src/skills/security/SKILL.md +8 -0
  53. package/dist/agent-src/skills/security-audit/SKILL.md +12 -1
  54. package/dist/agent-src/skills/skill-writing/SKILL.md +34 -570
  55. package/dist/agent-src/skills/skill-writing/references/procedure.md +275 -0
  56. package/dist/agent-src/skills/skill-writing/references/read-only-scripts.md +18 -0
  57. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +298 -0
  58. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  59. package/dist/agent-src/templates/roadmaps.md +65 -4
  60. package/dist/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  61. package/dist/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  62. package/dist/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  63. package/dist/cli/registry.js +2 -1
  64. package/dist/cli/registry.js.map +1 -1
  65. package/dist/cli-delegate/chunk-2GNWGMAL.js +172 -0
  66. package/dist/cli-delegate/{chunk-P6LQDIWK.js → chunk-7PRE6ZV2.js} +338 -0
  67. package/dist/cli-delegate/{chunk-BKO2AZ7Z.js → chunk-B2ERU2VA.js} +1 -1
  68. package/dist/cli-delegate/chunk-E4XIZDIB.js +402 -0
  69. package/dist/cli-delegate/{chunk-3UCJWMMP.js → chunk-EEJUMCDZ.js} +16 -16
  70. package/dist/cli-delegate/{chunk-NXFWFAYV.js → chunk-G23AT6GD.js} +1 -0
  71. package/dist/cli-delegate/{chunk-XURJ4AQC.js → chunk-H4VIVD4C.js} +385 -284
  72. package/dist/cli-delegate/chunk-I3EIN2YG.js +36 -0
  73. package/dist/cli-delegate/{chunk-RLN73PR5.js → chunk-LPPWO5CE.js} +12 -8
  74. package/dist/cli-delegate/chunk-MWRD5YOH.js +100 -0
  75. package/dist/cli-delegate/{chunk-UEZ7D35A.js → chunk-N7CDDGI3.js} +4 -23
  76. package/dist/cli-delegate/{chunk-63WSP6YZ.js → chunk-PMEKGDED.js} +74 -167
  77. package/dist/cli-delegate/{chunk-GRRPEPRN.js → chunk-T7L2QK3K.js} +24 -5
  78. package/dist/cli-delegate/{chunk-EVTY7ISR.js → chunk-YM4GZDJG.js} +9 -1
  79. package/dist/cli-delegate/cmd_adr_effective.js +1162 -0
  80. package/dist/cli-delegate/cmd_conformance.js +466 -716
  81. package/dist/cli-delegate/cmd_converge.js +3 -3
  82. package/dist/cli-delegate/cmd_doctor.js +10 -10
  83. package/dist/cli-delegate/cmd_explain.js +1 -1
  84. package/dist/cli-delegate/cmd_export.js +10 -9
  85. package/dist/cli-delegate/cmd_handoff.js +10 -9
  86. package/dist/cli-delegate/cmd_memory_get.js +2 -1
  87. package/dist/cli-delegate/cmd_migrate.js +2 -2
  88. package/dist/cli-delegate/cmd_packs_active.js +1 -1
  89. package/dist/cli-delegate/cmd_preflight.js +5 -5
  90. package/dist/cli-delegate/cmd_prune.js +11 -10
  91. package/dist/cli-delegate/cmd_route_audit.js +6 -5
  92. package/dist/cli-delegate/cmd_route_explain.js +3 -3
  93. package/dist/cli-delegate/cmd_session_recycle.js +840 -30
  94. package/dist/cli-delegate/cmd_settings_get.js +3 -3
  95. package/dist/cli-delegate/cmd_settings_migrate.js +10 -9
  96. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  97. package/dist/cli-delegate/cmd_sync.js +11 -10
  98. package/dist/cli-delegate/cmd_uninstall.js +13 -11
  99. package/dist/cli-delegate/cmd_update.js +4 -4
  100. package/dist/cli-delegate/cmd_upgrade.js +4 -4
  101. package/dist/cli-delegate/cmd_validate.js +11 -10
  102. package/dist/cli-delegate/cmd_versions.js +3 -3
  103. package/dist/discovery/deprecation-report.md +1 -1
  104. package/dist/discovery/discovery-manifest.json +111 -37
  105. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  106. package/dist/discovery/discovery-manifest.summary.md +5 -5
  107. package/dist/discovery/dormancy-report.md +1 -1
  108. package/dist/discovery/orphan-report.md +1 -1
  109. package/dist/discovery/packs.json +15 -12
  110. package/dist/discovery/trust-report.md +3 -3
  111. package/dist/discovery/workspaces.json +11 -8
  112. package/dist/hooks/dispatch.js +3165 -2192
  113. package/dist/install/claudePathsPlan.js +187 -0
  114. package/dist/install/claudePathsPlan.js.map +1 -0
  115. package/dist/install/globalRuleLayers.js +169 -0
  116. package/dist/install/globalRuleLayers.js.map +1 -0
  117. package/dist/install/hostLayerFingerprint.js +136 -0
  118. package/dist/install/hostLayerFingerprint.js.map +1 -0
  119. package/dist/install/install.mjs +553 -425
  120. package/dist/install/partitionEligibility.js +432 -0
  121. package/dist/install/partitionEligibility.js.map +1 -0
  122. package/dist/install/ruleLayerPartition.js +157 -0
  123. package/dist/install/ruleLayerPartition.js.map +1 -0
  124. package/dist/mcp/registry-manifest.json +3 -3
  125. package/dist/mcp/server.json +2 -2
  126. package/dist/mcp/server.mjs +1863 -1234
  127. package/dist/router.json +1 -1
  128. package/dist/scripts/_lib/agent_src.js +41 -0
  129. package/dist/scripts/_lib/agent_src.js.map +1 -1
  130. package/dist/scripts/_lib/install_layout.js +83 -0
  131. package/dist/scripts/_lib/install_layout.js.map +1 -0
  132. package/dist/scripts/_lib/installed_lock.js +444 -0
  133. package/dist/scripts/_lib/installed_lock.js.map +1 -0
  134. package/dist/scripts/_lib/prune_empty_dirs.js +85 -0
  135. package/dist/scripts/_lib/prune_empty_dirs.js.map +1 -0
  136. package/dist/scripts/condense.js +63 -251
  137. package/dist/scripts/condense.js.map +1 -1
  138. package/dist/server/schemas/settings.js +4 -0
  139. package/dist/server/schemas/settings.js.map +1 -1
  140. package/docs/contracts/settings-classes.md +12 -6
  141. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +8 -3
  142. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +45 -1
  143. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +26 -0
  144. package/docs/guidelines/agent-infra/false-green.md +47 -1
  145. package/docs/guidelines/agent-infra/memory-access.md +17 -0
  146. package/docs/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  147. package/package.json +1 -1
  148. package/src/agent-src/scripts/archival_sweep.ts +117 -0
  149. package/src/agent-src/scripts/archive_completed_roadmaps.ts +26 -7
  150. package/src/agent-src/scripts/dashboard_mode.ts +212 -0
  151. package/src/agent-src/scripts/gate_budget.ts +282 -0
  152. package/src/agent-src/scripts/gate_execute.ts +72 -31
  153. package/src/agent-src/scripts/roadmap_gates.ts +74 -3
  154. package/src/agent-src/scripts/update_roadmap_progress.ts +296 -53
  155. package/src/agent-src/templates/scripts/telemetry/flush_sender.mjs +163 -0
  156. package/src/agent-src/templates/scripts/telemetry/remote.ts +160 -7
  157. package/src/agent-src/templates/scripts/telemetry/transport.ts +169 -0
  158. package/src/config/agent-settings.template.yml +27 -2
  159. package/src/config/ci-local-parity.yml +39 -0
  160. package/src/config/estate-count-budget.json +612 -3
  161. package/src/config/evaluator-budgets.json +3 -3
  162. package/src/config/gate-coverage.yml +220 -12
  163. package/src/config/gate-violation-baselines.json +73 -63
  164. package/src/config/gitignore-block.txt +15 -2
  165. package/src/config/hook-latency-budget.json +5 -0
  166. package/src/config/rule-activation-census.json +14 -6
  167. package/src/config/rule-stub-ceilings.json +34 -7
  168. package/src/install/claudePathsPlan.ts +196 -0
  169. package/src/install/globalRuleLayers.ts +197 -0
  170. package/src/install/hostLayerFingerprint.ts +145 -0
  171. package/src/install/partitionEligibility.ts +502 -0
  172. package/src/install/ruleLayerPartition.ts +212 -0
  173. package/src/scripts/_cli/cmd_adr_effective.ts +484 -0
  174. package/src/scripts/_cli/cmd_session_recycle.ts +9 -1
  175. package/src/scripts/_dispatch.bash +17 -1
  176. package/src/scripts/_lib/ac_heading.ts +30 -0
  177. package/src/scripts/_lib/adr_frontmatter.test.ts +365 -0
  178. package/src/scripts/_lib/adr_frontmatter.ts +459 -0
  179. package/src/scripts/_lib/agent_src.ts +42 -0
  180. package/src/scripts/_lib/bench_ab_pinned_repo.ts +162 -0
  181. package/src/scripts/_lib/bench_ab_workspace.ts +10 -1
  182. package/src/scripts/_lib/envelope_grounding.ts +49 -9
  183. package/src/scripts/_lib/installed_lock.ts +50 -5
  184. package/src/scripts/_lib/layer_overlap_notice.ts +11 -2
  185. package/src/scripts/_lib/md_section.ts +129 -0
  186. package/src/scripts/_lib/prune_empty_dirs.ts +80 -0
  187. package/src/scripts/_lib/scope_guard.sh +26 -3
  188. package/src/scripts/_lib/self_repair.ts +19 -0
  189. package/src/scripts/_lib/self_repair_class_b.ts +171 -0
  190. package/src/scripts/adr/evidence_census.ts +899 -0
  191. package/src/scripts/adr/regenerate_index.ts +12 -32
  192. package/src/scripts/adr_cite_check.ts +540 -39
  193. package/src/scripts/ai_council/cli_help.ts +55 -0
  194. package/src/scripts/audit_adr_coverage.ts +103 -17
  195. package/src/scripts/before_complete_hook.ts +153 -28
  196. package/src/scripts/bench_ab_v2_complexity.ts +27 -7
  197. package/src/scripts/bench_hook_latency.ts +204 -0
  198. package/src/scripts/build_archive_index.ts +34 -0
  199. package/src/scripts/check_adr_frontmatter.ts +574 -39
  200. package/src/scripts/check_hook_bundle_content.ts +219 -0
  201. package/src/scripts/check_new_adr_evidence.ts +529 -0
  202. package/src/scripts/check_references.ts +78 -0
  203. package/src/scripts/check_release_published.ts +32 -11
  204. package/src/scripts/check_rule_layer_partition.ts +531 -0
  205. package/src/scripts/check_single_delivery.ts +194 -17
  206. package/src/scripts/check_standing_rule_delivery.ts +8 -2
  207. package/src/scripts/ci_settle.ts +170 -0
  208. package/src/scripts/condense.ts +79 -259
  209. package/src/scripts/council_cli.ts +3 -3
  210. package/src/scripts/dispatch_r2_reviewer.ts +6 -14
  211. package/src/scripts/external_sources_denylist.json +4 -1
  212. package/src/scripts/hook_manifest.json +1 -1
  213. package/src/scripts/hook_manifest.yaml +77 -14
  214. package/src/scripts/hooks/block_no_verify.ts +61 -10
  215. package/src/scripts/hooks/block_unauthorized_git.ts +21 -1
  216. package/src/scripts/hooks/concern_registry.ts +4 -0
  217. package/src/scripts/hooks/dispatch_hook.ts +154 -187
  218. package/src/scripts/hooks/dispatch_issues.ts +38 -19
  219. package/src/scripts/hooks/fallback_yaml.ts +66 -0
  220. package/src/scripts/hooks/host_semantics.ts +21 -0
  221. package/src/scripts/hooks/injection_budget.ts +13 -3
  222. package/src/scripts/hooks/py_json_dumps.ts +103 -0
  223. package/src/scripts/hooks/rtk_wrap_hook.ts +8 -3
  224. package/src/scripts/hooks/run_continuation_hook.ts +8 -5
  225. package/src/scripts/hooks/ship_diff_volume_hook.ts +81 -15
  226. package/src/scripts/hooks/source_first_gate_hook.ts +464 -0
  227. package/src/scripts/hooks/state_io.ts +870 -21
  228. package/src/scripts/hooks/stdin_failure_policy.ts +96 -0
  229. package/src/scripts/hooks/subagent_ledger_hook.ts +44 -15
  230. package/src/scripts/hooks/telemetry_flush_hook.ts +139 -0
  231. package/src/scripts/hooks/telemetry_self_repair.ts +128 -0
  232. package/src/scripts/hooks/telemetry_usage_hook.ts +22 -4
  233. package/src/scripts/hooks/turn_end_gate_hook.ts +81 -15
  234. package/src/scripts/injection_scan_hook.ts +137 -5
  235. package/src/scripts/install.ts +16 -11
  236. package/src/scripts/language_mirror_hook.ts +561 -25
  237. package/src/scripts/lint_framework_leakage_allowlist.json +2 -2
  238. package/src/scripts/lint_hook_manifest.ts +49 -0
  239. package/src/scripts/lint_plan_risk_register.ts +4 -3
  240. package/src/scripts/lint_provenance_vocabulary.ts +472 -4
  241. package/src/scripts/lint_skill_router_head.ts +4 -4
  242. package/src/scripts/mcp_server/tools.ts +2 -2
  243. package/src/scripts/new_roadmap.ts +136 -0
  244. package/src/scripts/pack_mcp_content.ts +20 -5
  245. package/src/scripts/release.ts +37 -38
  246. package/src/scripts/report_layer_overlap.ts +6 -0
  247. package/src/scripts/routing_doctor.ts +5 -1
  248. package/src/scripts/self_repair_hook.ts +37 -5
  249. package/src/scripts/session_register_hook.ts +11 -0
  250. package/src/scripts/skill_usage_collect.ts +11 -1
  251. package/src/scripts/skill_usage_report.ts +278 -8
  252. package/src/scripts/sync_pr_branch.ts +170 -20
  253. package/src/server/schemas/settings.ts +8 -0
  254. package/dist/cli-delegate/chunk-EJITJBJX.js +0 -172
  255. package/dist/cli-delegate/chunk-PZWRPRWP.js +0 -38
  256. package/dist/cli-delegate/{chunk-PPQO4NGR.js → chunk-6RJA2F5A.js} +3 -3
  257. package/dist/cli-delegate/{chunk-RYNADUFG.js → chunk-LWTYTX6F.js} +0 -0
  258. package/dist/cli-delegate/{chunk-FBKL6JWT.js → chunk-MMSGVZKV.js} +3 -3
@@ -0,0 +1,275 @@
1
+ # skill-writing — procedure
2
+
3
+ > Mode body of the [`skill-writing`](../SKILL.md) skill (router-head
4
+ > retrofit, 2026-08-20). Content moved VERBATIM from SKILL.md — load this
5
+ > file when the mode table in SKILL.md routes here.
6
+
7
+ ## Procedure
8
+
9
+ ### 0. Inspect, then run the Drafting Protocol
10
+
11
+ Before writing, **inspect** the landscape: grep
12
+ `src/skills/` and `src/rules/` for duplicates or
13
+ near-matches, and **analyze** 1–2 gold-standard peers (e.g. `pest-testing`,
14
+ `php-coder`) to anchor shape and tone. If requirements are unclear or
15
+ incomplete, stop and ask — do not assume.
16
+
17
+ Then run the Understand → Research → Draft sequence from the
18
+ [`artifact-drafting-protocol`](../../../rules/artifact-drafting-protocol.md)
19
+ rule. Skip only on explicit *"just do it"* bypass or trivial edits
20
+ (typo, link, single-line clarification).
21
+
22
+ ### 0b. Skill-growth gate (new skill only)
23
+
24
+ The skill count keeps climbing; nothing forces *"should this be a new skill at
25
+ all?"*. Before creating a **new** skill, answer these in the PR body — a new
26
+ skill that cannot answer them is a merge / guideline / no-op in disguise:
27
+
28
+ 1. **Family** — which capability family does it join? (engineering, product, …)
29
+ 2. **Capability** — what does it do that no existing skill does? Name the gap.
30
+ 3. **Why not extend / merge** — which nearest skill did you consider folding into, and why is a separate skill better?
31
+ 4. **Why not a guideline** — is this executable workflow (skill) or reference material (guideline)? Guideline-shaped content does not become a skill.
32
+ 5. **Visibility tier** — `core` or `lab`? Which pack?
33
+
34
+ **Surface overlap before deciding** — run `./scripts-run src/scripts/skill_overlap`
35
+ (or `audit_skill_overlap`) and read the nearest matches; a high-overlap hit is a
36
+ merge signal, not a green light. This gate is the authoring-time companion to the
37
+ [capability-boundary matrix](../../../../../docs/contracts/capability-boundary.md): the
38
+ matrix governs packs, this governs the skills inside them.
39
+
40
+ ### 1. Define the trigger
41
+
42
+ Write "When to use" first. This is the in-body trigger — it documents the
43
+ workflow's entry conditions for anyone reading the skill.
44
+
45
+ Good:
46
+ Use when creating Laravel middleware for request filtering
47
+
48
+ Bad:
49
+ Use when working with Laravel
50
+
51
+ ### 1b. Write a pushy frontmatter description
52
+
53
+ The `description:` field is what Claude reads at routing time. Polite or
54
+ generic descriptions cause **undertriggering**. Normative source:
55
+ `skill-quality` rule § *Description Triggering*.
56
+
57
+ Three rules: name 2+ triggers (domains, symptoms, user phrasing), end with
58
+ `... even if they don't explicitly ask for \`<skill-name>\`.`, and stay
59
+ **≤ 200 characters** (`skill_linter.ts` errors `description_too_long` above
60
+ that — a hard cap). When trimming to fit, drop adjectives or the second example phrasing
61
+ before you drop a trigger class or the `even if ...` tail.
62
+
63
+ Canonical before/after (2026-04-21 audit baseline):
64
+
65
+ ```yaml
66
+ # Bad (138 chars, polite, single trigger class):
67
+ description: "Use when writing Playwright E2E tests — browser automation,
68
+ visual regression testing, Page Objects, fixtures, and reliable test
69
+ patterns."
70
+
71
+ # Good (pushy, second trigger class, explicit tail):
72
+ description: "Use when writing Playwright E2E tests — locators, assertions,
73
+ Page Objects, fixtures, CI, and flaky test prevention — even if the user
74
+ doesn't say Playwright."
75
+ ```
76
+
77
+ The *good* version routes correctly on *"my E2E keeps flaking on CI"*
78
+ without naming Playwright. Run `./scripts-run src/scripts/audit_skill_descriptions`
79
+ after writing; if flagged `too-short` or `no-trigger-prefix`, rewrite
80
+ before commit.
81
+
82
+ When iterating on phrasing with the user (e.g. "make this pushier",
83
+ "will this ever fire"), delegate to the
84
+ [`description-assist`](../../description-assist/SKILL.md) skill — it runs the
85
+ approval-gated propose / pick loop with at most two rounds.
86
+
87
+ ### 1c. Propose a trigger-eval stub (new skills only)
88
+
89
+ When creating a new skill, propose a stub
90
+ `src/skills/{name}/evals/triggers.json` before writing
91
+ the body. Draw the queries from Phase A of the drafting protocol (the
92
+ user's "should trigger" and "must not trigger" answers).
93
+
94
+ Stub shape — 5 should-trigger + 5 should-not-trigger queries, first-person,
95
+ single-sentence, **no leakage of the skill name** in the queries:
96
+
97
+ ```json
98
+ {
99
+ "skill": "{name}",
100
+ "description": "5 should-trigger + 5 should-not-trigger queries. No query mentions '{name}' directly. Near-misses share domain vocabulary without being the actual task.",
101
+ "queries": [
102
+ {"q": "<phrasing from user Phase A that MUST route here>", "trigger": true},
103
+ {"q": "<another should-trigger phrasing>", "trigger": true},
104
+ {"q": "<...3 more>", "trigger": true},
105
+ {"q": "<near-miss sharing vocabulary but different task>", "trigger": false},
106
+ {"q": "<another near-miss>", "trigger": false},
107
+ {"q": "<...3 more>", "trigger": false}
108
+ ]
109
+ }
110
+ ```
111
+
112
+ Present the stub as a numbered-options prompt (per `user-interaction`):
113
+
114
+ ```
115
+ > 1. Accept stub as drafted — commit alongside the skill
116
+ > 2. Edit queries before commit
117
+ > 3. Skip evals for now — create later
118
+ ```
119
+
120
+ Nothing is committed without the user's pick. If the user picks *skip*,
121
+ record it in the commit message (`Eval stub: deferred`). Peer examples
122
+ for the expected format: `php-coder/evals/triggers.json`,
123
+ `eloquent/evals/triggers.json`, `skill-writing/evals/triggers.json`.
124
+
125
+ Presence is CI-enforced for new skills: `check_trigger_eval_presence`
126
+ fails any skill outside the shrink-only grandfather allowlist that
127
+ lacks `evals/triggers.json` — *skip* therefore defers the queries'
128
+ quality, never the file itself.
129
+
130
+ Rules / commands / guidelines do **not** get eval stubs — only skills
131
+ route through the top-level catalogue.
132
+
133
+ ### 2. Write the procedure
134
+
135
+ Use numbered, verifiable steps.
136
+
137
+ Good:
138
+
139
+ 1. Check if middleware exists
140
+ 2. Create with artisan command
141
+ 3. Implement logic
142
+ 4. Register in route or kernel
143
+
144
+ Bad:
145
+
146
+ 1. Create middleware
147
+ 2. Add logic
148
+
149
+ ### 3. Add validation
150
+
151
+ End with concrete validation.
152
+
153
+ Good:
154
+
155
+ * Route returns expected status
156
+ * Appears in route list
157
+ * No static analysis errors
158
+
159
+ Bad:
160
+
161
+ * Vague statements like "see if outcome is correct" (no concrete command or assertion)
162
+
163
+ ### 4. Add safe/unsafe example
164
+
165
+ Show minimal contrast.
166
+
167
+ Good:
168
+
169
+ * Typed middleware, correctly registered
170
+
171
+ Bad:
172
+
173
+ * Business logic inside middleware
174
+
175
+ ### 5. Define output format
176
+
177
+ Control response structure.
178
+
179
+ Example:
180
+
181
+ 1. Code snippet
182
+ 2. Registration location
183
+ 3. Gotcha (if relevant)
184
+
185
+ ### 6. Validate against quality checklist
186
+
187
+ * K1: Description is a trigger ("Use when...")
188
+ * K2: Not over-defined
189
+ * K3: No obvious content
190
+ * K4: Contains gotchas
191
+ * K5: Has Output format (numbered, 2-4 deliverables)
192
+ * K6: Not pointer-only (executable without opening guidelines)
193
+ * K7: Created with analysis (not blind, expected behavior defined)
194
+ * Size: Within limits (see size-and-scope guideline)
195
+
196
+ ### 7. Run + iterate evals (quantitative loop)
197
+
198
+ Triggers (`evals/triggers.json`) check **routing**. A separate
199
+ `evals/evals.json` checks **behavior** — does the skill make the agent
200
+ produce a better answer than baseline? Add this layer for any skill
201
+ where the procedure has measurable output (commands, artifacts,
202
+ structured text). Skip for evergreen heuristics with no falsifiable
203
+ output (e.g. `direct-answers`, `language-and-tone`) unless the user
204
+ asks for it.
205
+
206
+ **Workspace layout** (all under `.gitignore`):
207
+
208
+ ```
209
+ src/skills/{name}/evals/
210
+ triggers.json # tracked — routing eval (§ 1c)
211
+ evals.json # tracked — behavior eval definitions
212
+ runs/ # gitignored — per-iteration outputs
213
+ {timestamp}-baseline/ # sub-agent run without the skill
214
+ {timestamp}-with-skill/ # sub-agent run with the skill
215
+ {timestamp}-benchmark.json
216
+ ```
217
+
218
+ **`evals.json` shape** — 3–10 scenarios, each with prompt + grading
219
+ rubric:
220
+
221
+ ```json
222
+ {
223
+ "skill": "{name}",
224
+ "scenarios": [
225
+ {
226
+ "id": "happy-path",
227
+ "prompt": "<full user-shaped task that exercises the skill>",
228
+ "assertions": [
229
+ {"kind": "contains", "value": "<expected substring in output>"},
230
+ {"kind": "file_exists", "path": "<artifact path the skill should create>"},
231
+ {"kind": "rubric", "criterion": "<one-line judgement, e.g. 'output includes a numbered procedure'>"}
232
+ ]
233
+ }
234
+ ]
235
+ }
236
+ ```
237
+
238
+ `contains` / `file_exists` grade deterministically. `rubric` items grade
239
+ via a fresh sub-agent reading the output against the criterion — keep
240
+ each criterion to one falsifiable sentence.
241
+
242
+ **Loop** (orchestrated by `scripts/run_skill_evals.ts`):
243
+
244
+ 1. **Scaffold** — `./scripts-run src/scripts/run_skill_evals scaffold {skill}`
245
+ creates `runs/{timestamp}-{baseline,with-skill}/` and seeds each
246
+ scenario's `meta.json`.
247
+ 2. **Baseline run** — spawn one sub-agent per scenario **without** the
248
+ skill loaded. Capture stdout + any artifacts into
249
+ `runs/{timestamp}-baseline/{scenario-id}/`.
250
+ 3. **With-skill run** — same scenarios, same sub-agent harness, **with**
251
+ the skill loaded. Capture into `runs/{timestamp}-with-skill/{scenario-id}/`.
252
+ 4. **Grade** — for each scenario, write a `grade.json` file with
253
+ per-assertion pass/fail. Deterministic assertions auto-grade;
254
+ rubric assertions need a grader sub-agent.
255
+ 5. **Aggregate** — `./scripts-run src/scripts/run_skill_evals aggregate {skill}
256
+ --run {timestamp}` produces `runs/{timestamp}-benchmark.json` with
257
+ pass-rate, timing, token deltas baseline-vs-with-skill.
258
+ 6. **Report** — `./scripts-run src/scripts/run_skill_evals report {skill}
259
+ --run {timestamp}` prints the diff. Iterate on the skill body
260
+ until `with-skill` outperforms `baseline` on every scenario.
261
+
262
+ The script ships with sub-agent spawning **stubbed** — the orchestration
263
+ layer is per-environment (Claude Code, Augment, council). Implement
264
+ the spawn function once for your environment, the rest of the loop
265
+ (aggregate / report / scaffold) works out of the box.
266
+
267
+ **Exit criterion** — every scenario passes with-skill, at least one
268
+ fails baseline (proves the skill earns its slot). Commit the
269
+ `evals.json` alongside the skill; never commit `runs/`.
270
+
271
+ Neighbors:
272
+ * `description-assist` — iterate on the trigger phrasing
273
+ * `skill-reviewer` — structural 7-Killers audit
274
+ * `lint-skills` — static checks (frontmatter, sections, size)
275
+ * `skill-improvement-pipeline` — production-learning capture
@@ -0,0 +1,18 @@
1
+ # skill-writing — read-only-by-default scripts
2
+
3
+ > Mode body of the [`skill-writing`](../SKILL.md) skill (router-head
4
+ > retrofit, 2026-08-20). Content moved VERBATIM from SKILL.md — load this
5
+ > file when the mode table in SKILL.md routes here.
6
+
7
+ ## Read-only-by-default scripts
8
+
9
+ A script shipped inside a skill (`scripts/**`) is **side-effect-free by
10
+ default** — it inspects, computes, and prints; it does not mutate the
11
+ filesystem. Any mutation (writing a file, deleting, rename/copy) must be gated
12
+ behind an explicit flag named in this SKILL.md — `--writable` / `--apply` /
13
+ `--write` / `--output` / `--fix` — so the default invocation is safe to run
14
+ blind. A generator whose *declared purpose* is to write (it emits an artifact
15
+ to a caller-supplied path) is allowlisted with a rationale in
16
+ `src/scripts/lint_skill_scripts_readonly_allowlist.json` rather than carrying a
17
+ redundant flag. `lint_skill_scripts_readonly` enforces this: an ungated,
18
+ non-allowlisted write fails the build.
@@ -0,0 +1,298 @@
1
+ # skill-writing — section patterns
2
+
3
+ > Mode body of the [`skill-writing`](../SKILL.md) skill (router-head
4
+ > retrofit, 2026-08-20). Content moved VERBATIM from SKILL.md — load this
5
+ > file when the mode table in SKILL.md routes here.
6
+
7
+ ## Description-optimizer loop (U1 — held-out, not vibes)
8
+
9
+ Descriptions are the trigger surface; tune them like a model, not like prose:
10
+
11
+ 1. Draft 2-3 candidate descriptions for the skill.
12
+ 2. Ensure `evals/triggers.json` has should- AND should-not-trigger queries
13
+ (grow beyond the 5+5 stub when optimizing — more queries = a real test split).
14
+ 3. Run the helper: `npx tsx src/scripts/optimize_skill_description.ts
15
+ --skill <id> --candidate "…" [--candidate "…"] [--live]` — it splits the
16
+ queries deterministically into train/held-out, scores every candidate
17
+ (deterministic token-overlap proxy by default; `--live` = haiku judge,
18
+ ~$0.001 per query·candidate), and picks the best **held-out** accuracy.
19
+ 4. Adopt the pick ONLY if it beats the current description on the held-out
20
+ split — a train-only win is overfitting to the queries you wrote.
21
+
22
+ ## Self-QA loop for output-producing skills (optional pattern)
23
+
24
+ For skills whose product is a rendered/structural artifact (decks, docs,
25
+ diagrams, dashboards, generated UI): **assume there are problems** and have a
26
+ fresh-eyes pass find them before handing back. The author-context is blind to
27
+ its own omissions; a context-free verifier is not.
28
+
29
+ 1. Produce the artifact.
30
+ 2. Dispatch a fresh subagent (no authoring context) with ONLY the artifact +
31
+ the acceptance criteria: "list every visual/structural defect; assume at
32
+ least one exists."
33
+ 3. Fix what it finds; re-run once. Two clean passes → done.
34
+
35
+ Worked example (deck skill): the author renders 12 slides; the fresh-eyes
36
+ pass gets the PDF + "check overflow, contrast, orphaned bullets, broken
37
+ images" — it flags a clipped title on slide 7 the author never re-read.
38
+ One fix, one re-check, done.
39
+
40
+ Scope: complements `verify-before-complete` (which gates the completion
41
+ claim); this pattern is HOW to get the fresh evidence for artifacts where no
42
+ deterministic checker exists. Skip it when a real validator covers the
43
+ surface (linter, schema, test) — deterministic checks beat judge passes.
44
+
45
+ ## Known-pitfalls section (optional pattern, tool skills)
46
+
47
+ Tool/integration skills teach the happy path; the recurring support burden is
48
+ the *silent* failures — the ones that cost money, corrupt state, or fail with no
49
+ error. For a high-support-burden tool skill, add a `## Known pitfalls` section
50
+ in this micro-format:
51
+
52
+ 1. **A Symptom → Root cause → Fix table.** Each row starts from the *observable
53
+ symptom* (what the user sees), not the internal cause — the user greps for
54
+ the symptom, not the fix.
55
+
56
+ | Symptom | Root cause | Fix |
57
+ |---|---|---|
58
+ | `<what the user observes>` | `<why it happens>` | `<the concrete action>` |
59
+
60
+ 2. **Optionally, a quick-reference anti-pattern checklist** (Anti-pattern ·
61
+ cost/impact · fix difficulty) for traps worth scanning before shipping — add
62
+ it only when it does not restate the skill's existing `## Gotcha` / `## Do
63
+ NOT`; the table is the load-bearing part.
64
+
65
+ Sourcing floor — **real, not invented**: every entry names a genuinely common
66
+ failure (a high-vote community question, a documented incident class), never a
67
+ hypothetical. **≤ 5 entries per skill.** The value is a short, sourced,
68
+ high-signal list; a long one is noise. A pitfall is a *section on the existing
69
+ tool skill*, **never** a new skill per pitfall and never a generated grid (see
70
+ [`size-enforcement`](../../../rules/size-enforcement.md) § Per-tool pitfall
71
+ content).
72
+
73
+ ## Rationalizations-to-reject section (recommended pattern, security-stop-routed skills)
74
+
75
+ A skill routed by `security-sensitive-stop` already carries a forbidden-moves or
76
+ failure-mode list. Those describe **what is wrong**. They do not answer the
77
+ sentence the agent actually produces at the moment it skips the control:
78
+ *"this one is internal, so the tenant check is not needed here."*
79
+
80
+ So those skills add `## Rationalizations to reject`, where each entry is a pair:
81
+
82
+ - **the shortcut, in the words it will be argued in** — not a label. "It is an
83
+ internal endpoint" beats "insufficient authorization".
84
+ - **the mechanism that defeats it** — the concrete fact that makes the argument
85
+ wrong. "Internal is a network claim, not an identity claim; the object id
86
+ still comes from the request."
87
+
88
+ Writing the shortcut in its persuasive form is the whole point. A list of
89
+ labelled anti-patterns is matched against by a reader who has already decided;
90
+ a list of *arguments* is matched against by a reader mid-decision, which is when
91
+ the skip actually happens.
92
+
93
+ Keep it to the arguments that have really been made. An invented rationalization
94
+ teaches nothing and dilutes the ones that recur.
95
+
96
+ ## Non-negotiable-deliverable section (recommended pattern, adjacent-technology clusters)
97
+
98
+ Some skills sit next to a technology that is a *tempting wrong answer* — close
99
+ enough to look interchangeable, different enough that picking it silently loses
100
+ something. The framework-cluster skills the routing rules already disambiguate
101
+ pairwise are the standing example.
102
+
103
+ For those, state the deliverable as a constraint rather than as a preference:
104
+
105
+ 1. **What the output must use.** One sentence, unhedged.
106
+ 2. **The substitutes to refuse, named.** The agent will meet them; naming them
107
+ is what makes the refusal recognisable rather than a judgement call.
108
+ 3. **What each substitute loses.** This is the load-bearing line. A prohibition
109
+ without a cost reads as arbitrary and gets argued away the first time the
110
+ substitute is more convenient; a named loss survives that conversation.
111
+
112
+ The routing rules answer *which skill loads*. This section answers *what the
113
+ skill may emit once it has loaded* — a different question, and the one that goes
114
+ wrong quietly.
115
+
116
+ ## Destructive-operation gates belong in the description
117
+
118
+ If a skill performs an operation the user cannot undo — deleting, removing,
119
+ publishing, spending — the confirmation gate goes in the **description**, not
120
+ only in the body.
121
+
122
+ The reason is routing order: the description is what the agent reads when
123
+ choosing a skill, and the body loads afterwards. A gate stated only in the body
124
+ is invisible at exactly the moment the skill is being selected for a task whose
125
+ shape the gate might forbid.
126
+
127
+ One clause is enough — `worktree-lifecycle` carries "safe cleanup that refuses
128
+ while unique unmerged commits exist", which tells a router both what the skill
129
+ does and what it will not do. Verified by
130
+ `./scripts-run src/scripts/lint_skill_descriptions`.
131
+
132
+ ## Upstream-version-notes section (optional pattern, wrapped fast-moving tools)
133
+
134
+ A skill that wraps an external tool is written against one version of it. When
135
+ the tool renames a flag, restructures its report, or drops a subcommand, the
136
+ skill does not fail loudly — it fails as **the agent concluding the skill is
137
+ wrong**, or, worse, inventing the removed surface so its own instructions still
138
+ make sense. Both are silent.
139
+
140
+ For a skill wrapping a tool that moves faster than this package's release
141
+ cadence, add `## Upstream version notes` carrying exactly three things:
142
+
143
+ 1. **The version this skill was written against, and the date it was checked.**
144
+ A version alone rots into a claim nobody can date.
145
+ 2. **What was renamed** — old → new, one line each. This is the row that stops
146
+ an agent inventing a flag that no longer exists.
147
+ 3. **How to read older output** — the agent will meet reports from earlier
148
+ versions in logs, issues and fixtures, and needs to know which fields moved
149
+ rather than guessing.
150
+
151
+ State briefly what is **unchanged** too. "The subcommand set is unchanged since
152
+ X" is what lets an agent trust the rest of the skill after finding one stale
153
+ flag, instead of second-guessing every instruction that follows.
154
+
155
+ Scope floor — add it only where drift is **observed**, never anticipated. A
156
+ version-notes block on a stable tool is maintenance with no reader, and a stale
157
+ one is worse than none: it is a dated claim that is now false.
158
+
159
+ ## Security-constraints section (required pattern, script-bearing skills)
160
+
161
+ A skill that ships an executable script carries its constraints in the
162
+ always-loaded rules — `tool-safety`, `runtime-safety`, `lethal-trifecta-guard`.
163
+ That holds while the skill is read inside this suite. It stops holding the
164
+ moment the script travels: vendored into a consumer, copied into another
165
+ project, or run by an agent whose rule set is not ours. The constraints stay
166
+ behind; the script does not.
167
+
168
+ So a skill with anything under its `scripts/` directory states them **on the
169
+ artifact**, in a `## Security constraints` section:
170
+
171
+ - **What it may touch** — the paths and hosts it legitimately reads or writes.
172
+ Naming the boundary is what makes an overreach reviewable.
173
+ - **What it must never do** — the prohibitions specific to THIS script, not a
174
+ restatement of the general rules. "Never writes outside the target directory"
175
+ is checkable; "follows security best practice" is not.
176
+ - **Its default-invocation behaviour** — read-only or mutating. A script that
177
+ mutates on a bare invocation already violates the `## Do NOT` list below; if
178
+ it is gated behind a flag, name the flag here.
179
+ - **What it sends outbound, if anything** — the egress leg of the lethal
180
+ trifecta. A script with no network access says so in four words, and that
181
+ sentence is the cheapest possible answer to a reviewer's first question.
182
+
183
+ This duplicates the rules on purpose, and the duplication is the point: the
184
+ rules are the enforcement, the section is what survives the artifact leaving
185
+ their reach.
186
+
187
+ ## Action-reference split (required pattern, `safety_mode: strict` skills)
188
+
189
+ `execution.safety_mode: strict` says the skill's execution path may mutate
190
+ something. That is a claim made in the frontmatter, and until the body backs it
191
+ the claim costs nothing: a reader who follows the procedure top to bottom finds
192
+ the mutating step sitting inline with every other step, indistinguishable from a
193
+ read.
194
+
195
+ A strict skill therefore takes one of exactly two shapes, and says which:
196
+
197
+ - **Gate it inline.** The mutating step carries its precondition in the same
198
+ breath — propose the exact command first, `--dry-run` before the live run, the
199
+ user confirms, verify the effect landed afterwards. The precondition is part of
200
+ the step, never a general reassurance three sections away.
201
+ - **Defer it.** The SKILL.md states plainly that it **does not define the
202
+ mutating workflow**, and points the write-path steps at a file under the
203
+ skill's own `references/`. The pointer is the precondition's home: the
204
+ reference opens with what must be true before its first step runs.
205
+
206
+ Deferring is the better shape once the write path has more than a couple of
207
+ steps, and for the reason the split exists at all — the main body stays readable
208
+ as the thing an agent loads to decide *whether* to act, while the steps that
209
+ change something live behind one deliberate extra read. What it must never
210
+ become is a second copy: the reference holds the write path, the SKILL.md holds
211
+ the pointer, and neither restates the other.
212
+
213
+ `skill_linter` nudges (`strict_mode_missing_write_gate`, warning) when a strict
214
+ skill's body carries neither shape. It is a warning and it matches on prose, so
215
+ treat it as a prompt to check the body rather than a verdict on it — a skill that
216
+ gates its write path some third way is doing the right thing and should say so
217
+ plainly enough that the next reader sees the gate without running the linter.
218
+
219
+ Read with § Security-constraints above: that section states what the script may
220
+ touch, this one states what must be true before it touches it.
221
+
222
+ ## Mechanism-teaching section (optional pattern, skills whose subject has one)
223
+
224
+ A procedure tells the agent what to do in the cases you thought of. A
225
+ **mechanism** tells it why those steps work, which is the only thing that
226
+ transfers to the case you did not. Where a skill's subject has a mechanism worth
227
+ one screen — how the cascade resolves, why the queue drops the message, what the
228
+ scheduler actually orders — state it in a `## How it works` section, ahead of the
229
+ procedure that depends on it.
230
+
231
+ Keep it to one screen and to mechanisms only: no history, no alternatives-considered,
232
+ no restating the procedure in prose. If it takes more than a screen, the skill is
233
+ carrying a guideline's worth of material and should point at one instead.
234
+
235
+ The test for whether it earns its place: name a plausible situation the procedure
236
+ does not cover, and check whether this section is enough to answer it. If the
237
+ answer is still "read the source", the section is decoration.
238
+
239
+ Optional, and it gets no gate: "teaches a mechanism" is a prose judgement, and a
240
+ predicate over prose is the false-positive class this file's other patterns avoid.
241
+
242
+ ## Illustrative-not-verbatim marker (optional pattern, reference code)
243
+
244
+ A code block in a skill is read as copy-me by default. When a block is teaching a
245
+ *shape* — a signature to mirror, a structure to follow, pseudocode standing in for
246
+ the real call — say so on the line above it:
247
+
248
+ ```
249
+ <!-- illustrative: shape only, not a working snippet -->
250
+ ```
251
+
252
+ One line, immediately above the fence, in the skill's own words if you prefer.
253
+ What matters is that the reader can tell shape-teaching code from code that runs,
254
+ because the failure mode is silent: an agent pastes the illustration, it almost
255
+ works, and the debugging starts from the wrong premise.
256
+
257
+ The inverse deserves the same care — a block that IS meant to be run verbatim,
258
+ where a reader might assume otherwise, says so too. See also `### 4. Add
259
+ safe/unsafe example`, which governs a different axis: safe-vs-unsafe, not
260
+ runnable-vs-illustrative.
261
+
262
+ ## Headline metric + closing report (optional pattern, optimization skills)
263
+
264
+ A skill whose job is to make something better — smaller, faster, cheaper, quieter
265
+ — has to say **which single number it moves**. Without one, "optimized" is a
266
+ claim nobody can check and every run reports success.
267
+
268
+ So an optimization skill names, up front:
269
+
270
+ 1. **The headline metric.** One number, with its unit and how it is measured.
271
+ "Initial-context tokens, measured by `audit-tokens`" — not "context cost".
272
+ 2. **The closing report shape.** Before, after, delta, and the command that
273
+ produced both. The same command for both readings, or the delta is not a delta.
274
+
275
+ State what the metric does **not** capture, in one line. An optimization that
276
+ moves the headline number by degrading something it does not measure is the
277
+ failure this pattern exists to make visible, and only the author knows where that
278
+ edge is.
279
+
280
+ ## Contrastive-example slot (optional pattern, authoring and behaviour skills)
281
+
282
+ Where a skill's guidance is easy to agree with and hard to apply — tone, phrasing,
283
+ question shape, what counts as evidence — a wrong/right pair does what prose
284
+ cannot: it shows the near-miss. Six live corpora already carry them:
285
+ [`direct-answers-demos`](../../../../../docs/guidelines/agent-infra/direct-answers-demos.md),
286
+ [`asking-and-brevity-examples`](../../../../../docs/guidelines/agent-infra/asking-and-brevity-examples.md),
287
+ [`language-and-tone-examples`](../../../../../docs/guidelines/agent-infra/language-and-tone-examples.md),
288
+ and `autonomy-examples` / `interrupt-examples` / `cheap-question-mechanics` under
289
+ `src/agent-src/contexts/execution/`.
290
+
291
+ Follow one of those rather than inventing a format. The shape they share: the
292
+ **wrong** version first, in the form it actually gets written; the **right**
293
+ version second; and one line of **why** — which is the load-bearing part, because
294
+ a pair without it teaches the specific case and not the rule.
295
+
296
+ Put the corpus in a guideline or context file and point at it from the skill when
297
+ it outgrows a section. A near-miss corpus is reference material read on demand,
298
+ not always-loaded prose.
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "14.6.0"
42
+ agent_config_version: "14.8.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project: