@evomap/evolver 1.89.3 → 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 (104) 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.md +86 -528
  10. package/README.public.md +569 -0
  11. package/SECURITY.md +108 -0
  12. package/assets/gep/events.jsonl +3 -0
  13. package/examples/atp-consumer-quickstart.md +100 -0
  14. package/examples/hello-world.md +38 -0
  15. package/index.js +30 -1
  16. package/package.json +6 -17
  17. package/proxy-package.json +39 -0
  18. package/public.manifest.json +143 -0
  19. package/src/config.js +23 -0
  20. package/src/evolve/guards.js +721 -1
  21. package/src/evolve/pipeline/collect.js +1283 -1
  22. package/src/evolve/pipeline/dispatch.js +421 -1
  23. package/src/evolve/pipeline/enrich.js +440 -1
  24. package/src/evolve/pipeline/hub.js +319 -1
  25. package/src/evolve/pipeline/select.js +274 -1
  26. package/src/evolve/pipeline/signals.js +206 -1
  27. package/src/evolve/utils.js +264 -1
  28. package/src/evolve.js +350 -1
  29. package/src/experiment/agentRunner.js +229 -0
  30. package/src/experiment/cli.js +159 -0
  31. package/src/experiment/comparison.js +233 -0
  32. package/src/experiment/metrics.js +75 -0
  33. package/src/forceUpdate.js +147 -59
  34. package/src/gep/a2aProtocol.js +4455 -1
  35. package/src/gep/antiAbuseTelemetry.js +233 -0
  36. package/src/gep/autoDistillConv.js +205 -1
  37. package/src/gep/autoDistillLlm.js +315 -1
  38. package/src/gep/candidateEval.js +92 -1
  39. package/src/gep/candidates.js +198 -1
  40. package/src/gep/contentHash.js +30 -1
  41. package/src/gep/conversationSniffer.js +266 -1
  42. package/src/gep/crypto.js +89 -1
  43. package/src/gep/curriculum.js +163 -1
  44. package/src/gep/deviceId.js +218 -1
  45. package/src/gep/envFingerprint.js +118 -1
  46. package/src/gep/epigenetics.js +31 -1
  47. package/src/gep/execBridge.js +711 -1
  48. package/src/gep/explore.js +289 -1
  49. package/src/gep/hash.js +15 -1
  50. package/src/gep/hubFetch.js +359 -1
  51. package/src/gep/hubReview.js +207 -1
  52. package/src/gep/hubSearch.js +526 -1
  53. package/src/gep/hubVerify.js +306 -1
  54. package/src/gep/learningSignals.js +89 -1
  55. package/src/gep/memoryGraph.js +1374 -1
  56. package/src/gep/memoryGraphAdapter.js +203 -1
  57. package/src/gep/mutation.js +203 -1
  58. package/src/gep/narrativeMemory.js +108 -1
  59. package/src/gep/openPRRegistry.js +205 -1
  60. package/src/gep/personality.js +423 -1
  61. package/src/gep/policyCheck.js +599 -1
  62. package/src/gep/prompt.js +836 -1
  63. package/src/gep/recallInject.js +409 -1
  64. package/src/gep/recallVerifier.js +318 -1
  65. package/src/gep/reflection.js +177 -1
  66. package/src/gep/sanitize.js +9 -0
  67. package/src/gep/selector.js +602 -1
  68. package/src/gep/skillDistiller.js +1294 -1
  69. package/src/gep/solidify.js +1699 -1
  70. package/src/gep/strategy.js +136 -1
  71. package/src/gep/tokenSavings.js +88 -1
  72. package/src/gep/validator/sandboxExecutor.js +29 -1
  73. package/src/gep/workspaceKeychain.js +174 -1
  74. package/src/proxy/extensions/traceControl.js +99 -1
  75. package/src/proxy/index.js +10 -1
  76. package/src/proxy/inject.js +52 -1
  77. package/src/proxy/lifecycle/manager.js +19 -0
  78. package/src/proxy/mailbox/store.js +2 -1
  79. package/src/proxy/router/messages_route.js +5 -2
  80. package/src/proxy/trace/extractor.js +646 -1
  81. package/src/proxy/trace/usage.js +105 -1
  82. package/CONTRIBUTING.md +0 -19
  83. package/assets/cover.png +0 -0
  84. package/scripts/a2a_export.js +0 -63
  85. package/scripts/a2a_ingest.js +0 -79
  86. package/scripts/a2a_promote.js +0 -118
  87. package/scripts/analyze_by_skill.js +0 -121
  88. package/scripts/build_binaries.js +0 -479
  89. package/scripts/check-changelog.js +0 -166
  90. package/scripts/extract_log.js +0 -85
  91. package/scripts/generate_history.js +0 -75
  92. package/scripts/gep_append_event.js +0 -96
  93. package/scripts/gep_personality_report.js +0 -234
  94. package/scripts/human_report.js +0 -147
  95. package/scripts/recall-verify-report.js +0 -234
  96. package/scripts/recover_loop.js +0 -61
  97. package/scripts/refresh_stars_badge.js +0 -168
  98. package/scripts/seed-merchants.js +0 -91
  99. package/scripts/suggest_version.js +0 -89
  100. package/scripts/validate-modules.js +0 -38
  101. package/scripts/validate-suite.js +0 -78
  102. package/skills/index.json +0 -14
  103. /package/assets/gep/{genes.seed.json → genes.json} +0 -0
  104. /package/{skills → bundled-skills}/_meta/SKILL.md +0 -0
@@ -0,0 +1,182 @@
1
+ # Bugbot Review Rules — evolver-private-dev
2
+
3
+ This file gives Cursor Bugbot project-specific context. The repository is the
4
+ **private source of truth** for `@evomap/evolver`; the public mirror is
5
+ `EvoMap/evolver`, built via `scripts/build_public.js` driven by
6
+ `public.manifest.json`. Treat anything that could leak from private to public,
7
+ or that could break GEP asset integrity, as high severity.
8
+
9
+ ## Project shape
10
+
11
+ - Pure Node.js (no TypeScript). Public surface is the npm package
12
+ `@evomap/evolver`; entry point is `index.js`.
13
+ - Runtime dependencies are intentionally minimal — only `dotenv`. Do not
14
+ approve PRs that add new runtime dependencies without a clear justification
15
+ in the PR description.
16
+ - Tests run via `node --test`. There is no ESLint/Prettier in CI; rely on
17
+ Bugbot to catch style and correctness regressions.
18
+
19
+ ## High-severity rules (block the PR)
20
+
21
+ ### 1. Secrets must round-trip through `src/gep/sanitize.js`
22
+
23
+ Any code path that writes capsule payloads, agent logs, prompts, or hub
24
+ broadcasts must call `sanitizePayload` (or an equivalent redactor) **before**
25
+ the data leaves the process. Flag as a blocking Bug if a PR:
26
+
27
+ - Logs raw `process.env.*`, request headers, or `Authorization` values.
28
+ - Sends capsule/event/log objects to `src/gep/bridge.js`,
29
+ `src/gep/a2aProtocol.js`, `src/gep/issueReporter.js`, `src/proxy/sync/**`,
30
+ or any HTTP/IPC sink without first running `sanitizePayload`.
31
+ - Adds a new secret pattern (API key, token, private key) that is not also
32
+ added to `REDACT_PATTERNS` in `sanitize.js`.
33
+
34
+ ### 2. Public/private leak prevention
35
+
36
+ `scripts/build_public.js` + `public.manifest.json` decide what ships to the
37
+ public repo and to npm. Block PRs that:
38
+
39
+ - Add a new top-level path that is **not** covered by either `include` or
40
+ `exclude` in `public.manifest.json`. New private-only paths (docs/,
41
+ memory/, internal scripts) must be added to `exclude`.
42
+ - Add `console.log` / TODO / FIXME / internal URLs / employee emails inside
43
+ files listed in the `obfuscate` array — those files are shipped after
44
+ obfuscation and any plaintext secret/comment leaks past obfuscation.
45
+ - Reference `EvoMap/evolver-private-dev` (this repo's URL) inside any file
46
+ that is part of the public include set.
47
+ - **Add a new file under `src/gep/**` or `src/evolve/**` (or any directory
48
+ whose siblings are already in the `obfuscate` array) without also adding
49
+ the new file to `obfuscate`.** Sibling consistency is the rule: if every
50
+ other `*.js` in the same directory is obfuscated, the new one must be
51
+ too. Exception: the PR description must explicitly state why obfuscation
52
+ is unnecessary (e.g. "trivial public algorithm reused from MIT-licensed
53
+ source") AND the file must contain no business logic, no env-var reads,
54
+ and no path/URL constants. Historical regressions: PR #20 (hub.js,
55
+ enrich.js, utils.js missed obfuscate, fixed in 79821fc and 3da07e3),
56
+ PR #34 (hash.js missed obfuscate).
57
+
58
+ **This file is private-only.** `.cursor/BUGBOT.md` is private to this repo
59
+ and is pruned from the public build via `public.manifest.json`'s
60
+ `exclude: [".cursor/**"]`. Project-specific rules for the public mirror
61
+ `EvoMap/evolver` (if any are needed) live in the Cursor dashboard's
62
+ repository manual rules, not in the source tree, so the published npm
63
+ package and the public GitHub repo do not carry editor-tool config files.
64
+
65
+ ### 3. GEP asset integrity
66
+
67
+ The GEP protocol depends on stable hashing and signatures
68
+ (`src/gep/contentHash.js`, `src/gep/crypto.js`, `src/gep/integrityCheck.js`).
69
+ Block PRs that:
70
+
71
+ - Change `contentHash` / `crypto.sign` / `crypto.verify` behaviour without an
72
+ explicit version bump and a migration path for existing
73
+ `assets/gep/*.jsonl` records.
74
+ - Mutate gene/capsule/event objects in-place after they have been hashed or
75
+ signed.
76
+ - Introduce non-deterministic ordering (e.g. `Object.keys` without sort, or
77
+ `for ... in`) inside any code that participates in hashing.
78
+ - **Ship a schema factory (e.g. `createGene` / `createCapsule` / `createTask`,
79
+ or any new `src/gep/schemas/<X>.js`) without proving the matching
80
+ `validate<X>` is actually called on every write/publish path.** A schema
81
+ that no one calls is dead code that masks LLM/Hub-supplied garbage.
82
+ Require the PR description to include a `grep -rn 'validate<X>' src/`
83
+ output covering at least: every `upsert<X>` / `append<X>` in
84
+ `src/gep/assetStore.js`, every `buildPublish<X>*` in
85
+ `src/gep/a2aProtocol.js`, and every direct disk-write site. Historical
86
+ regression: PR #25 / #27 shipped `validateGene` / `validateCapsule` that
87
+ no caller invoked, fixed retroactively as audit issue #30 H1 (commit
88
+ 902a256). Track the same expectation for any future `validate<Y>`.
89
+ - **Spread `DEFAULTS` into a partial without slicing every reference-typed
90
+ field afterwards.** `Object.assign({}, X_DEFAULTS, partial)` is a shallow
91
+ copy: arrays and sub-objects on the result still point to either
92
+ `X_DEFAULTS`'s shared instance or to `partial`'s caller-owned
93
+ instance. Downstream `.push(...)` then contaminates every other consumer.
94
+ Every array field needs `Array.isArray(x) ? x.slice() : []`; every
95
+ sub-object needs `Object.assign({}, FIELD_DEFAULTS, x)`. Historical
96
+ regression: PR #25 createGene leaked `epigenetic_marks` /
97
+ `learning_history` / `anti_patterns` / `constraints.forbidden_paths`
98
+ across all genes (commit 549f1bd).
99
+
100
+ ### 4. Filesystem and network safety
101
+
102
+ - Reject `child_process.exec*` / `spawn*` calls that interpolate untrusted
103
+ strings into the command. Use the array form with explicit args.
104
+ - Reject `fs.writeFileSync` / `fs.rmSync({recursive:true})` calls that
105
+ resolve paths from user/LLM input without going through `src/gep/paths.js`
106
+ or an equivalent allowlist.
107
+ - Reject HTTP fetches that disable TLS verification
108
+ (`rejectUnauthorized: false`, `NODE_TLS_REJECT_UNAUTHORIZED=0`) outside
109
+ isolated test fixtures.
110
+
111
+ ## Medium-severity rules (request changes)
112
+
113
+ ### Async correctness
114
+
115
+ - Every Promise must either be `await`ed or have a `.catch` handler. Flag
116
+ unhandled-rejection risks.
117
+ - Do not mix `await` with `.then(...)` chains inside the same logical block.
118
+ - Long-running loops in `src/proxy/**` must respect the existing cancellation
119
+ / shutdown signals (look for `idleScheduler.js`, `lifecycle/**`).
120
+
121
+ ### Module-load ordering vs. dotenv
122
+
123
+ `src/evolve.js` calls `require('dotenv').config(...)` mid-file (around
124
+ the comment block "Load environment variables from repo root"). Any module
125
+ that reads `process.env.X` at module-load time (e.g.
126
+ `const FOO = process.env.FOO || default` at the top of the file) MUST be
127
+ required AFTER the `dotenv.config()` call, otherwise `process.env.X` is
128
+ empty and the constant freezes to the default for the rest of the process
129
+ lifetime. Block PRs that:
130
+
131
+ - Add a new module-level `const`/`let` initialized from `process.env.*` and
132
+ hoist its `require(...)` above the `dotenv.config()` call in `evolve.js`,
133
+ `index.js`, or any new top-level entry point.
134
+ - Re-introduce eager `require('./evolve/pipeline/<X>')` at the top of
135
+ `src/evolve.js`. The current pattern requires those modules AFTER dotenv;
136
+ see commit 3da07e3 for context.
137
+
138
+ A safe pattern when a module truly needs env at module-load time: read the
139
+ env via `src/config.js`'s `envInt()` / `envStr()` helpers, which are
140
+ re-evaluated lazily on each call instead of frozen at module load.
141
+
142
+ ### CLI compatibility
143
+
144
+ `index.js` is the public CLI binary. Any change to CLI flags, default
145
+ behaviour, exit codes, or stdout/stderr format is a breaking change for
146
+ downstream users. Require:
147
+
148
+ - A note in `CHANGELOG.md` describing the user-visible change.
149
+ - Backwards-compatible behaviour behind a feature flag in
150
+ `src/gep/featureFlags.js` whenever possible.
151
+
152
+ ### Node version
153
+
154
+ `package.json` does not currently pin an `engines` field. The package is
155
+ distributed as a CLI to end users on a wide range of Node versions. Treat
156
+ Node.js >= 18 as the de-facto floor and flag use of APIs that require Node
157
+ 20+ (e.g. `fs.glob`, top-level `using`, `--experimental-strip-types`) unless
158
+ the PR also adds an `engines.node` constraint to `package.json` and notes
159
+ the bump in `CHANGELOG.md`.
160
+
161
+ ## Low-severity rules (nit / suggestion)
162
+
163
+ - Use `node:` prefix for built-in module imports (`require('node:fs')`).
164
+ - Prefer named functions over anonymous arrow functions when registering
165
+ event listeners — eases stack traces.
166
+ - Avoid `JSON.stringify(...)` of large objects in hot paths inside
167
+ `src/proxy/server/**`; prefer streaming or pagination.
168
+
169
+ ## Context Bugbot should NOT flag
170
+
171
+ - The lack of TypeScript or ESLint config — intentional.
172
+ - Single-dependency `package.json` — intentional minimal supply chain.
173
+ - Files under `assets/gep/*.jsonl` are gitignored; if a PR appears to add
174
+ them, that is a **block**, not a nit (see rule 2).
175
+ - The `dist-public/` and `dist-binaries/` directories are build artifacts —
176
+ do not review them.
177
+
178
+ ## Style
179
+
180
+ This repository forbids emoji in code, comments, commit messages, and
181
+ documentation, with a single allowed exception: the DNA glyph used in
182
+ public-facing docs. Flag any PR that adds other emoji.
package/.env.example ADDED
@@ -0,0 +1,68 @@
1
+ # EvoMap Hub connection (optional -- all core features work offline without these)
2
+ # A2A_HUB_URL=https://evomap.ai
3
+ # A2A_NODE_ID=your_node_id_here
4
+
5
+ # Evolution strategy: balanced (default) | innovate | harden | repair-only
6
+ # EVOLVE_STRATEGY=balanced
7
+
8
+ # Bridge mode: controls sessions_spawn() output for host runtimes like OpenClaw.
9
+ # Defaults to off unless OPENCLAW_WORKSPACE is set.
10
+ # EVOLVE_BRIDGE=false
11
+
12
+ # Heartbeat interval in milliseconds (default: 360000 = 6 minutes)
13
+ # HEARTBEAT_INTERVAL_MS=360000
14
+
15
+ # Worker pool: set to 1 to participate as a worker in the EvoMap network
16
+ # WORKER_ENABLED=1
17
+ # WORKER_DOMAINS=repair,harden
18
+ # WORKER_MAX_LOAD=5
19
+
20
+ # Path overrides (usually auto-detected)
21
+ # MEMORY_DIR=./memory
22
+ # EVOLVER_REPO_ROOT=.
23
+ # OPENCLAW_WORKSPACE=
24
+ # When evolver runs as an npm dependency or a skill under a host repo,
25
+ # it auto-detects the host's .git so it can see Hand Agent edits.
26
+ # Set this to 'true' only if you deliberately want evolver to ignore the
27
+ # host repo and treat its own package directory as the work area.
28
+ # EVOLVER_NO_PARENT_GIT=false
29
+
30
+ # Auto GitHub issue reporting (enabled by default)
31
+ # EVOLVER_AUTO_ISSUE=true
32
+ # GITHUB_TOKEN=your_github_token_here
33
+
34
+ # Pre-publish leak check mode: strict (default since v1.69.7) | warn | off
35
+ # - strict: block publish when sensitive data is detected in the capsule/gene payload
36
+ # - warn: log a warning and continue publishing (relies on sanitizePayload redaction)
37
+ # - off: skip the leak scan entirely (not recommended)
38
+ # Set to 'warn' to restore v1.69.6 and earlier behavior.
39
+ # EVOLVER_LEAK_CHECK=strict
40
+
41
+ # Hub URL resolution (v1.69.7+):
42
+ # - A2A_HUB_URL is the primary override (used at runtime by most modules)
43
+ # - EVOMAP_HUB_URL is a secondary override kept for backward compatibility
44
+ # - EVOLVER_DEFAULT_HUB_URL overrides the compile-time default when neither of
45
+ # the above is set. Use this for fully air-gapped deployments that still want
46
+ # to point validator/directory/privacy clients at a private hub endpoint.
47
+ # EVOLVER_DEFAULT_HUB_URL=https://evomap.ai
48
+
49
+ # Verbose logging
50
+ # EVOLVER_VERBOSE=true
51
+
52
+ # Memory graph rotation (issue #519). memory_graph.jsonl accumulates
53
+ # every evolution event and grows unboundedly on long-running nodes.
54
+ # When the active file crosses EVOLVER_MEMORY_GRAPH_MAX_SIZE_MB it is
55
+ # renamed to memory_graph.jsonl.<timestamp>.gz and a fresh file is
56
+ # started. Only the most recent EVOLVER_MEMORY_GRAPH_RETENTION_COUNT
57
+ # archives are kept; older ones are deleted.
58
+ # EVOLVER_MEMORY_GRAPH_AUTO_ROTATE=true
59
+ # EVOLVER_MEMORY_GRAPH_MAX_SIZE_MB=100
60
+ # EVOLVER_MEMORY_GRAPH_RETENTION_COUNT=7
61
+
62
+ # Rollback strategy when a solidify cycle's validation fails.
63
+ # stash (default): git stash push --include-untracked. Recover via 'git stash pop'.
64
+ # hard: git reset --hard. WARNING: discards uncommitted changes irrecoverably.
65
+ # none: do nothing. Leaves the failed cycle's edits in place.
66
+ # Default flipped from 'hard' to 'stash' in 1.80.8 to prevent silent data loss
67
+ # when evolver runs in third-party host repos.
68
+ # EVOLVER_ROLLBACK_MODE=stash
@@ -0,0 +1 @@
1
+ SKILL_COMMIT
@@ -0,0 +1,63 @@
1
+ # Code owners for this repository
2
+ # Format: each rule grants automatic review-request to the listed owner(s)
3
+ # when a matching path is touched in a PR. Combined with branch protection's
4
+ # "Require review from Code Owners" rule on main, these owners must approve
5
+ # the PR before it can merge.
6
+ #
7
+ # Multiple owners on each line means GitHub will auto-request a review from
8
+ # all listed owners on a matching PR; ANY one of them approving is sufficient
9
+ # to satisfy the branch-protection 'require code owner review' gate. This is
10
+ # the agreed fallback order: autogame-17 primary, forrestlinfeng + cloudcarver
11
+ # as backups when the primary is unavailable.
12
+ #
13
+ # Why we need this: PR #34 (2026-05-10) was self-merged by the author 2 minutes
14
+ # before a maintainer review comment landed, shipping a missing obfuscate
15
+ # registration into main. CODEOWNERS + branch protection make that pattern
16
+ # physically impossible.
17
+
18
+ # Default: every file is owned by autogame-17 unless a more specific rule below
19
+ # overrides it. Keeps coverage complete even for files we forget to call out.
20
+ * @autogame-17 @forrestlinfeng @cloudcarver
21
+
22
+ # High-risk paths -- listed explicitly so GitHub UI surfaces "Owner review
23
+ # required" prominently when these are touched, even if the catch-all above
24
+ # would already cover them. New contributors should treat any change here
25
+ # as a multi-day review cycle.
26
+
27
+ # GEP schemas (Gene / Capsule / Task / future). Validators and defaults must
28
+ # stay in sync with hub-side expectations; shallow-copy bugs and validator-
29
+ # wiring gaps in this directory have a track record (PR #25 / #27 / audit #30).
30
+ /src/gep/schemas/ @autogame-17 @forrestlinfeng @cloudcarver
31
+
32
+ # Pipeline modules. Module-load order vs dotenv is fragile here; refactors
33
+ # in PR #20-#24 introduced multiple dotenv-ordering and missing-import
34
+ # regressions before merge.
35
+ /src/evolve/ @autogame-17 @forrestlinfeng @cloudcarver
36
+
37
+ # Content-addressable storage and integrity primitives. Any change here
38
+ # changes asset_id semantics across all stored capsules.
39
+ /src/gep/contentHash.js @autogame-17 @forrestlinfeng @cloudcarver
40
+ /src/gep/crypto.js @autogame-17 @forrestlinfeng @cloudcarver
41
+ /src/gep/integrityCheck.js @autogame-17 @forrestlinfeng @cloudcarver
42
+ /src/gep/shield.js @autogame-17 @forrestlinfeng @cloudcarver
43
+ /src/gep/hubVerify.js @autogame-17 @forrestlinfeng @cloudcarver
44
+
45
+ # Anything that touches secrets, sanitization, or proxy auth.
46
+ /src/gep/sanitize.js @autogame-17 @forrestlinfeng @cloudcarver
47
+ /src/proxy/ @autogame-17 @forrestlinfeng @cloudcarver
48
+
49
+ # Public-mirror surface. Manifest mistakes leak source / runtime assets to
50
+ # npm; build/publish scripts directly drive npm + GitHub Release.
51
+ /public.manifest.json @autogame-17 @forrestlinfeng @cloudcarver
52
+ /scripts/build_public.js @autogame-17 @forrestlinfeng @cloudcarver
53
+ /scripts/publish_public.js @autogame-17 @forrestlinfeng @cloudcarver
54
+ /scripts/pre_publish_check.js @autogame-17 @forrestlinfeng @cloudcarver
55
+ /scripts/build_binaries.js @autogame-17 @forrestlinfeng @cloudcarver
56
+ /scripts/deploy.sh @autogame-17 @forrestlinfeng @cloudcarver
57
+
58
+ # Repo metadata that gates everything else.
59
+ /.github/ @autogame-17 @forrestlinfeng @cloudcarver
60
+ /.cursor/ @autogame-17 @forrestlinfeng @cloudcarver
61
+ /CODEOWNERS @autogame-17 @forrestlinfeng @cloudcarver
62
+ /package.json @autogame-17 @forrestlinfeng @cloudcarver
63
+ /package-lock.json @autogame-17 @forrestlinfeng @cloudcarver
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: Good first issue
3
+ about: Help newcomers get started with a small, self-contained task
4
+ labels: good first issue, help wanted, docs
5
+
6
+ ---
7
+
8
+ ## Summary
9
+
10
+ Short description of the task to complete.
11
+
12
+ ## Steps to reproduce / task
13
+
14
+ 1. Steps to reproduce (if a bug) or steps to implement (if feature)
15
+ 2. What files to edit
16
+
17
+ ## Acceptance criteria
18
+
19
+ - What success looks like
20
+
21
+ ## Notes
22
+
23
+ Any pointers / links / helpful context
@@ -0,0 +1,45 @@
1
+ ## Summary
2
+
3
+ Short 1-2 sentence summary of the change.
4
+
5
+ ## What changed
6
+
7
+ - Bullet list of changes
8
+
9
+ ## How to test
10
+
11
+ 1. Copy commands
12
+ 2. Expected output
13
+
14
+ ## Risk
15
+
16
+ Low / Medium / High -- note if it touches infra or public API.
17
+
18
+ ## Self-check
19
+
20
+ Tick only the boxes that apply, but every applicable box must be ticked. Bugbot
21
+ reads the project rules and will request changes if anything below is missing.
22
+
23
+ - [ ] If this PR adds a new source file under `src/`, it is registered in
24
+ `public.manifest.json` consistently with its sibling files (e.g. listed
25
+ in `obfuscate` when the rest of the directory is). Build verification
26
+ passed: `node scripts/build_public.js` succeeded and the new file shows
27
+ up in `dist-public/` in the expected (obfuscated or plain) form.
28
+ - [ ] If this PR adds or modifies a schema factory under `src/gep/schemas/`,
29
+ the corresponding `validate*` function is invoked at every write and
30
+ every publish call site (not just defined).
31
+ - [ ] If this PR uses `Object.assign({}, DEFAULTS, partial)` to build an
32
+ object, every reference-typed field (arrays, sub-objects) on the result
33
+ is sliced or cloned -- not held by reference to either source.
34
+ - [ ] If this PR introduces a new module-level constant initialized from
35
+ `process.env.X`, the owning module is loaded after the entry point's
36
+ dotenv configuration step (or the constant is migrated to the lazy
37
+ env helpers in `src/config.js`).
38
+ - [ ] No new runtime dependencies added without a clear justification in the
39
+ "What changed" section above.
40
+ - [ ] Tests added or updated to cover the new behavior; full suite passes
41
+ locally (`node --test test/*.test.js`).
42
+
43
+ ## Related
44
+
45
+ Closes #NN
@@ -0,0 +1,75 @@
1
+ name: test
2
+
3
+ # Runs the Node test suite on every PR and on pushes to main. Originally
4
+ # Ubuntu-only (#198): PR checks were Cursor Bugbot + Security, neither of
5
+ # which runs `npm test`, so a green PR did NOT mean the tests passed.
6
+ #
7
+ # This workflow now also runs the suite on Windows + macOS via a second job
8
+ # (test-cross). #198 explicitly flagged Windows / macOS as a follow-up: the
9
+ # suite still has Linux-specific assumptions (symlink reliance, hard-coded
10
+ # ~/.volta layout, POSIX-style path equality) that would fail on those
11
+ # hosts. test-cross runs on PRs in **advisory** mode (continue-on-error)
12
+ # so those red signals are visible to reviewers without blocking merge
13
+ # while the suite is being made hermetic. Each fix can flip its tests
14
+ # from "red on Win/Mac" to "green on Win/Mac" incrementally. Once the
15
+ # remaining failures are cleaned up, drop `continue-on-error: true` and
16
+ # add `test-cross` to required checks to make cross-platform green a
17
+ # hard merge gate.
18
+ #
19
+ # main pushes skip test-cross to keep private-repo billing predictable
20
+ # (macos-latest is 10x and windows-latest is 2x the ubuntu rate).
21
+
22
+ on:
23
+ pull_request:
24
+ push:
25
+ branches: [main]
26
+
27
+ permissions:
28
+ contents: read
29
+
30
+ concurrency:
31
+ group: test-${{ github.workflow }}-${{ github.ref }}
32
+ cancel-in-progress: true
33
+
34
+ jobs:
35
+ test:
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+
40
+ - uses: actions/setup-node@v4
41
+ with:
42
+ node-version: '22' # engines: node >=22.12
43
+ cache: npm
44
+
45
+ - name: Install dependencies
46
+ run: npm ci
47
+
48
+ - name: Run tests (node --test)
49
+ run: npm test
50
+
51
+ test-cross:
52
+ # Advisory cross-platform run: PR-only (skips main push to save billing),
53
+ # continue-on-error so a known Win/Mac regression does not block merge
54
+ # while the suite is being hardened. Reviewers still see the result and
55
+ # can opt-in to wait for a fix on a per-PR basis.
56
+ if: github.event_name == 'pull_request'
57
+ strategy:
58
+ fail-fast: false
59
+ matrix:
60
+ os: [windows-latest, macos-latest]
61
+ runs-on: ${{ matrix.os }}
62
+ continue-on-error: true
63
+ steps:
64
+ - uses: actions/checkout@v4
65
+
66
+ - uses: actions/setup-node@v4
67
+ with:
68
+ node-version: '22'
69
+ cache: npm
70
+
71
+ - name: Install dependencies
72
+ run: npm ci
73
+
74
+ - name: Run tests (node --test)
75
+ run: npm test