@evomap/evolver 1.89.2 → 1.89.4

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 (110) hide show
  1. package/.cursor/BUGBOT.md +182 -0
  2. package/.env.example +68 -0
  3. package/.git-commit-guard-token +1 -0
  4. package/.github/CODEOWNERS +63 -0
  5. package/.github/ISSUE_TEMPLATE/good_first_issue.md +23 -0
  6. package/.github/pull_request_template.md +45 -0
  7. package/.github/workflows/test.yml +75 -0
  8. package/CHANGELOG.md +1237 -0
  9. package/README.ja-JP.md +1 -3
  10. package/README.ko-KR.md +1 -3
  11. package/README.md +86 -530
  12. package/README.public.md +569 -0
  13. package/README.zh-CN.md +1 -3
  14. package/SECURITY.md +108 -0
  15. package/assets/gep/events.jsonl +3 -0
  16. package/assets/gep/genes.json +496 -0
  17. package/examples/atp-consumer-quickstart.md +100 -0
  18. package/examples/hello-world.md +38 -0
  19. package/index.js +44 -48
  20. package/package.json +6 -17
  21. package/proxy-package.json +39 -0
  22. package/public.manifest.json +143 -0
  23. package/src/adapters/hookAdapter.js +2 -0
  24. package/src/adapters/scripts/_lockPaths.js +74 -0
  25. package/src/adapters/scripts/evolver-session-start.js +19 -27
  26. package/src/config.js +23 -0
  27. package/src/evolve/guards.js +721 -1
  28. package/src/evolve/pipeline/collect.js +1283 -1
  29. package/src/evolve/pipeline/dispatch.js +421 -1
  30. package/src/evolve/pipeline/enrich.js +440 -1
  31. package/src/evolve/pipeline/hub.js +319 -1
  32. package/src/evolve/pipeline/select.js +274 -1
  33. package/src/evolve/pipeline/signals.js +206 -1
  34. package/src/evolve/utils.js +264 -1
  35. package/src/evolve.js +350 -1
  36. package/src/experiment/agentRunner.js +229 -0
  37. package/src/experiment/cli.js +159 -0
  38. package/src/experiment/comparison.js +233 -0
  39. package/src/experiment/metrics.js +75 -0
  40. package/src/forceUpdate.js +311 -30
  41. package/src/gep/a2aProtocol.js +4455 -1
  42. package/src/gep/antiAbuseTelemetry.js +233 -0
  43. package/src/gep/autoDistillConv.js +205 -1
  44. package/src/gep/autoDistillLlm.js +315 -1
  45. package/src/gep/candidateEval.js +92 -1
  46. package/src/gep/candidates.js +198 -1
  47. package/src/gep/contentHash.js +30 -1
  48. package/src/gep/conversationSniffer.js +266 -1
  49. package/src/gep/crypto.js +89 -1
  50. package/src/gep/curriculum.js +163 -1
  51. package/src/gep/deviceId.js +218 -1
  52. package/src/gep/envFingerprint.js +118 -1
  53. package/src/gep/epigenetics.js +31 -1
  54. package/src/gep/execBridge.js +711 -1
  55. package/src/gep/explore.js +289 -1
  56. package/src/gep/hash.js +15 -1
  57. package/src/gep/hubFetch.js +359 -1
  58. package/src/gep/hubReview.js +207 -1
  59. package/src/gep/hubSearch.js +526 -1
  60. package/src/gep/hubVerify.js +306 -1
  61. package/src/gep/learningSignals.js +89 -1
  62. package/src/gep/memoryGraph.js +1374 -1
  63. package/src/gep/memoryGraphAdapter.js +203 -1
  64. package/src/gep/mutation.js +203 -1
  65. package/src/gep/narrativeMemory.js +108 -1
  66. package/src/gep/openPRRegistry.js +205 -1
  67. package/src/gep/personality.js +423 -1
  68. package/src/gep/policyCheck.js +599 -1
  69. package/src/gep/prompt.js +836 -1
  70. package/src/gep/recallInject.js +409 -1
  71. package/src/gep/recallVerifier.js +318 -1
  72. package/src/gep/reflection.js +177 -1
  73. package/src/gep/sanitize.js +9 -0
  74. package/src/gep/selector.js +602 -1
  75. package/src/gep/skillDistiller.js +1294 -1
  76. package/src/gep/solidify.js +1699 -1
  77. package/src/gep/strategy.js +136 -1
  78. package/src/gep/tokenSavings.js +88 -1
  79. package/src/gep/validator/sandboxExecutor.js +29 -1
  80. package/src/gep/workspaceKeychain.js +174 -1
  81. package/src/proxy/extensions/traceControl.js +99 -1
  82. package/src/proxy/index.js +14 -5
  83. package/src/proxy/inject.js +52 -1
  84. package/src/proxy/lifecycle/manager.js +30 -0
  85. package/src/proxy/mailbox/store.js +2 -1
  86. package/src/proxy/router/messages_route.js +13 -2
  87. package/src/proxy/trace/extractor.js +646 -1
  88. package/src/proxy/trace/usage.js +105 -1
  89. package/CONTRIBUTING.md +0 -19
  90. package/assets/cover.png +0 -0
  91. package/assets/gep/genes.seed.json +0 -245
  92. package/scripts/a2a_export.js +0 -63
  93. package/scripts/a2a_ingest.js +0 -79
  94. package/scripts/a2a_promote.js +0 -118
  95. package/scripts/analyze_by_skill.js +0 -121
  96. package/scripts/build_binaries.js +0 -479
  97. package/scripts/check-changelog.js +0 -166
  98. package/scripts/extract_log.js +0 -85
  99. package/scripts/generate_history.js +0 -75
  100. package/scripts/gep_append_event.js +0 -96
  101. package/scripts/gep_personality_report.js +0 -234
  102. package/scripts/human_report.js +0 -147
  103. package/scripts/recall-verify-report.js +0 -234
  104. package/scripts/recover_loop.js +0 -61
  105. package/scripts/seed-merchants.js +0 -91
  106. package/scripts/suggest_version.js +0 -89
  107. package/scripts/validate-modules.js +0 -38
  108. package/scripts/validate-suite.js +0 -78
  109. package/skills/index.json +0 -14
  110. /package/{skills → bundled-skills}/_meta/SKILL.md +0 -0
package/SECURITY.md ADDED
@@ -0,0 +1,108 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We support the latest minor version of `@evomap/evolver` on npm. Only the current release line receives security updates; older minor versions are not backported.
6
+
7
+ | Version | Supported |
8
+ | --------- | ------------------- |
9
+ | 1.67.x | Yes (current) |
10
+ | < 1.67 | No |
11
+
12
+ Run `npm view @evomap/evolver version` to check the latest published version.
13
+
14
+ ## Reporting a Vulnerability
15
+
16
+ Please do **not** open a public GitHub issue for security vulnerabilities. Instead, use one of the private channels below.
17
+
18
+ ### Preferred: GitHub Private Vulnerability Reporting
19
+
20
+ Submit a private report via:
21
+
22
+ https://github.com/EvoMap/evolver/security/advisories/new
23
+
24
+ This is the fastest and most secure channel. Only repository maintainers will see the report.
25
+
26
+ ### Alternative: Email
27
+
28
+ If you cannot use GitHub advisories, email `team@evomap.ai` with subject line `[SECURITY] evolver: <short title>`.
29
+
30
+ ### What to include
31
+
32
+ - A clear description of the vulnerability and its impact
33
+ - Affected version(s) and environment (OS, Node.js version)
34
+ - Steps to reproduce or a minimal proof-of-concept
35
+ - Any suggested mitigation or patch
36
+
37
+ ### What to expect
38
+
39
+ - **Acknowledgement**: within 48 hours of receipt
40
+ - **Initial assessment**: within 7 days (severity, affected versions, mitigation plan)
41
+ - **Fix timeline**: critical issues are targeted for a patch release within 14 days; lower severity follows the normal release cadence
42
+ - **Disclosure**: we practice coordinated disclosure. Once a fix is available, we publish a GitHub Security Advisory crediting the reporter (unless anonymity is requested)
43
+
44
+ ### Scope
45
+
46
+ In scope:
47
+
48
+ - `@evomap/evolver` npm package source code
49
+ - Default configuration and built-in protocols (GEP, A2A Proxy)
50
+ - Supply-chain risks (malicious dependencies, install scripts)
51
+
52
+ Out of scope:
53
+
54
+ - Vulnerabilities in the EvoMap Hub service itself -- please report those separately to `security@evomap.ai`
55
+ - Third-party LLM providers, user-authored genes, or user-generated content
56
+ - Social engineering and physical attacks
57
+
58
+ ## Threat model notes
59
+
60
+ ### Workspace-id same-uid readability (issue #111)
61
+
62
+ The per-workspace secret (`workspace-id`) authenticates a workspace to the
63
+ EvoMap Hub. There are two distinct attacker models for it:
64
+
65
+ - **Forgery / cross-workspace claim by a different uid** — closed in PR #109
66
+ (the FS file is created with `O_EXCL` + mode `0600`, and symlinks are
67
+ rejected).
68
+ - **Read by another process running under the *same* uid** — a same-uid
69
+ process can read `<workspace>/.evolver/workspace-id` off disk. Issue #111
70
+ Phase 1 added optional OS-keychain backing (`@napi-rs/keyring`) to close
71
+ this. The mode is selected by `EVOLVER_WORKSPACE_KEYCHAIN`
72
+ (`auto` default / `force` / `off`).
73
+
74
+ **What protection you actually get, by install path:**
75
+
76
+ | Install path | `@napi-rs/keyring` present? | Same-uid readability |
77
+ |---|---|---|
78
+ | `npm install -g @evomap/evolver` on **npm 7+** | Yes — optional deps install by default | Closed where the OS keychain backend is reachable |
79
+ | Same, but `--omit=optional` / `npm config set omit optional` / npm ≤ 6 | No | **Open** — secret stays on disk, FS-only |
80
+ | Headless Linux with no libsecret / D-Bus session | Addon loads but keychain unusable | **Open** — `auto` falls back to FS |
81
+ | Standalone bun-compiled binary (Phase 2 pending) | No — addon is `--external` and not yet sideloaded | **Open** — FS-only by design today |
82
+
83
+ A common misconception is that `optionalDependencies` are skipped by a
84
+ default `npm install`. That was true for npm 5/6; since **npm 7 (2020)**
85
+ optional dependencies are installed by default and must be opted *out* with
86
+ `--omit=optional`. So the modern `npm install -g` path **does** pull the
87
+ keyring and gets same-uid protection wherever a keychain backend exists.
88
+
89
+ Where the keychain is genuinely absent (the rows marked **Open** above),
90
+ `EVOLVER_WORKSPACE_KEYCHAIN=auto` transparently falls back to the FS secret —
91
+ identical to v1.85.x behaviour — and the workspace-id remains readable to any
92
+ same-uid process. To assert the keychain is in use (and fail loudly if it is
93
+ not), set `EVOLVER_WORKSPACE_KEYCHAIN=force`. Operators who do not want
94
+ keychain involvement at all can set `EVOLVER_WORKSPACE_KEYCHAIN=off`.
95
+
96
+ The same-uid threat is generally accepted for single-user developer machines
97
+ (any same-uid process already has broad access). It matters most on shared or
98
+ multi-tenant hosts where multiple workloads run under one service account.
99
+
100
+ ## Safe Harbor
101
+
102
+ Good-faith security research conducted under this policy is authorized. We will not pursue legal action against researchers who:
103
+
104
+ - Give us reasonable time to respond before public disclosure
105
+ - Avoid accessing data that does not belong to them
106
+ - Do not degrade service for other users
107
+
108
+ Thank you for helping keep the EvoMap ecosystem safe.
@@ -0,0 +1,3 @@
1
+ {"type": "EvolutionEvent", "schema_version": "1.6.0", "id": "evt_1776784060000", "parent": null, "intent": "optimize", "signals": ["skill_distillation", "skill2gep", "gene_authoring"], "genes_used": ["gene_skill2gep_gene_distill"], "mutation_id": null, "personality_state": null, "blast_radius": {"files": 2, "lines": 110}, "outcome": {"status": "success", "score": 0.88}, "capsule_id": "cap_20260421t150740_420781e4", "source_type": "skill2gep_distillation", "reused_asset_id": null, "env_fingerprint": {"os": "linux-6.1", "node": "22.22.0", "key_deps": {"skill2gep": "0.1.0"}}, "validation_report_id": "valrpt_1776784060000", "meta": {"at": "2026-04-21T15:07:40.000Z", "note": "first real execution: distilled ~/.cursor/skills/skill2gep/SKILL.md into 3 Genes (gene_distill, capsule_collect, publish_route). Validators exit=0, blast_radius=2/110.", "run_id": "run_skill2gep_self_distill_1"}}
2
+ {"type": "EvolutionEvent", "schema_version": "1.6.0", "id": "evt_1776784535635", "parent": "evt_1776784060000", "intent": "optimize", "signals": ["skill_distillation", "vercel_deploy", "ci_cd"], "genes_used": ["gene_skill2gep_gene_distill"], "mutation_id": null, "personality_state": null, "blast_radius": {"files": 2, "lines": 34}, "outcome": {"status": "success", "score": 0.86}, "capsule_id": "cap_20260421t150740_420781e4", "source_type": "skill2gep_distillation", "reused_asset_id": "sha256:bf3156da689e036fa96d1f20e6a2114b922e3122bfc37c6cd8b037b0789bc775", "env_fingerprint": {"os": "linux-6.1", "node": "22.22.0", "key_deps": {"skill2gep": "0.1.0"}}, "validation_report_id": "valrpt_1776784535635", "meta": {"at": "2026-04-21T15:15:35.000Z", "note": "second independent execution: distilled vercel/skills/deployments-cicd/SKILL.md into gene_vercel_deploy_cicd. validate_gene.js passed schema+dry-run, scenario replay accept against source Best Practices + Common Build Errors sections.", "run_id": "run_skill2gep_reuse_vercel_cicd"}}
3
+ {"type":"EvolutionEvent","schema_version":"1.6.0","id":"evt_1776818440_bundle3","parent":"evt_1776784535635","intent":"optimize","signals":["skill_distillation","skill2gep","vercel_ai_sdk"],"genes_used":["gene_skill2gep_gene_distill"],"capsule_id":"cap_20260421t150740_420781e4","mutation_id":"mut_skill2gep_run3","personality_state":{},"blast_radius":{"files":1,"lines":0},"outcome":{"status":"success","score":0.9},"reused_asset_id":"sha256:ce814505124e8320cf3cce13676364c892e04a62ef7a29308913495a38fb9237","validation_report_id":"valrpt_1776818440_bundle3","source_type":"skill2gep_distillation","env_fingerprint":{"os":"linux-6.1","node":"22.22.0","platform":"linux","arch":"x64","key_deps":{"skill2gep":"0.1.0"}},"meta":{"at":"2026-04-22T00:40:40.563Z","note":"bundle republish: capsule upgraded with full 7-step execution_trace + success_streak=2 to clear intent_drift. event records third run against vercel ai-sdk/SKILL.md.","run_id":"run_skill2gep_bundle_v2"},"asset_id":"sha256:60f7d29049c52775e3cce89fe27b0997322ffe3ba13063dd80f17fa5c0ab76c8"}
@@ -0,0 +1,496 @@
1
+ {
2
+ "version": 2,
3
+ "genes": [
4
+ {
5
+ "type": "Gene",
6
+ "id": "gene_gep_repair_from_errors",
7
+ "category": "repair",
8
+ "signals_match": [
9
+ "error|错误|异常|エラー|오류",
10
+ "exception|异常|例外|예외",
11
+ "failed|失败|失敗|실패|fail",
12
+ "unstable|不稳定|不安定|불안정",
13
+ "log_error",
14
+ "test_failure"
15
+ ],
16
+ "preconditions": [
17
+ "signals contains error-related indicators"
18
+ ],
19
+ "strategy": [
20
+ "Extract structured signals from logs and user instructions",
21
+ "Select an existing Gene by signals match (no improvisation)",
22
+ "Estimate blast radius (files, lines) before editing",
23
+ "Apply smallest reversible patch",
24
+ "Validate using declared validation steps; rollback on failure",
25
+ "Solidify knowledge: append EvolutionEvent, update Gene/Capsule store"
26
+ ],
27
+ "constraints": {
28
+ "max_files": 20,
29
+ "forbidden_paths": [
30
+ ".git",
31
+ "node_modules"
32
+ ]
33
+ },
34
+ "validation": [
35
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/selector ./src/gep/memoryGraph ./src/gep/assetStore",
36
+ "node scripts/validate-suite.js"
37
+ ]
38
+ },
39
+ {
40
+ "type": "Gene",
41
+ "id": "gene_gep_optimize_prompt_and_assets",
42
+ "category": "optimize",
43
+ "signals_match": [
44
+ "protocol|协议|プロトコル|프로토콜",
45
+ "gep",
46
+ "prompt|提示词|提示|プロンプト|프롬프트",
47
+ "audit|审计|監査|감사",
48
+ "reusable|可复用|再利用|재사용"
49
+ ],
50
+ "preconditions": [
51
+ "need stricter, auditable evolution protocol outputs"
52
+ ],
53
+ "strategy": [
54
+ "Extract signals and determine selection rationale via Selector JSON",
55
+ "Prefer reusing existing Gene/Capsule; only create if no match exists",
56
+ "Refactor prompt assembly to embed assets (genes, capsules, parent event)",
57
+ "Reduce noise and ambiguity; enforce strict output schema",
58
+ "Validate by running node index.js run and ensuring no runtime errors",
59
+ "Solidify: record EvolutionEvent, update Gene definitions, create Capsule on success"
60
+ ],
61
+ "constraints": {
62
+ "max_files": 20,
63
+ "forbidden_paths": [
64
+ ".git",
65
+ "node_modules"
66
+ ]
67
+ },
68
+ "validation": [
69
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/prompt ./src/gep/contentHash ./src/gep/skillDistiller",
70
+ "node scripts/validate-suite.js"
71
+ ]
72
+ },
73
+ {
74
+ "type": "Gene",
75
+ "id": "gene_gep_innovate_from_opportunity",
76
+ "category": "innovate",
77
+ "signals_match": [
78
+ "user_feature_request|功能请求|機能リクエスト|기능요청",
79
+ "user_improvement_suggestion|改进建议|改善提案|개선제안",
80
+ "perf_bottleneck|性能瓶颈|パフォーマンス|성능병목",
81
+ "capability_gap|能力缺口|機能ギャップ|역량공백",
82
+ "stable_success_plateau",
83
+ "external_opportunity|外部机会|外部機会|외부기회",
84
+ "bounty_task"
85
+ ],
86
+ "preconditions": [
87
+ "at least one opportunity signal is present",
88
+ "no active log_error signals (stability first)"
89
+ ],
90
+ "strategy": [
91
+ "Extract opportunity signals and identify the specific user need or system gap",
92
+ "Search existing Genes and Capsules for partial matches (avoid reinventing)",
93
+ "Design a minimal, testable implementation plan (prefer small increments)",
94
+ "Estimate blast radius; innovate changes may touch more files but must stay within constraints",
95
+ "Implement the change with clear validation criteria",
96
+ "Validate using declared validation steps; rollback on failure",
97
+ "Solidify: record EvolutionEvent with intent=innovate, create new Gene if pattern is novel, create Capsule on success"
98
+ ],
99
+ "constraints": {
100
+ "max_files": 25,
101
+ "forbidden_paths": [
102
+ ".git",
103
+ "node_modules"
104
+ ]
105
+ },
106
+ "validation": [
107
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/mutation ./src/gep/personality",
108
+ "node scripts/validate-suite.js"
109
+ ]
110
+ },
111
+ {
112
+ "type": "Gene",
113
+ "id": "gene_gep_optimize_tool_usage",
114
+ "summary": "Optimize tool execution patterns by reducing redundant exec calls, improving tool selection strategy, and enforcing tool-use constraints to prevent bypass.",
115
+ "category": "optimize",
116
+ "signals_match": [
117
+ "high_tool_usage:exec",
118
+ "repeated_tool_usage:exec",
119
+ "tool_bypass|工具绕过|ツール迂回|도구우회",
120
+ "tool_loop|工具循环|ツールループ|도구반복",
121
+ "high_tool_usage"
122
+ ],
123
+ "preconditions": [
124
+ "agent repeatedly invokes the same tool (especially exec) without progress",
125
+ "tool execution bypass patterns detected",
126
+ "no active error signals (errors would take repair priority)"
127
+ ],
128
+ "strategy": [
129
+ "Analyze tool usage patterns to identify the root cause of repetition (wrong tool, missing context, or lack of guardrails)",
130
+ "Introduce strategy-level guardrails: prefer single-shot commands, batch related operations, add explicit retry limits",
131
+ "If tool_bypass detected, strengthen constraint enforcement in prompt assembly or tool routing",
132
+ "Estimate blast radius; changes should target tool routing, prompt constraints, or signal deduplication logic",
133
+ "Validate by confirming no regressions in existing tool tests and signal extraction accuracy",
134
+ "Solidify: record EvolutionEvent with intent=optimize, update Capsule on success"
135
+ ],
136
+ "constraints": {
137
+ "max_files": 15,
138
+ "forbidden_paths": [
139
+ ".git",
140
+ "node_modules"
141
+ ]
142
+ },
143
+ "validation": [
144
+ "node scripts/validate-modules.js ./src/gep/signals ./src/evolve",
145
+ "node scripts/validate-suite.js"
146
+ ],
147
+ "routing_hint": {
148
+ "tier": "mid",
149
+ "reasoning_level": "medium"
150
+ }
151
+ },
152
+ {
153
+ "type": "Gene",
154
+ "id": "gene_distilled_s2g-env-vars",
155
+ "summary": "Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration.",
156
+ "category": "optimize",
157
+ "signals_match": [
158
+ "use_when_working_with",
159
+ "env_files",
160
+ "vercel_env_commands",
161
+ "oidc_tokens",
162
+ "vercel_env_pull",
163
+ "env_local_overwrite",
164
+ "oidc_token_expiry",
165
+ "dotenv_cli"
166
+ ],
167
+ "preconditions": [
168
+ "Skill env-vars has just been executed locally"
169
+ ],
170
+ "strategy": [
171
+ "Identify the dominant trigger signals from the Skill description.",
172
+ "Apply the smallest targeted change that satisfies the Skill workflow.",
173
+ "Run the Skill validation commands and abort if any fails."
174
+ ],
175
+ "constraints": {
176
+ "max_files": 12,
177
+ "forbidden_paths": [
178
+ ".git",
179
+ "node_modules"
180
+ ]
181
+ },
182
+ "validation": [
183
+ "node --version"
184
+ ],
185
+ "routing_hint": {
186
+ "tier": "cheap",
187
+ "reasoning_level": "low"
188
+ },
189
+ "schema_version": "1.6.0",
190
+ "_source": {
191
+ "kind": "skill2gep",
192
+ "skill_name": "env-vars",
193
+ "skill_platform": "vercel",
194
+ "skill_hash": "ba0bdb4db2",
195
+ "rationale_paper": "Wang, Ren, Zhang. From Procedural Skills to Strategy Genes. arXiv:2604.15097",
196
+ "paper_scope": "code-science (arXiv:2604.15097, 45 tasks, Gemini 3.1 Pro/Flash Lite)",
197
+ "claims_outside_scope": "assumption",
198
+ "quality_heuristics": {
199
+ "strategy_steps": 0,
200
+ "avoid_count": 0,
201
+ "validation_declared_count": 0,
202
+ "validation_runnable_count": 0,
203
+ "validation_fallback_used": true,
204
+ "signals_extracted": 4,
205
+ "preconditions_extracted": 0
206
+ }
207
+ },
208
+ "asset_id": "sha256:1501bc37fbefb18630c4dc8a95d8cdc1ed32bec4a465dc3223280ae907e07297"
209
+ },
210
+ {
211
+ "type": "Gene",
212
+ "id": "gene_tool_integrity",
213
+ "category": "repair",
214
+ "signals_match": [
215
+ "tool_bypass|工具绕过|ツール迂回|도구우회"
216
+ ],
217
+ "preconditions": [
218
+ "agent used shell/exec to perform an action that a registered tool can handle"
219
+ ],
220
+ "strategy": [
221
+ "Always prefer registered tools over ad-hoc scripts or shell workarounds",
222
+ "If a registered tool fails, report the actual error honestly and attempt to fix the root cause",
223
+ "Never fabricate explanations -- describe actual actions transparently",
224
+ "Do not create temporary scripts in extension or project directories"
225
+ ],
226
+ "constraints": {
227
+ "max_files": 4,
228
+ "forbidden_paths": [
229
+ ".git",
230
+ "node_modules"
231
+ ]
232
+ },
233
+ "validation": [
234
+ "node scripts/validate-suite.js"
235
+ ],
236
+ "anti_patterns": [
237
+ "tool_bypass"
238
+ ],
239
+ "routing_hint": {
240
+ "tier": "cheap",
241
+ "reasoning_level": "low"
242
+ }
243
+ },
244
+ {
245
+ "type": "Gene",
246
+ "id": "gene_publish_feishu_doc",
247
+ "category": "innovate",
248
+ "signals_match": [
249
+ "publish_markdown_to_feishu",
250
+ "create_feishu_doc",
251
+ "export_report_to_feishu",
252
+ "把结果发到飞书文档",
253
+ "发布飞书文档",
254
+ "把报告导出到飞书",
255
+ "publish results to a feishu doc",
256
+ "export notes to lark document",
257
+ "飞书文档",
258
+ "发布到飞书",
259
+ "导出到飞书",
260
+ "发到飞书",
261
+ "lark文档",
262
+ "飞书文档|lark doc|feishu doc"
263
+ ],
264
+ "strategy": [
265
+ "Verify the toolchain: run `lark-cli doctor` and require ok:true with at least one ready identity",
266
+ "Always use the Docs v2 API (v1 is deprecated): pass `--api-version v2`",
267
+ "Write the body as Lark-flavored Markdown to a temp file and pass `--content @file.md --doc-format markdown` to avoid shell-escaping bugs",
268
+ "Create with the user identity so the doc is human-owned: `lark-cli docs +create --api-version v2 --as user --doc-format markdown --content @file.md`",
269
+ "To place it in a folder or wiki add `--parent-token <token>` (use `--parent-position my_library` for the personal space)",
270
+ "Parse data.document.url from the JSON response and return it to the user; use `docs +update --api-version v2` with the document_id to amend instead of recreating"
271
+ ],
272
+ "validation": [
273
+ "node --version"
274
+ ],
275
+ "constraints": {
276
+ "max_files": 2,
277
+ "forbidden_paths": [
278
+ ".git",
279
+ "node_modules",
280
+ "~/.lark-cli/config.json"
281
+ ]
282
+ },
283
+ "preconditions": [
284
+ "lark-cli installed and on PATH (npm i -g @larksuite/cli)",
285
+ "lark-cli auth status reports a ready user or bot identity"
286
+ ],
287
+ "summary": "Publish Markdown content as a Feishu/Lark document via the official lark-cli (Docs v2). Use --as user for human-owned docs and @file content for long bodies; return the resulting document URL.",
288
+ "schema_version": "1.6.0",
289
+ "epigenetic_marks": [],
290
+ "learning_history": [],
291
+ "anti_patterns": [],
292
+ "routing_hint": null,
293
+ "tool_policy": null,
294
+ "avoid": [
295
+ "using the deprecated Docs v1 API or the v1 --markdown flag",
296
+ "passing long markdown inline (shell-escaping corrupts it) instead of --content @file",
297
+ "overwriting ~/.lark-cli/config.json (holds the app secret and tokens)"
298
+ ],
299
+ "asset_id": "sha256:9ed275fd6394567d0eb6c0fda45193bbeaba7bd84941ea4e75eb7fc859fb0dcf"
300
+ },
301
+ {
302
+ "type": "Gene",
303
+ "id": "gene_conventional_git_commit",
304
+ "category": "optimize",
305
+ "signals_match": [
306
+ "git_commit",
307
+ "create_commit",
308
+ "commit_changes",
309
+ "conventional_commit",
310
+ "提交代码",
311
+ "生成提交信息",
312
+ "write a commit message",
313
+ "stage and commit"
314
+ ],
315
+ "strategy": [
316
+ "Inspect the change: `git diff --staged` if anything is staged, else `git diff`, plus `git status --porcelain`",
317
+ "Pick a Conventional Commits type (feat/fix/docs/style/refactor/perf/test/build/ci/chore/revert) and optional scope from what actually changed",
318
+ "Stage logically-grouped files explicitly (git add <paths>); NEVER stage or commit secrets (.env, credentials, private keys)",
319
+ "Write a present-tense imperative description under 72 chars; add a body/footer for breaking changes (type! or BREAKING CHANGE:) and issue refs (Closes #N)",
320
+ "Commit one logical change with `git commit -m` (heredoc for multi-line)",
321
+ "Safety: never touch git config, never --force/hard-reset/--no-verify without explicit request, never force-push main; if a hook fails, fix and make a NEW commit (do not amend)"
322
+ ],
323
+ "validation": [
324
+ "node --version"
325
+ ],
326
+ "constraints": {
327
+ "max_files": 50,
328
+ "forbidden_paths": [
329
+ ".git",
330
+ "node_modules"
331
+ ]
332
+ },
333
+ "preconditions": [
334
+ "a git repository with staged or unstaged changes"
335
+ ],
336
+ "summary": "Create a Conventional Commits-style git commit: analyze the diff to pick type/scope, stage logical groups (never secrets), and write an imperative <72-char message.",
337
+ "schema_version": "1.6.0",
338
+ "epigenetic_marks": [],
339
+ "learning_history": [],
340
+ "anti_patterns": [],
341
+ "routing_hint": null,
342
+ "tool_policy": null,
343
+ "avoid": [
344
+ "committing secrets or unrelated changes in one commit",
345
+ "amending or force-pushing to bypass a failing hook",
346
+ "past-tense or vague messages like \"updated stuff\""
347
+ ],
348
+ "asset_id": "sha256:505c207b9984c397255daed61c5f24fb3bfcadedb803d2a4eaa429457f08cd2f"
349
+ },
350
+ {
351
+ "type": "Gene",
352
+ "id": "gene_poll_bugbot_review",
353
+ "category": "optimize",
354
+ "signals_match": [
355
+ "poll_bugbot",
356
+ "bugbot_review",
357
+ "wait_for_ci_review",
358
+ "pr_review_gate",
359
+ "等bugbot",
360
+ "等待评审",
361
+ "check bugbot",
362
+ "review the pr",
363
+ "pr opened"
364
+ ],
365
+ "strategy": [
366
+ "Poll the \"Cursor Bugbot\" check via `gh pr view --json statusCheckRollup` every ~60s until status=COMPLETED (cap ~10min); filter by name, not index",
367
+ "On SUCCESS: safe to merge ONLY if no other required check is red AND zero open inline comments from the cursor[bot] login (note the [bot] suffix)",
368
+ "On NEUTRAL: do NOT treat as pass — fetch inline comments `gh api repos/:o/:r/pulls/:n/comments` filtered to user.login==\"cursor[bot]\", surface path/line/severity, hand back to the human",
369
+ "On FAILURE/ACTION_REQUIRED: surface findings, do not merge",
370
+ "Auto-merge (squash + delete-branch) only when explicitly authorized AND conclusion is SUCCESS; merge conflicts/CI-red/required-review surface verbatim, never auto-fixed here"
371
+ ],
372
+ "validation": [
373
+ "node --version"
374
+ ],
375
+ "constraints": {
376
+ "max_files": 1,
377
+ "forbidden_paths": [
378
+ ".git",
379
+ "node_modules"
380
+ ]
381
+ },
382
+ "preconditions": [
383
+ "an open GitHub PR in a repo where Cursor Bugbot runs"
384
+ ],
385
+ "summary": "Wait for Cursor Bugbot on a GitHub PR, then gate on the conclusion: SUCCESS may merge, NEUTRAL/FAILURE always pauses to surface inline findings to the human.",
386
+ "schema_version": "1.6.0",
387
+ "epigenetic_marks": [],
388
+ "learning_history": [],
389
+ "anti_patterns": [],
390
+ "routing_hint": null,
391
+ "tool_policy": null,
392
+ "avoid": [
393
+ "treating NEUTRAL as pass (it has shipped real bugs before)",
394
+ "filtering comments on \"cursor\" instead of \"cursor[bot]\" (silently returns nothing)",
395
+ "auto-merging without explicit authorization or with CI red"
396
+ ],
397
+ "asset_id": "sha256:0f50f4cfecb0e6f3a9bd3c9c0a426e56f4f1c0230b4836a9471b38e499410ea9"
398
+ },
399
+ {
400
+ "type": "Gene",
401
+ "id": "gene_gateway_timeout_recovery",
402
+ "category": "repair",
403
+ "signals_match": [
404
+ "gateway_timeout",
405
+ "upstream_timeout",
406
+ "http_524",
407
+ "request_timed_out",
408
+ "超时了",
409
+ "网关超时",
410
+ "遇到超时",
411
+ "retry on timeout",
412
+ "operation timed out"
413
+ ],
414
+ "strategy": [
415
+ "Treat it as transient or size-driven, not a logic failure; do not report it as a hard failure before recovering",
416
+ "Retry the SAME operation verbatim exactly ONCE (a large fraction clear on immediate retry); do not loop",
417
+ "If it times out again, STOP retrying the monolith: split the work along a natural seam (per-file/dir/endpoint/record/section/time-window) into small independent units",
418
+ "Dispatch the units as parallel subagents in a single batch so each finishes under the gateway deadline; merge their results",
419
+ "If one unit itself times out, apply this same procedure recursively to that slice"
420
+ ],
421
+ "validation": [
422
+ "node --version"
423
+ ],
424
+ "constraints": {
425
+ "max_files": 1,
426
+ "forbidden_paths": [
427
+ ".git",
428
+ "node_modules"
429
+ ]
430
+ },
431
+ "preconditions": [
432
+ "a tool call / fetch / subagent / long command returned a gateway-class timeout (524/522/502/504)"
433
+ ],
434
+ "summary": "Recover from a gateway/upstream timeout: retry the same call once, and if it still times out, decompose the work into parallel subagents and merge — never loop the monolithic call.",
435
+ "schema_version": "1.6.0",
436
+ "epigenetic_marks": [],
437
+ "learning_history": [],
438
+ "anti_patterns": [],
439
+ "routing_hint": null,
440
+ "tool_policy": null,
441
+ "avoid": [
442
+ "retrying the same large call more than once",
443
+ "serial retries instead of parallel decomposition",
444
+ "surfacing the timeout as a hard failure before recovering"
445
+ ],
446
+ "asset_id": "sha256:63c4251dcd8308030194f797051c08672691b52553e00b0eb33772c215712acc"
447
+ },
448
+ {
449
+ "type": "Gene",
450
+ "id": "gene_github_webhook_listener",
451
+ "category": "innovate",
452
+ "signals_match": [
453
+ "github_webhook_listener",
454
+ "bugbot_webhook",
455
+ "passive_pr_notifications",
456
+ "设置webhook",
457
+ "部署webhook监听",
458
+ "notify when bugbot finishes",
459
+ "webhook tunnel"
460
+ ],
461
+ "strategy": [
462
+ "Run the idempotent deploy: a loopback Python listener (127.0.0.1:8644) validating GitHub X-Hub-Signature-256 HMAC via hmac.compare_digest, writing vetted payloads to ~/.claude/inbox/",
463
+ "Expose it via a cloudflared quick tunnel (outbound-only, no inbound port); a path-watcher re-PATCHes the GitHub webhook config whenever the tunnel URL changes",
464
+ "Keep listener + tunnel alive with systemd --user units hardened (ProtectSystem=strict, NoNewPrivileges, MemoryDenyWriteExecute); a SessionStart hook drains the inbox and re-validates PR state via gh api before surfacing",
465
+ "Security invariants: HMAC on every request, X-GitHub-Delivery dedup against replay, write-only sink (never exec/template/deserialize payload), file modes secret 0600 / inbox 0700",
466
+ "Add repos with deploy.sh --repos; rotate the secret every 90 days (rotate-secret.sh) and immediately on any leak; never trust the inbox payload without re-fetching"
467
+ ],
468
+ "validation": [
469
+ "node --version"
470
+ ],
471
+ "constraints": {
472
+ "max_files": 20,
473
+ "forbidden_paths": [
474
+ ".git",
475
+ "node_modules"
476
+ ]
477
+ },
478
+ "preconditions": [
479
+ "a developer machine with systemd --user and cloudflared available"
480
+ ],
481
+ "summary": "Deploy a per-developer GitHub webhook listener (HMAC-validated, cloudflared tunnel, systemd-kept) that drops PR/Bugbot events into ~/.claude/inbox for the next session to surface.",
482
+ "schema_version": "1.6.0",
483
+ "epigenetic_marks": [],
484
+ "learning_history": [],
485
+ "anti_patterns": [],
486
+ "routing_hint": null,
487
+ "tool_policy": null,
488
+ "avoid": [
489
+ "opening an inbound port instead of an outbound cloudflared tunnel",
490
+ "trusting the webhook payload without HMAC validation and PR re-fetch",
491
+ "execing or deserializing anything from the payload"
492
+ ],
493
+ "asset_id": "sha256:ac2a2f185390aef37996651ef21355f4beb437049e52a6ca3898619a8d648084"
494
+ }
495
+ ]
496
+ }