synergyspec-selfevolving 2.1.4 → 2.1.6
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.
- package/dist/commands/config.js +4 -0
- package/dist/commands/learn.js +80 -24
- package/dist/commands/self-evolution-dream.d.ts +54 -0
- package/dist/commands/self-evolution-dream.js +265 -0
- package/dist/commands/self-evolution-episode.d.ts +5 -0
- package/dist/commands/self-evolution-episode.js +160 -107
- package/dist/commands/self-evolution.js +127 -4
- package/dist/commands/workflow/status.js +38 -7
- package/dist/core/archive.js +27 -9
- package/dist/core/change-readiness.d.ts +63 -6
- package/dist/core/change-readiness.js +912 -23
- package/dist/core/completions/command-registry.js +1 -1
- package/dist/core/fitness/loss.d.ts +10 -5
- package/dist/core/fitness/loss.js +11 -4
- package/dist/core/fitness/test-metrics.d.ts +3 -0
- package/dist/core/fitness/test-metrics.js +78 -1
- package/dist/core/learn/trajectory-discovery.js +5 -0
- package/dist/core/learn.js +131 -13
- package/dist/core/migration.d.ts +6 -14
- package/dist/core/migration.js +63 -21
- package/dist/core/profiles.d.ts +1 -1
- package/dist/core/profiles.js +1 -0
- package/dist/core/runner-evidence.d.ts +53 -0
- package/dist/core/runner-evidence.js +613 -0
- package/dist/core/self-evolution/candidates.d.ts +1 -1
- package/dist/core/self-evolution/candidates.js +1 -2
- package/dist/core/self-evolution/canonical-targets.js +1 -0
- package/dist/core/self-evolution/dream.d.ts +132 -0
- package/dist/core/self-evolution/dream.js +1093 -0
- package/dist/core/self-evolution/episode-orchestrator.d.ts +7 -0
- package/dist/core/self-evolution/episode-orchestrator.js +162 -12
- package/dist/core/self-evolution/episode-store.d.ts +21 -0
- package/dist/core/self-evolution/episode-store.js +16 -3
- package/dist/core/self-evolution/evolving-agent.js +8 -0
- package/dist/core/self-evolution/host-harness.d.ts +46 -12
- package/dist/core/self-evolution/host-harness.js +198 -55
- package/dist/core/self-evolution/index.d.ts +1 -0
- package/dist/core/self-evolution/index.js +1 -0
- package/dist/core/self-evolution/policy/policy-store.d.ts +19 -2
- package/dist/core/self-evolution/policy/policy-store.js +85 -0
- package/dist/core/self-evolution/promote.d.ts +7 -5
- package/dist/core/self-evolution/promote.js +111 -19
- package/dist/core/self-evolution/reward-agent.js +11 -9
- package/dist/core/self-evolution/reward-aggregator.js +2 -2
- package/dist/core/shared/skill-generation.d.ts +37 -0
- package/dist/core/shared/skill-generation.js +91 -0
- package/dist/core/templates/skill-templates.d.ts +1 -0
- package/dist/core/templates/skill-templates.js +1 -0
- package/dist/core/templates/workflow-manifest.js +2 -0
- package/dist/core/templates/workflows/archive-change.js +76 -39
- package/dist/core/templates/workflows/ci.js +47 -1
- package/dist/core/templates/workflows/dream.d.ts +10 -0
- package/dist/core/templates/workflows/dream.js +123 -0
- package/dist/core/templates/workflows/gen-tests.js +9 -3
- package/dist/core/templates/workflows/learn.js +11 -7
- package/dist/core/templates/workflows/run-tests.js +99 -4
- package/dist/core/templates/workflows/self-evolving.js +118 -115
- package/dist/core/templates/workflows/verify-change.js +130 -22
- package/dist/core/trajectory/adapters/codex.js +87 -29
- package/dist/core/trajectory/adapters/opencode.js +69 -23
- package/dist/core/trajectory/facts.d.ts +1 -1
- package/dist/core/trajectory/facts.js +23 -5
- package/dist/core/trajectory/registry.d.ts +16 -2
- package/dist/core/trajectory/registry.js +104 -29
- package/dist/core/trajectory/source.d.ts +27 -4
- package/dist/dashboard/react-client.js +4 -4
- package/dist/utils/change-utils.d.ts +2 -0
- package/dist/utils/change-utils.js +53 -2
- package/package.json +99 -99
- package/schemas/spec-driven/templates/design.md +6 -0
- package/scripts/nl2repo_synergyspec-selfevolving_wrapper.py +170 -0
|
@@ -21,6 +21,35 @@ const INSTRUCTIONS_BODY = `**Input**: No change name required — CI runs across
|
|
|
21
21
|
- coverage metrics: lines, branches, functions, statements
|
|
22
22
|
(parse \`coverage-summary.json\` if present, or the runner's table output)
|
|
23
23
|
|
|
24
|
+
Persist durable runner evidence before writing the CI summary. Create:
|
|
25
|
+
\`synergyspec-selfevolving/ci-evidence/<YYYYMMDDTHHMMSSZ>/\`.
|
|
26
|
+
|
|
27
|
+
For the unit/integration coverage run, save:
|
|
28
|
+
- \`unit.stdout.log\` — raw stdout, unedited
|
|
29
|
+
- \`unit.stderr.log\` — raw stderr, unedited (empty if none)
|
|
30
|
+
- \`unit-exit.json\` — machine-readable execution metadata:
|
|
31
|
+
|
|
32
|
+
\`\`\`json
|
|
33
|
+
{
|
|
34
|
+
"command": "<exact command that was run>",
|
|
35
|
+
"cwd": "<absolute working directory>",
|
|
36
|
+
"startedAt": "<ISO timestamp>",
|
|
37
|
+
"finishedAt": "<ISO timestamp>",
|
|
38
|
+
"exitCode": 0,
|
|
39
|
+
"signal": null,
|
|
40
|
+
"stdoutLog": "synergyspec-selfevolving/ci-evidence/<timestamp>/unit.stdout.log",
|
|
41
|
+
"stderrLog": "synergyspec-selfevolving/ci-evidence/<timestamp>/unit.stderr.log",
|
|
42
|
+
"junitXml": null,
|
|
43
|
+
"coverageSummary": "coverage/coverage-summary.json",
|
|
44
|
+
"coverageLcov": "coverage/lcov.info",
|
|
45
|
+
"coverageHtml": "coverage/lcov-report/index.html"
|
|
46
|
+
}
|
|
47
|
+
\`\`\`
|
|
48
|
+
|
|
49
|
+
If a listed JUnit or coverage path does not exist, set it to \`null\`. The
|
|
50
|
+
CI verdict must be derived from this exit JSON plus parsed runner outputs,
|
|
51
|
+
not from a hand-written summary alone.
|
|
52
|
+
|
|
24
53
|
This single run covers all changes since the project test suite is shared.
|
|
25
54
|
|
|
26
55
|
2b. **Spec Blast Radius Coverage** (if any blast radius files exist)
|
|
@@ -88,7 +117,13 @@ const INSTRUCTIONS_BODY = `**Input**: No change name required — CI runs across
|
|
|
88
117
|
browsers/binaries as needed.
|
|
89
118
|
- After ensuring the tool is installed, run the e2e suite using the appropriate command
|
|
90
119
|
(e.g. \`npx playwright test --reporter=json\`, \`npx cypress run --reporter json\`) and
|
|
91
|
-
save the output to \`e2e-results/latest/<tool>-results.json\`.
|
|
120
|
+
save the output to \`e2e-results/latest/<tool>-results.json\`. Also save raw
|
|
121
|
+
\`<tool>.stdout.log\`, \`<tool>.stderr.log\`, and \`<tool>-exit.json\` under
|
|
122
|
+
\`synergyspec-selfevolving/ci-evidence/<timestamp>/\`, using the same
|
|
123
|
+
command/cwd/startedAt/finishedAt/exitCode/stdoutLog/stderrLog fields as the
|
|
124
|
+
unit runner evidence. Include the JSON reporter path in \`junitXml\` only if
|
|
125
|
+
it is actually JUnit XML; otherwise record it as a separate report path in
|
|
126
|
+
the CI markdown.
|
|
92
127
|
- Map each TP entry result (pass/fail) from the tool's output.
|
|
93
128
|
|
|
94
129
|
**Never skip e2e tests because a dependency is missing — always install it first.**
|
|
@@ -145,6 +180,15 @@ const INSTRUCTIONS_BODY = `**Input**: No change name required — CI runs across
|
|
|
145
180
|
| Functions | X% (A/B) |
|
|
146
181
|
| Statements | X% (A/B) |
|
|
147
182
|
|
|
183
|
+
### Runner Evidence
|
|
184
|
+
| Runner | Command | CWD | Started | Finished | Exit Code | stdout | stderr | Exit JSON | Optional Reports |
|
|
185
|
+
|--------|---------|-----|---------|----------|-----------|--------|--------|-----------|------------------|
|
|
186
|
+
| unit/coverage | \`<exact command>\` | \`<absolute cwd>\` | \`<ISO>\` | \`<ISO>\` | \`0\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/unit.stdout.log\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/unit.stderr.log\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/unit-exit.json\` | coverage/JUnit paths or N/A |
|
|
187
|
+
| e2e:<tool> | \`<exact command>\` | \`<absolute cwd>\` | \`<ISO>\` | \`<ISO>\` | \`0\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/<tool>.stdout.log\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/<tool>.stderr.log\` | \`synergyspec-selfevolving/ci-evidence/<timestamp>/<tool>-exit.json\` | reporter output path or N/A |
|
|
188
|
+
|
|
189
|
+
The overall verdict must agree with every listed \`*-exit.json\`. A non-zero
|
|
190
|
+
exit code is a CI failure even if the markdown summary claims otherwise.
|
|
191
|
+
|
|
148
192
|
### E2E Test Plan Results
|
|
149
193
|
| Change | ID | Description | Verdict |
|
|
150
194
|
|--------|----|-------------|---------|
|
|
@@ -166,6 +210,7 @@ const INSTRUCTIONS_BODY = `**Input**: No change name required — CI runs across
|
|
|
166
210
|
|
|
167
211
|
### Artifacts
|
|
168
212
|
- Coverage: \`coverage/lcov-report/index.html\`
|
|
213
|
+
- Runner evidence: \`synergyspec-selfevolving/ci-evidence/<timestamp>/\`
|
|
169
214
|
- Screenshots: \`e2e-results/latest/artifacts/\`
|
|
170
215
|
- Archived to: \`e2e-results/<timestamp>/\`
|
|
171
216
|
\`\`\`
|
|
@@ -189,6 +234,7 @@ const INSTRUCTIONS_BODY = `**Input**: No change name required — CI runs across
|
|
|
189
234
|
- No pbt-regressions.md for a change: note "PBT not yet run for \`<name>\` — suggest \`/synspec:run-tests\`" and treat that change as PARTIAL, not FAIL.
|
|
190
235
|
- Test runner detection fails: ask the user rather than failing silently.
|
|
191
236
|
- Coverage tooling not configured: skip coverage metrics, note the gap.
|
|
237
|
+
- Durable runner evidence cannot be written: mark CI PARTIAL, list the missing evidence paths, and do not claim PASS from markdown summaries alone.
|
|
192
238
|
|
|
193
239
|
**Output**
|
|
194
240
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Template Workflow Modules
|
|
3
|
+
*
|
|
4
|
+
* Dream workflow: chat-native entrance for the offline Supervised Learning
|
|
5
|
+
* Dream lane. The CLI remains the engine; this wrapper is the agent harness UX.
|
|
6
|
+
*/
|
|
7
|
+
import type { CommandTemplate, SkillTemplate } from '../types.js';
|
|
8
|
+
export declare function getDreamSkillTemplate(): SkillTemplate;
|
|
9
|
+
export declare function getOpsxDreamCommandTemplate(): CommandTemplate;
|
|
10
|
+
//# sourceMappingURL=dream.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const INSTRUCTIONS_BODY = `**Input**: Optionally specify a Dream mode and flags after \`/synspec:dream\`.
|
|
2
|
+
|
|
3
|
+
Accepted forms:
|
|
4
|
+
|
|
5
|
+
\`\`\`text
|
|
6
|
+
/synspec:dream
|
|
7
|
+
/synspec:dream preview [--target <id>] [--limit <n>] [--json]
|
|
8
|
+
/synspec:dream run [--target <id>] [--limit <n>] [--apply --yes] [--json]
|
|
9
|
+
/synspec:dream show [runId] [--json]
|
|
10
|
+
/synspec:dream policy-update <candidateId> --accepted-by <name> --yes [--json]
|
|
11
|
+
\`\`\`
|
|
12
|
+
|
|
13
|
+
Bare \`/synspec:dream\` means \`preview\`. Preview is read-only. Plain \`run\` writes only Dream artifacts. \`run --apply --yes\` and \`policy-update ... --yes\` are explicit policy-update entrances for already accepted Dream candidates.
|
|
14
|
+
|
|
15
|
+
**Purpose**
|
|
16
|
+
|
|
17
|
+
This is the SS agent-harness entrance for offline Supervised Learning Dream. The user should trigger Dream from the code-agent chat, not by opening a separate terminal. Your job is to call the existing CLI engine, parse the JSON result, and relay a short Dream Verdict.
|
|
18
|
+
|
|
19
|
+
Dream is not the loop-v2 episode runner. It batch-reads completed evidence and proposes optimizer briefs for existing skill/workflow/template targets. It never creates new skills, never edits POLICY directly, and never runs the episode/reward/evolving agents. By default Dream is proposal-only; policy changes require an explicit accepted-candidate update with \`--yes\`, synthesize bounded edits into the candidate package, pass the static gate, and promote through the existing rollback/ledger path.
|
|
20
|
+
|
|
21
|
+
**Mode parsing**
|
|
22
|
+
|
|
23
|
+
1. If the first argument is missing, use \`preview\`.
|
|
24
|
+
2. If the first argument is one of \`preview\`, \`run\`, \`show\`, or \`policy-update\`, use that mode.
|
|
25
|
+
3. If the first argument starts with \`--\`, treat it as a \`preview\` flag.
|
|
26
|
+
4. If the mode is unknown, stop and show the accepted forms above.
|
|
27
|
+
|
|
28
|
+
Pass only these user options through:
|
|
29
|
+
- \`--target <id>\`
|
|
30
|
+
- \`--limit <n>\`
|
|
31
|
+
- \`--apply\` and \`--yes\` for \`run\`
|
|
32
|
+
- \`candidateId\`, \`--accepted-by <name>\`, and \`--yes\` for \`policy-update\`
|
|
33
|
+
- \`--json\`
|
|
34
|
+
- \`runId\` for \`show\`
|
|
35
|
+
|
|
36
|
+
Always add \`--json\` to the CLI command you run so the result is machine-readable. If the user explicitly asked for \`--json\`, include the compact raw JSON after the Dream Verdict; otherwise provide the human summary only.
|
|
37
|
+
|
|
38
|
+
**Steps**
|
|
39
|
+
|
|
40
|
+
1. **Run the CLI engine from the project root**
|
|
41
|
+
|
|
42
|
+
For preview:
|
|
43
|
+
\`\`\`bash
|
|
44
|
+
synergyspec-selfevolving self-evolution dream preview --json
|
|
45
|
+
\`\`\`
|
|
46
|
+
|
|
47
|
+
For run:
|
|
48
|
+
\`\`\`bash
|
|
49
|
+
synergyspec-selfevolving self-evolution dream run --json
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
For show:
|
|
53
|
+
\`\`\`bash
|
|
54
|
+
synergyspec-selfevolving self-evolution dream show --json
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
For accepted candidate policy update:
|
|
58
|
+
\`\`\`bash
|
|
59
|
+
synergyspec-selfevolving self-evolution dream policy-update <candidateId> --accepted-by <name> --yes --json
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
Append \`--target <id>\`, \`--limit <n>\`, \`--apply\`, \`--yes\`, \`--accepted-by <name>\`, or \`runId\` only when the user supplied them. Never add \`--yes\` on the user's behalf.
|
|
63
|
+
|
|
64
|
+
2. **Interpret the result without re-judging it**
|
|
65
|
+
|
|
66
|
+
Read candidate ids, target ids, evidence summary, run id, update outcome, gate result, promoted files, policy version, and write paths from the CLI JSON when present. Do not invent candidate ids or claim a policy change.
|
|
67
|
+
|
|
68
|
+
3. **Classify writes**
|
|
69
|
+
|
|
70
|
+
- \`preview\`: Writes are \`none\`.
|
|
71
|
+
- plain \`run\`: Writes are \`dream-run + draft candidates\`.
|
|
72
|
+
- \`run --apply --yes\`: Writes are \`dream-run + candidates + gated policy update\` when the update is promoted; otherwise report the refusal outcome.
|
|
73
|
+
- \`show\`: Writes are \`none\`.
|
|
74
|
+
- \`policy-update --yes\`: Writes are \`gated policy update\` when promoted; otherwise report the refusal outcome.
|
|
75
|
+
|
|
76
|
+
4. **Report the next step**
|
|
77
|
+
|
|
78
|
+
Plain Dream candidates are proposal-only optimizer briefs. To turn an accepted candidate into policy, use \`/synspec:dream policy-update <candidateId> --accepted-by <name> --yes\`. The update path must author bounded edits, pass the static gate, and promote through the existing rollback/ledger channel; if any gate refuses, report the refusal and leave the policy unchanged.
|
|
79
|
+
|
|
80
|
+
**Output Format**
|
|
81
|
+
|
|
82
|
+
End with this block:
|
|
83
|
+
|
|
84
|
+
\`\`\`text
|
|
85
|
+
## Dream Verdict
|
|
86
|
+
- Mode: preview | run | show | policy-update
|
|
87
|
+
- Run id: <id or none>
|
|
88
|
+
- Candidates: <ids or none>
|
|
89
|
+
- Targets: <target ids or all eligible>
|
|
90
|
+
- Evidence read: <short summary>
|
|
91
|
+
- Writes: none | dream-run + draft candidates | dream-run + candidates + gated policy update | gated policy update
|
|
92
|
+
- Policy changed: yes | no
|
|
93
|
+
- New skills created: no
|
|
94
|
+
- Next step: review candidate(s), run accepted policy-update, or inspect gate refusal
|
|
95
|
+
\`\`\`
|
|
96
|
+
|
|
97
|
+
If the CLI command fails, still end with \`## Dream Verdict\` and set fields to \`none\` where unknown. Put the command failure under \`Evidence read\` or \`Next step\`; do not retry with a different self-evolution command.`;
|
|
98
|
+
export function getDreamSkillTemplate() {
|
|
99
|
+
return {
|
|
100
|
+
name: 'synergyspec-selfevolving-dream',
|
|
101
|
+
description: 'SS Dream entrance: preview, run, inspect, or apply accepted offline Supervised Learning Dream updates from the code-agent chat.',
|
|
102
|
+
instructions: `Run the SS offline Supervised Learning Dream lane from the code-agent harness.
|
|
103
|
+
|
|
104
|
+
${INSTRUCTIONS_BODY}`,
|
|
105
|
+
license: 'MIT',
|
|
106
|
+
compatibility: 'Requires synergyspec-selfevolving CLI.',
|
|
107
|
+
metadata: { author: 'synergyspec-selfevolving', version: '1.0' },
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function getOpsxDreamCommandTemplate() {
|
|
111
|
+
return {
|
|
112
|
+
name: 'SS: Dream',
|
|
113
|
+
description: 'Preview, run, inspect, or apply accepted offline Supervised Learning Dream updates from the code-agent chat',
|
|
114
|
+
category: 'Workflow',
|
|
115
|
+
tags: ['workflow', 'dream', 'self-evolution', 'offline-learning'],
|
|
116
|
+
content: `Run the SS offline Supervised Learning Dream lane from the code-agent harness.
|
|
117
|
+
|
|
118
|
+
**Input**: Optionally specify a mode after \`/synspec:dream\` (for example \`/synspec:dream preview\`, \`/synspec:dream run --limit 5\`, \`/synspec:dream show\`, or \`/synspec:dream policy-update <candidateId> --accepted-by <name> --yes\`). Bare \`/synspec:dream\` means read-only \`preview\`.
|
|
119
|
+
|
|
120
|
+
${INSTRUCTIONS_BODY}`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=dream.js.map
|
|
@@ -72,7 +72,7 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
72
72
|
|
|
73
73
|
Detection order: scan existing test files for PBT imports first; if none found, infer from project language; if ambiguous, use AskUserQuestion.
|
|
74
74
|
|
|
75
|
-
**Every WHEN/THEN scenario extracted in step 4 must
|
|
75
|
+
**Every WHEN/THEN scenario extracted in step 4 must be represented in PBT Coverage**, preferably by exactly one PBT test. There is ONE sanctioned \`➖ N/A\` exception: a scenario whose behaviour is already exhaustively covered by an existing example/benchmark test AND cannot be expressed as a meaningful property may be recorded as \`➖ N/A\` in step 8. The \`➖ N/A\` row must cite the covering test path (and line when available) in the \`PBT Test\` column and explain why a property would be vacuous or duplicate coverage. Otherwise, no exceptions:
|
|
76
76
|
- **WHEN** clause → generator expression + precondition guard (filter/assume)
|
|
77
77
|
- **THEN** clause → invariant (property assertion that must hold for all generated inputs)
|
|
78
78
|
- When the WHEN clause has no parameterisable variable (e.g. "WHEN the app loads"), generate arbitrary system/environment state as the input and use the THEN clause alone as the invariant.
|
|
@@ -136,9 +136,15 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
136
136
|
|---------|----------|----------|-----------|--------|
|
|
137
137
|
| UC1-S1 | <scenario description> | \`test/uc1-s1.property.test.ts:5\` | fast-check | ✅ |
|
|
138
138
|
| UC1-S2 | <scenario description> | \`test/uc1-s2.property.test.ts:12\` | fast-check | ✅ |
|
|
139
|
+
| UC1-S3 | <scenario description> | \`test/exhaustive-example.test.ts:44\` | N/A | ➖ N/A — exhaustively covered; property would duplicate fixed finite cases |
|
|
139
140
|
| UC1-E2a | <scenario description> | \`test/uc1-e2a.property.test.ts:8\` | fast-check | ❌ missing |
|
|
140
141
|
...
|
|
141
142
|
|
|
143
|
+
A \`➖ N/A\` row is valid only when it cites an existing covering test path in
|
|
144
|
+
\`PBT Test\` and the status text states the reason. A \`➖ N/A\` row with no
|
|
145
|
+
covering test path, or with only a prose justification, is invalid and must be
|
|
146
|
+
treated as \`❌ missing\`.
|
|
147
|
+
|
|
142
148
|
## Use Case Details: <name> (ID: UC1)
|
|
143
149
|
|
|
144
150
|
### Main Scenario
|
|
@@ -161,7 +167,7 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
161
167
|
|
|
162
168
|
9. **Decision point (Re-generate or output)**
|
|
163
169
|
|
|
164
|
-
- Report missing or incomplete **example-based tests
|
|
170
|
+
- Report missing or incomplete **example-based tests**, any **PBT Coverage** rows marked \`❌ missing\`, and any invalid \`➖ N/A\` rows that lack a concrete covering test path.
|
|
165
171
|
- **Ask if they want to generate / update all missing and incomplete tests (both kinds).**
|
|
166
172
|
- If the user confirms, go back to steps 6–7 and generate / update tests.
|
|
167
173
|
- If the user does not confirm, proceed to the output step.
|
|
@@ -176,7 +182,7 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
176
182
|
- Classify by requirement boundary, not by code layer. A test that calls a low-level function but verifies a single spec step is still a Unit test. A test that exercises the UI but covers an entire use case flow is an Integration test.
|
|
177
183
|
- Map requirements to tests via: exact name match, keyword match, file path match
|
|
178
184
|
- When uncertain about test implementation status, mark as ⚠️ (partial) not ✅
|
|
179
|
-
- Every WHEN/THEN scenario must have
|
|
185
|
+
- Every WHEN/THEN scenario must have either one PBT test or one valid \`➖ N/A\` row with a concrete covering test path. When the WHEN clause has no parameterisable input, generate arbitrary system/environment state and use the THEN clause as the invariant unless the strict \`➖ N/A\` criteria above apply.
|
|
180
186
|
|
|
181
187
|
**Graceful Degradation**
|
|
182
188
|
|
|
@@ -19,17 +19,19 @@ This is the review-and-learn step after \`/synspec:apply\` and \`/synspec:verify
|
|
|
19
19
|
The runner starts with NO conversation context, so collect every handle it needs:
|
|
20
20
|
- **Project root**: the absolute path of the current working directory.
|
|
21
21
|
- **Change name**: from step 1.
|
|
22
|
-
- **Harness**:
|
|
23
|
-
- **Mode**: always \`apply\` — the episode runs the full loop (score, decide, and the 演进智能体's ONE bounded edit) autonomously, with no confirmation prompt. There is NO read-only episode and NO \`--preview\` flag. If the user wants a read-only look (no rollback, no evolution), do NOT run an episode: use the read-only view \`synergyspec-selfevolving self-evolution policy show\` (or a plain \`synergyspec-selfevolving learn <name>\` without \`--apply\`) instead.
|
|
24
|
-
- **
|
|
22
|
+
- **Harness**: resolve the CURRENT host runtime, not the change metadata. If this skill is running in Codex, use \`codex\`; in Claude Code, use \`claude\`; in OpenCode, use \`opencode\`. Use \`unknown\` only when the host is genuinely unidentified after checking the active session/tooling. Do NOT read \`harness:\` from the per-change YAML for this field: that metadata is historical provenance, not the runtime that will spawn the loop-v2 agents.
|
|
23
|
+
- **Mode**: always \`apply\` — the episode runs the full loop (score, decide, and the 演进智能体's ONE bounded edit) autonomously, with no confirmation prompt. There is NO read-only episode and NO \`--preview\` flag. If the user wants a read-only look (no rollback, no evolution), do NOT run an episode: use the read-only view \`synergyspec-selfevolving self-evolution policy show\` (or a plain \`synergyspec-selfevolving learn <name>\` without \`--apply\`) instead.
|
|
24
|
+
- **Force-new episode**: \`yes\` only when the user explicitly asked to rerun / force a fresh episode; otherwise \`no\`. A normal learn run must not invent a rerun.
|
|
25
|
+
- **Isolation**: \`fresh-context subagent\` for the spawned runner.
|
|
26
|
+
- **Session handle (optional)**: if your harness exposes this session's id or transcript path, capture it; otherwise omit it (the 主智能体 MAIN AGENT arm's trajectory discovery then uses the change window).
|
|
25
27
|
|
|
26
28
|
3. **Spawn the runner**
|
|
27
29
|
|
|
28
|
-
Use the host's available general-purpose Task/subagent runner (for example \`general-purpose\` on Claude or \`general\` on hosts that expose that type), prompt: "Use Skill tool to invoke synergyspec-selfevolving-self-evolving for change '<name>'. Project root: <root>. Harness: <harness>. Mode: apply. Session-id: <id>. Transcript: <path>. Trigger the loop-v2 self-evolution episode autonomously, do not ask the user questions, and end with the '## Episode Verdict' block."
|
|
30
|
+
Use the host's available general-purpose Task/subagent runner (for example \`general-purpose\` on Claude or \`general\` on hosts that expose that type), prompt: "Use Skill tool to invoke synergyspec-selfevolving-self-evolving for change '<name>'. Project root: <root>. Harness: <harness>. Mode: apply. Force-new: <yes|no>. Isolation: fresh-context subagent. Session-id: <id>. Transcript: <path>. Trigger the loop-v2 self-evolution episode autonomously, do not ask the user questions, and end with the '## Episode Verdict' block."
|
|
29
31
|
|
|
30
32
|
Include the \`Session-id: <id>.\` / \`Transcript: <path>.\` segment only when the session handle from step 2 is known — omit it entirely when unknown.
|
|
31
33
|
|
|
32
|
-
The runner triggers exactly one CLI command — \`synergyspec-selfevolving self-evolution episode --change "<name>" --session-id <id
|
|
34
|
+
The runner triggers exactly one CLI command — \`synergyspec-selfevolving self-evolution episode --change "<name>" --harness <harness> --session-id <id> --rerun\` when force-new is \`yes\`; omit \`--rerun\` when force-new is \`no\`; omit \`--harness\` when it is \`unknown\` — and the orchestrator CODE-SPAWNS the 奖励智能体 REWARD AGENT + 演进智能体 EVOLVING AGENT (+ optional CRITIC AGENT(基线智能体)). Neither you nor the runner grades or edits canonical files.
|
|
33
35
|
|
|
34
36
|
Guardrails:
|
|
35
37
|
- Do NOT trigger the episode yourself in this session — it must run from a fresh context.
|
|
@@ -42,6 +44,7 @@ This is the review-and-learn step after \`/synspec:apply\` and \`/synspec:verify
|
|
|
42
44
|
|
|
43
45
|
Read the runner's \`## Episode Verdict\` block from its final message, then:
|
|
44
46
|
- Cross-check it against \`synergyspec-selfevolving status --change "<name>" --json\` and the episode's \`episode.json\` / \`diagnosis.json\`. NEVER contradict the machine-written outcome.
|
|
47
|
+
- Write durable learn evidence to \`synergyspec-selfevolving/changes/<name>/learn-report.md\` before the final reply. The report MUST be derived from the runner's machine verdict and the cross-checks, not from a new judgment. Include: the verbatim \`## Episode Verdict\` fields, status cross-check result, episode artifact paths checked, policy/canonical files changed, rollback command, defect/safe-no-op classification, isolation mode, and next step. Create the file for \`evolved\`, \`kept\`, \`abstained\`, \`rolled-back\`, \`busy-in-flight\`, safe refusals, and real \`error-...\` defects alike; archive uses this file as evidence that learn actually ran. If the write fails, say so explicitly and include the full report text in the chat instead of pretending learn evidence exists.
|
|
45
48
|
- Relay the outcome, the decision (rolled-back / kept / abstained), the evolution kind, the new 策略 POLICY version, the evolved target, and the rollback command verbatim.
|
|
46
49
|
- Classify the outcome before moving on: a \`kept\` / \`abstained\` no-op on a verified-green or no-nameable-gap run is the CORRECT outcome (产物即弃), not a missed evolution; a \`rolled-back\` decision is the loop working (the 否决缓冲 reject-buffer recorded the lost direction). A SAFE refusal (missing/red evidence, frozen target, gate refused on real grounds) is expected, not a bug; a DEFECT the runner flagged (an unbindable target, an orchestrator failure that is NOT about evidence / freezing / scope) must be surfaced to the user, not archived over.
|
|
47
50
|
|
|
@@ -50,12 +53,13 @@ This is the review-and-learn step after \`/synspec:apply\` and \`/synspec:verify
|
|
|
50
53
|
- Lead with the runner's verdict, not the spawn mechanics.
|
|
51
54
|
- Relay the \`## Episode Verdict\` fields verbatim: outcome, decision, evolution kind, advantage, new 策略 POLICY version, evolved target, canonical file(s) changed, and the rollback command.
|
|
52
55
|
- State clearly whether the 策略 POLICY changed (evolved / rolled-back / unchanged) and the isolation mode (fresh-context subagent, or inline fallback (degraded)).
|
|
56
|
+
- State whether \`synergyspec-selfevolving/changes/<name>/learn-report.md\` was written, and do not call the change archive-ready if that write failed.
|
|
53
57
|
- Separate safe no-ops and refusals from DEFECTs to surface.
|
|
54
58
|
- End with the normal next step: \`/synspec:archive\` once the user is satisfied with the review.`;
|
|
55
59
|
export function getLearnSkillTemplate() {
|
|
56
60
|
return {
|
|
57
61
|
name: 'synergyspec-selfevolving-learn',
|
|
58
|
-
description: 'Review a completed SynergySpec-SelfEvolving change after apply/verify
|
|
62
|
+
description: 'Review a completed SynergySpec-SelfEvolving change after apply/verify, capture durable learn evidence, and relay the loop-v2 episode verdict.',
|
|
59
63
|
instructions: `Review and learn from a completed SynergySpec-SelfEvolving change after apply and verify.
|
|
60
64
|
|
|
61
65
|
${INSTRUCTIONS_BODY}`,
|
|
@@ -67,7 +71,7 @@ ${INSTRUCTIONS_BODY}`,
|
|
|
67
71
|
export function getOpsxLearnCommandTemplate() {
|
|
68
72
|
return {
|
|
69
73
|
name: 'SynergySpec-SelfEvolving: Learn',
|
|
70
|
-
description: 'Review a completed change
|
|
74
|
+
description: 'Review a completed change, capture durable learn evidence, and relay the loop-v2 episode verdict',
|
|
71
75
|
category: 'Workflow',
|
|
72
76
|
tags: ['workflow', 'learn', 'review', 'memory'],
|
|
73
77
|
content: `Review and learn from a completed SynergySpec-SelfEvolving change after \`/synspec:apply\` and \`/synspec:verify\`.
|
|
@@ -21,6 +21,71 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
21
21
|
Run: \`<detected-runner>\`
|
|
22
22
|
Capture stdout/stderr output.
|
|
23
23
|
|
|
24
|
+
3a. **Persist durable runner evidence**
|
|
25
|
+
|
|
26
|
+
Before summarizing results, create an evidence directory:
|
|
27
|
+
\`synergyspec-selfevolving/changes/<name>/test-evidence/<YYYYMMDDTHHMMSSZ>/\`.
|
|
28
|
+
|
|
29
|
+
Save the raw runner outputs and exit metadata:
|
|
30
|
+
- \`runner.stdout.log\` — raw stdout, unedited
|
|
31
|
+
- \`runner.stderr.log\` — raw stderr, unedited (create an empty file if the runner emitted none)
|
|
32
|
+
- \`runner-exit.json\` — machine-readable execution metadata:
|
|
33
|
+
|
|
34
|
+
\`\`\`json
|
|
35
|
+
{
|
|
36
|
+
"command": "<exact command that was run>",
|
|
37
|
+
"cwd": "<absolute working directory>",
|
|
38
|
+
"startedAt": "<ISO timestamp>",
|
|
39
|
+
"finishedAt": "<ISO timestamp>",
|
|
40
|
+
"exitCode": 0,
|
|
41
|
+
"signal": null,
|
|
42
|
+
"stdoutLog": "synergyspec-selfevolving/changes/<name>/test-evidence/<timestamp>/runner.stdout.log",
|
|
43
|
+
"stderrLog": "synergyspec-selfevolving/changes/<name>/test-evidence/<timestamp>/runner.stderr.log",
|
|
44
|
+
"stdoutLogSha256": "<sha256 of runner.stdout.log>",
|
|
45
|
+
"stderrLogSha256": "<sha256 of runner.stderr.log>",
|
|
46
|
+
"workspaceIdentity": {
|
|
47
|
+
"changeName": "<name>",
|
|
48
|
+
"taskId": "<benchmark task id, if any>",
|
|
49
|
+
"cwd": "<absolute working directory>",
|
|
50
|
+
"pyproject": null,
|
|
51
|
+
"packageJson": null
|
|
52
|
+
},
|
|
53
|
+
"testMetrics": {
|
|
54
|
+
"total": 29,
|
|
55
|
+
"passed": 29,
|
|
56
|
+
"failed": 0,
|
|
57
|
+
"passRate": 1
|
|
58
|
+
},
|
|
59
|
+
"junitXml": null,
|
|
60
|
+
"coverageSummary": null,
|
|
61
|
+
"coverageLcov": null,
|
|
62
|
+
"coverageHtml": null
|
|
63
|
+
}
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Set each workspace identity file entry to an object ONLY when that file
|
|
67
|
+
exists at the project root. If \`pyproject.toml\` or \`package.json\` is absent,
|
|
68
|
+
leave that field \`null\` (or omit it); do not emit a \`path\` for an absent file.
|
|
69
|
+
Object shape for a present file:
|
|
70
|
+
|
|
71
|
+
\`\`\`json
|
|
72
|
+
{
|
|
73
|
+
"path": "pyproject.toml",
|
|
74
|
+
"name": "<project/package name, or null>",
|
|
75
|
+
"sha256": "<sha256 of the file>"
|
|
76
|
+
}
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
If the runner summary exposes pass/fail counts, record them in
|
|
80
|
+
\`testMetrics\`; otherwise set \`testMetrics\` to \`null\` and preserve the raw
|
|
81
|
+
stdout/stderr logs. The \`stdoutLogSha256\` and \`stderrLogSha256\` fields MUST
|
|
82
|
+
be the SHA-256 hashes of the exact saved log files, computed after writing the
|
|
83
|
+
files and before writing \`runner-exit.json\`; do not hand-edit logs after
|
|
84
|
+
hashing. If the runner produces JUnit XML or coverage artifacts,
|
|
85
|
+
record their paths in \`runner-exit.json\`. If it does not, keep those fields
|
|
86
|
+
\`null\`. The markdown report may summarize results, but the raw logs and exit
|
|
87
|
+
JSON are the durable evidence that later verification must inspect.
|
|
88
|
+
|
|
24
89
|
3b. **Promote PBT counterexamples to regression tests**
|
|
25
90
|
|
|
26
91
|
Scan the captured stdout/stderr for PBT failure markers. Each major framework prints a minimal (shrunk) counterexample when a property fails:
|
|
@@ -52,6 +117,11 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
52
117
|
|
|
53
118
|
**If no PBT tests exist** (no \`.property.test.*\` files found anywhere): note "No PBT tests found — run \`/synspec:gen-tests\` to generate them."
|
|
54
119
|
|
|
120
|
+
**PBT N/A rows**: If \`spec-tests.md\` contains \`PBT Coverage\` rows marked
|
|
121
|
+
\`➖ N/A\`, do not count those rows as missing PBT tests only when each row cites
|
|
122
|
+
a covering example/benchmark test path. A \`➖ N/A\` row without a concrete
|
|
123
|
+
covering test is invalid and should be reported as missing PBT coverage.
|
|
124
|
+
|
|
55
125
|
4. **Generate Test Coverage Report**
|
|
56
126
|
|
|
57
127
|
Save this file to \`synergyspec-selfevolving/changes/<name>/test-report.md\`.
|
|
@@ -82,9 +152,33 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
82
152
|
| UC1-E4a1 | Error when no grid space | ❌ failed | \`gridSize=0, widgetCount=1\` | \`test/pbt-regression-uc1-e4a1-1.test.ts\` |
|
|
83
153
|
...
|
|
84
154
|
|
|
85
|
-
### Test Run Results
|
|
86
|
-
<
|
|
87
|
-
|
|
155
|
+
### Test Run Results
|
|
156
|
+
Summary: <N collected>, <N passed>, <N failed>, <N skipped>, <N collection errors>
|
|
157
|
+
<raw summary from test runner output: passed/failed/skipped counts>
|
|
158
|
+
If failures: list failing test names and errors.
|
|
159
|
+
|
|
160
|
+
### Runner Evidence
|
|
161
|
+
| Evidence | Path / Value |
|
|
162
|
+
|----------|--------------|
|
|
163
|
+
| Command | \`<exact command>\` |
|
|
164
|
+
| CWD | \`<absolute working directory>\` |
|
|
165
|
+
| Started | \`<ISO timestamp>\` |
|
|
166
|
+
| Finished | \`<ISO timestamp>\` |
|
|
167
|
+
| Exit Code | \`<numeric exit code>\` |
|
|
168
|
+
| stdout | \`synergyspec-selfevolving/changes/<name>/test-evidence/<timestamp>/runner.stdout.log\` |
|
|
169
|
+
| stderr | \`synergyspec-selfevolving/changes/<name>/test-evidence/<timestamp>/runner.stderr.log\` |
|
|
170
|
+
| Exit JSON | \`synergyspec-selfevolving/changes/<name>/test-evidence/<timestamp>/runner-exit.json\` |
|
|
171
|
+
| Workspace Identity | \`pyproject.toml [project].name=<name>, sha256=<hash>; package.json name=<name>, sha256=<hash>\` |
|
|
172
|
+
| JUnit XML | \`<path or N/A>\` |
|
|
173
|
+
| Coverage Summary | \`<path or N/A>\` |
|
|
174
|
+
|
|
175
|
+
The pass/fail verdict must be consistent with \`runner-exit.json\`. If the
|
|
176
|
+
runner exited non-zero, do not report the suite as passed even if a textual
|
|
177
|
+
summary appears optimistic.
|
|
178
|
+
The current root package identity must also match
|
|
179
|
+
\`runner-exit.json.workspaceIdentity\` before the report can prove the current
|
|
180
|
+
workspace. If \`pyproject.toml\` or \`package.json\` changes after the run,
|
|
181
|
+
rerun tests and refresh this evidence instead of archiving stale results.
|
|
88
182
|
\`\`\`
|
|
89
183
|
|
|
90
184
|
5. **Generate Test Plan**
|
|
@@ -172,6 +266,7 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
172
266
|
**Graceful Degradation**
|
|
173
267
|
|
|
174
268
|
- If tests fail: still show the coverage report; highlight failures separately
|
|
269
|
+
- If durable runner evidence cannot be written: mark the report PARTIAL, explain why, and do not claim the tests passed solely from a self-authored summary
|
|
175
270
|
- If no spec-tests.md: note "Run /synspec:gen-tests first for accurate coverage mapping"
|
|
176
271
|
- If no PBT tests found: note "No PBT tests found — run /synspec:gen-tests to generate them" and skip step 3b
|
|
177
272
|
- If pbt-regressions.md already exists: update it in place (append new entries, update status of previously open regressions that now pass)
|
|
@@ -183,7 +278,7 @@ const INSTRUCTIONS_BODY = `**Input**: Optionally specify a change name. If omitt
|
|
|
183
278
|
- File:line references for existing tests
|
|
184
279
|
- Specific, actionable recommendations for missing coverage
|
|
185
280
|
- If test plan was generated: "Test plan saved to \`synergyspec-selfevolving/changes/<name>/test-plan.md\` — follow it to manually verify N uncovered steps."
|
|
186
|
-
- If coverage is complete: suggest \`/synspec:verify\` next, then \`/synspec:learn\`, then \`/synspec:archive\`
|
|
281
|
+
- If coverage is complete: suggest \`/synspec:verify\` next, then \`/synspec:learn\`, then \`/synspec:archive\`
|
|
187
282
|
- For full CI pipeline (all tests + e2e + coverage + screenshot comparison in one step): run \`/synspec:ci\``;
|
|
188
283
|
export function getRunTestsSkillTemplate() {
|
|
189
284
|
return {
|