maestro-flow 0.5.48 → 0.5.49
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/.agents/skills/manage-harvest/SKILL.md +4 -2
- package/.agents/skills/manage-knowledge-audit/SKILL.md +7 -2
- package/.agents/skills/quality-review/SKILL.md +2 -2
- package/.agents/skills/spec-add/SKILL.md +4 -0
- package/.agy/skills/manage-harvest/SKILL.md +4 -2
- package/.agy/skills/manage-knowledge-audit/SKILL.md +7 -2
- package/.agy/skills/quality-review/SKILL.md +2 -2
- package/.agy/skills/spec-add/SKILL.md +4 -0
- package/.claude/commands/manage-harvest.md +4 -2
- package/.claude/commands/manage-knowledge-audit.md +7 -2
- package/.claude/commands/quality-review.md +2 -2
- package/.claude/commands/spec-add.md +4 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.d.ts +2 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js +28 -37
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.d.ts +0 -34
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +0 -126
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.d.ts +6 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js +17 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.d.ts +28 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.js +70 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.test.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.test.js +78 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/time-decay.test.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +6 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +104 -29
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +2 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/writer.js +8 -5
- package/dashboard/dist-server/dashboard/src/server/wiki/writer.js.map +1 -1
- package/dashboard/dist-server/src/search/daemon-client.js +5 -3
- package/dashboard/dist-server/src/search/daemon-client.js.map +1 -1
- package/dashboard/dist-server/src/tools/spec-entry-parser.d.ts +42 -1
- package/dashboard/dist-server/src/tools/spec-entry-parser.js +22 -2
- package/dashboard/dist-server/src/tools/spec-entry-parser.js.map +1 -1
- package/dashboard/dist-server/src/tools/spec-loader.js +10 -3
- package/dashboard/dist-server/src/tools/spec-loader.js.map +1 -1
- package/dist/src/agents/api-explore/agent-loop.d.ts +2 -0
- package/dist/src/agents/api-explore/agent-loop.d.ts.map +1 -1
- package/dist/src/agents/api-explore/agent-loop.js +1 -1
- package/dist/src/agents/api-explore/agent-loop.js.map +1 -1
- package/dist/src/agents/api-explore/circuit-breaker.d.ts +11 -0
- package/dist/src/agents/api-explore/circuit-breaker.d.ts.map +1 -1
- package/dist/src/agents/api-explore/circuit-breaker.js +70 -1
- package/dist/src/agents/api-explore/circuit-breaker.js.map +1 -1
- package/dist/src/agents/api-explore/llm.d.ts +5 -0
- package/dist/src/agents/api-explore/llm.d.ts.map +1 -1
- package/dist/src/agents/api-explore/llm.js +31 -0
- package/dist/src/agents/api-explore/llm.js.map +1 -1
- package/dist/src/agents/api-explore/runner.d.ts.map +1 -1
- package/dist/src/agents/api-explore/runner.js +54 -6
- package/dist/src/agents/api-explore/runner.js.map +1 -1
- package/dist/src/commands/search.d.ts +4 -0
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +18 -3
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/commands/spec.d.ts.map +1 -1
- package/dist/src/commands/spec.js +113 -0
- package/dist/src/commands/spec.js.map +1 -1
- package/dist/src/commands/wiki.js +2 -2
- package/dist/src/commands/wiki.js.map +1 -1
- package/dist/src/search/daemon-client.d.ts.map +1 -1
- package/dist/src/search/daemon-client.js +5 -3
- package/dist/src/search/daemon-client.js.map +1 -1
- package/dist/src/search/daemon.d.ts.map +1 -1
- package/dist/src/search/daemon.js +17 -0
- package/dist/src/search/daemon.js.map +1 -1
- package/dist/src/tools/spec-conflict-marker.d.ts +62 -0
- package/dist/src/tools/spec-conflict-marker.d.ts.map +1 -1
- package/dist/src/tools/spec-conflict-marker.js +280 -1
- package/dist/src/tools/spec-conflict-marker.js.map +1 -1
- package/dist/src/tools/spec-entry-parser.d.ts +42 -1
- package/dist/src/tools/spec-entry-parser.d.ts.map +1 -1
- package/dist/src/tools/spec-entry-parser.js +22 -2
- package/dist/src/tools/spec-entry-parser.js.map +1 -1
- package/dist/src/tools/spec-loader.d.ts.map +1 -1
- package/dist/src/tools/spec-loader.js +10 -3
- package/dist/src/tools/spec-loader.js.map +1 -1
- package/dist/src/tools/spec-writer.d.ts +2 -0
- package/dist/src/tools/spec-writer.d.ts.map +1 -1
- package/dist/src/tools/spec-writer.js +8 -6
- package/dist/src/tools/spec-writer.js.map +1 -1
- package/dist/src/utils/update-notices.js +12 -0
- package/dist/src/utils/update-notices.js.map +1 -1
- package/package.json +1 -1
- package/workflows/agy-instructions.md +14 -5
- package/workflows/claude-instructions.md +25 -3
- package/workflows/codex-instructions.md +14 -5
- package/workflows/finish-work.md +65 -86
- package/workflows/knowledge-audit.md +2 -1
- package/workflows/specs-add.md +7 -3
|
@@ -48,7 +48,7 @@ Additional flags, source registry (scan paths), and storage locations defined in
|
|
|
48
48
|
2. **Never modify source artifacts** — harvest is purely extractive; source files remain untouched
|
|
49
49
|
3. **Dedup before write** — MUST check harvest-log.jsonl and existing stores before each write to prevent duplicates
|
|
50
50
|
4. **Source tagging** — MUST set `source: "harvest"` on every issues.jsonl row so concurrent writers can be distinguished
|
|
51
|
-
5. **
|
|
51
|
+
5. **Relationship pre-check on spec routing** — when routing to spec, MUST compare against existing specs with same keywords/category. Classify the relationship: **supersede** (new replaces old) → attach `supersedes = <old-sid>`, after add run `maestro spec supersede`; **conflict** (genuine dispute) → set `confidence="low"` and log conflict note; **independent** → no metadata
|
|
52
52
|
6. **Provenance tracking** — every routed item MUST be logged in harvest-log.jsonl with fragment ID, target store, and timestamp
|
|
53
53
|
7. **Dry-run safety** — `--dry-run` MUST NOT write any files; preview only
|
|
54
54
|
</invariants>
|
|
@@ -88,8 +88,10 @@ Extraction patterns, classification rules, routing infrastructure, and fragment
|
|
|
88
88
|
| Wiki graph needs linking | `/manage-wiki connect --fix` |
|
|
89
89
|
| Issues created | `/manage-issue list --source harvest` |
|
|
90
90
|
| Specs extracted | `/spec-load --role implement` |
|
|
91
|
-
| Specs extracted (
|
|
91
|
+
| Specs extracted (审查) | `/manage-knowledge-audit --scope spec` — 新写入的 spec 可能与现有条目矛盾或替代 |
|
|
92
|
+
| 查看演化链 | `maestro spec history <sid>` — 确认 supersede 链完整 |
|
|
92
93
|
| Spec 冲突标记已存在 | `maestro spec conflict list` — 查看当前冲突状态 |
|
|
94
|
+
| 知识健康检查 | `maestro spec health` — 悬空/循环 supersedes 校验 |
|
|
93
95
|
| Full phase retrospective | `/quality-retrospective` |
|
|
94
96
|
</completion>
|
|
95
97
|
|
|
@@ -83,15 +83,17 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
83
83
|
|
|
84
84
|
### Conflict Resolution Integration
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
五态决策(扩展自三态 keep/deprecate/delete):
|
|
87
87
|
|
|
88
88
|
| 动作 | 适用场景 | 执行 |
|
|
89
89
|
|------|---------|------|
|
|
90
90
|
| `keep` | 内容正确,无需变更 | 写 audit-log ignore 记录 |
|
|
91
91
|
| `contest` | 矛盾真实存在,需进一步审查 | `maestro spec conflict mark <file> <line> --note "<evidence>"` |
|
|
92
|
-
| `
|
|
92
|
+
| `supersede` | 内容过时,已有更新版本替代 | `maestro spec supersede <old-sid> --by <new-sid>`(保留演化链) |
|
|
93
|
+
| `deprecate` | 内容过时,无替代版本 | 注入 `status="deprecated"` + `maestro spec conflict clear <file> <line>` |
|
|
93
94
|
| `delete` | 内容明确错误 | 移除 entry + `maestro spec conflict clear <file> <line>` |
|
|
94
95
|
|
|
96
|
+
**supersede vs deprecate**: supersede 用于有明确替代条目的场景(建立演化链),deprecate 用于无替代条目的场景。
|
|
95
97
|
**关键**: deprecate/delete 执行时,如果目标条目有 conflict-marker,必须同步调用 `maestro spec conflict clear` 清除标记,避免悬空冲突。
|
|
96
98
|
|
|
97
99
|
### Code-as-Truth 校验(审查核心原则)
|
|
@@ -117,6 +119,9 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
117
119
|
| 验证 spec 现状 | `/spec-load --role implement` |
|
|
118
120
|
| 查看冲突标记 | `maestro spec conflict list` |
|
|
119
121
|
| 清除已解决冲突 | `maestro spec conflict clear-all <file>` |
|
|
122
|
+
| 查看演化链 | `maestro spec history <sid>` |
|
|
123
|
+
| 知识健康检查 | `maestro spec health` |
|
|
124
|
+
| 回填存量 sid | `maestro spec backfill-sid` |
|
|
120
125
|
| 周期巡检 | `--scope all --report` |
|
|
121
126
|
</completion>
|
|
122
127
|
|
|
@@ -66,7 +66,7 @@ Each artifact's type determines its outputs at `.workflow/{a.path}/`:
|
|
|
66
66
|
3. **Verdict is data-driven** — NEVER change verdict severity to accommodate user preference without new evidence. Verdicts flow from findings, not negotiation.
|
|
67
67
|
4. **Dimension independence** — each review dimension produces findings independently. One dimension's results MUST NOT suppress or override another's.
|
|
68
68
|
5. **Prior review delta** — when a prior review.json exists for the same phase, findings MUST be compared. Do NOT re-report already-resolved findings as new.
|
|
69
|
-
6. **Spec conflict integrity** — if code contradicts a spec entry, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
69
|
+
6. **Spec conflict integrity** — if code contradicts a spec entry: if the code is the evolved practice (spec outdated), suggest `maestro spec supersede`; if genuinely disputed, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
70
70
|
</invariants>
|
|
71
71
|
|
|
72
72
|
<execution>
|
|
@@ -87,7 +87,7 @@ Follow '~/.maestro/workflows/review.md' completely.
|
|
|
87
87
|
- REQUIRED: review.json written with findings, severity distribution, and verdict.
|
|
88
88
|
- REQUIRED: Issues auto-created based on level thresholds.
|
|
89
89
|
- REQUIRED: index.json updated with review status.
|
|
90
|
-
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule), suggest `maestro spec
|
|
90
|
+
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule): if spec is outdated (code evolved), suggest `maestro spec supersede`; if genuinely disputed, suggest `maestro spec conflict mark`. Code is the single source of truth.
|
|
91
91
|
|
|
92
92
|
**Output writes to REVIEW_DIR** (not EXEC_DIR):
|
|
93
93
|
- `REVIEW_DIR/review.json` — findings, severity distribution, verdict
|
|
@@ -25,6 +25,7 @@ $ARGUMENTS -- expects `[--scope <scope>] [--uid <uid>] <category> <content>`
|
|
|
25
25
|
|
|
26
26
|
**Options:**
|
|
27
27
|
- `--description <desc>` — One-line description for search results (falls back to content[:240])
|
|
28
|
+
- `--json` — Output JSON with generated `sid` (needed for supersession: `maestro spec supersede <old-sid> --by <new-sid>`)
|
|
28
29
|
- `--ref <path>` — Create as index entry referencing a knowhow document. If the path exists, only creates the spec index entry. If path doesn't exist, also creates the knowhow file.
|
|
29
30
|
- `--knowhow-type <type>` — Knowhow document type when creating with --ref (asset, blueprint, document, template, recipe, reference, decision)
|
|
30
31
|
|
|
@@ -104,6 +105,9 @@ Follow '~/.maestro/workflows/specs-add.md' completely.
|
|
|
104
105
|
| Condition | Suggestion |
|
|
105
106
|
|-----------|-----------|
|
|
106
107
|
| Verify entry added | `maestro load --type spec --scope <scope> --keyword {keyword}` |
|
|
108
|
+
| New entry replaces old one | `maestro spec supersede <old-sid> --by <new-sid>` |
|
|
109
|
+
| View evolution chain | `maestro spec history <sid>` |
|
|
107
110
|
| Add more entries | `/spec-add <category>` |
|
|
108
111
|
| View all specs | `/spec-load --category <category>` |
|
|
112
|
+
| Check knowledge health | `maestro spec health` |
|
|
109
113
|
</completion>
|
|
@@ -48,7 +48,7 @@ Additional flags, source registry (scan paths), and storage locations defined in
|
|
|
48
48
|
2. **Never modify source artifacts** — harvest is purely extractive; source files remain untouched
|
|
49
49
|
3. **Dedup before write** — MUST check harvest-log.jsonl and existing stores before each write to prevent duplicates
|
|
50
50
|
4. **Source tagging** — MUST set `source: "harvest"` on every issues.jsonl row so concurrent writers can be distinguished
|
|
51
|
-
5. **
|
|
51
|
+
5. **Relationship pre-check on spec routing** — when routing to spec, MUST compare against existing specs with same keywords/category. Classify the relationship: **supersede** (new replaces old) → attach `supersedes = <old-sid>`, after add run `maestro spec supersede`; **conflict** (genuine dispute) → set `confidence="low"` and log conflict note; **independent** → no metadata
|
|
52
52
|
6. **Provenance tracking** — every routed item MUST be logged in harvest-log.jsonl with fragment ID, target store, and timestamp
|
|
53
53
|
7. **Dry-run safety** — `--dry-run` MUST NOT write any files; preview only
|
|
54
54
|
</invariants>
|
|
@@ -88,8 +88,10 @@ Extraction patterns, classification rules, routing infrastructure, and fragment
|
|
|
88
88
|
| Wiki graph needs linking | `/manage-wiki connect --fix` |
|
|
89
89
|
| Issues created | `/manage-issue list --source harvest` |
|
|
90
90
|
| Specs extracted | `/spec-load --role implement` |
|
|
91
|
-
| Specs extracted (
|
|
91
|
+
| Specs extracted (审查) | `/manage-knowledge-audit --scope spec` — 新写入的 spec 可能与现有条目矛盾或替代 |
|
|
92
|
+
| 查看演化链 | `maestro spec history <sid>` — 确认 supersede 链完整 |
|
|
92
93
|
| Spec 冲突标记已存在 | `maestro spec conflict list` — 查看当前冲突状态 |
|
|
94
|
+
| 知识健康检查 | `maestro spec health` — 悬空/循环 supersedes 校验 |
|
|
93
95
|
| Full phase retrospective | `/quality-retrospective` |
|
|
94
96
|
</completion>
|
|
95
97
|
|
|
@@ -83,15 +83,17 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
83
83
|
|
|
84
84
|
### Conflict Resolution Integration
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
五态决策(扩展自三态 keep/deprecate/delete):
|
|
87
87
|
|
|
88
88
|
| 动作 | 适用场景 | 执行 |
|
|
89
89
|
|------|---------|------|
|
|
90
90
|
| `keep` | 内容正确,无需变更 | 写 audit-log ignore 记录 |
|
|
91
91
|
| `contest` | 矛盾真实存在,需进一步审查 | `maestro spec conflict mark <file> <line> --note "<evidence>"` |
|
|
92
|
-
| `
|
|
92
|
+
| `supersede` | 内容过时,已有更新版本替代 | `maestro spec supersede <old-sid> --by <new-sid>`(保留演化链) |
|
|
93
|
+
| `deprecate` | 内容过时,无替代版本 | 注入 `status="deprecated"` + `maestro spec conflict clear <file> <line>` |
|
|
93
94
|
| `delete` | 内容明确错误 | 移除 entry + `maestro spec conflict clear <file> <line>` |
|
|
94
95
|
|
|
96
|
+
**supersede vs deprecate**: supersede 用于有明确替代条目的场景(建立演化链),deprecate 用于无替代条目的场景。
|
|
95
97
|
**关键**: deprecate/delete 执行时,如果目标条目有 conflict-marker,必须同步调用 `maestro spec conflict clear` 清除标记,避免悬空冲突。
|
|
96
98
|
|
|
97
99
|
### Code-as-Truth 校验(审查核心原则)
|
|
@@ -117,6 +119,9 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
117
119
|
| 验证 spec 现状 | `/spec-load --role implement` |
|
|
118
120
|
| 查看冲突标记 | `maestro spec conflict list` |
|
|
119
121
|
| 清除已解决冲突 | `maestro spec conflict clear-all <file>` |
|
|
122
|
+
| 查看演化链 | `maestro spec history <sid>` |
|
|
123
|
+
| 知识健康检查 | `maestro spec health` |
|
|
124
|
+
| 回填存量 sid | `maestro spec backfill-sid` |
|
|
120
125
|
| 周期巡检 | `--scope all --report` |
|
|
121
126
|
</completion>
|
|
122
127
|
|
|
@@ -66,7 +66,7 @@ Each artifact's type determines its outputs at `.workflow/{a.path}/`:
|
|
|
66
66
|
3. **Verdict is data-driven** — NEVER change verdict severity to accommodate user preference without new evidence. Verdicts flow from findings, not negotiation.
|
|
67
67
|
4. **Dimension independence** — each review dimension produces findings independently. One dimension's results MUST NOT suppress or override another's.
|
|
68
68
|
5. **Prior review delta** — when a prior review.json exists for the same phase, findings MUST be compared. Do NOT re-report already-resolved findings as new.
|
|
69
|
-
6. **Spec conflict integrity** — if code contradicts a spec entry, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
69
|
+
6. **Spec conflict integrity** — if code contradicts a spec entry: if the code is the evolved practice (spec outdated), suggest `maestro spec supersede`; if genuinely disputed, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
70
70
|
</invariants>
|
|
71
71
|
|
|
72
72
|
<execution>
|
|
@@ -87,7 +87,7 @@ Follow '~/.maestro/workflows/review.md' completely.
|
|
|
87
87
|
- REQUIRED: review.json written with findings, severity distribution, and verdict.
|
|
88
88
|
- REQUIRED: Issues auto-created based on level thresholds.
|
|
89
89
|
- REQUIRED: index.json updated with review status.
|
|
90
|
-
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule), suggest `maestro spec
|
|
90
|
+
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule): if spec is outdated (code evolved), suggest `maestro spec supersede`; if genuinely disputed, suggest `maestro spec conflict mark`. Code is the single source of truth.
|
|
91
91
|
|
|
92
92
|
**Output writes to REVIEW_DIR** (not EXEC_DIR):
|
|
93
93
|
- `REVIEW_DIR/review.json` — findings, severity distribution, verdict
|
|
@@ -22,6 +22,7 @@ $ARGUMENTS -- expects `[--scope <scope>] [--uid <uid>] <category> <content>`
|
|
|
22
22
|
|
|
23
23
|
**Options:**
|
|
24
24
|
- `--description <desc>` — One-line description for search results (falls back to content[:240])
|
|
25
|
+
- `--json` — Output JSON with generated `sid` (needed for supersession: `maestro spec supersede <old-sid> --by <new-sid>`)
|
|
25
26
|
- `--ref <path>` — Create as index entry referencing a knowhow document. If the path exists, only creates the spec index entry. If path doesn't exist, also creates the knowhow file.
|
|
26
27
|
- `--knowhow-type <type>` — Knowhow document type when creating with --ref (asset, blueprint, document, template, recipe, reference, decision)
|
|
27
28
|
|
|
@@ -101,6 +102,9 @@ Follow '~/.maestro/workflows/specs-add.md' completely.
|
|
|
101
102
|
| Condition | Suggestion |
|
|
102
103
|
|-----------|-----------|
|
|
103
104
|
| Verify entry added | `maestro load --type spec --scope <scope> --keyword {keyword}` |
|
|
105
|
+
| New entry replaces old one | `maestro spec supersede <old-sid> --by <new-sid>` |
|
|
106
|
+
| View evolution chain | `maestro spec history <sid>` |
|
|
104
107
|
| Add more entries | `/spec-add <category>` |
|
|
105
108
|
| View all specs | `/spec-load --category <category>` |
|
|
109
|
+
| Check knowledge health | `maestro spec health` |
|
|
106
110
|
</completion>
|
|
@@ -46,7 +46,7 @@ Additional flags, source registry (scan paths), and storage locations defined in
|
|
|
46
46
|
2. **Never modify source artifacts** — harvest is purely extractive; source files remain untouched
|
|
47
47
|
3. **Dedup before write** — MUST check harvest-log.jsonl and existing stores before each write to prevent duplicates
|
|
48
48
|
4. **Source tagging** — MUST set `source: "harvest"` on every issues.jsonl row so concurrent writers can be distinguished
|
|
49
|
-
5. **
|
|
49
|
+
5. **Relationship pre-check on spec routing** — when routing to spec, MUST compare against existing specs with same keywords/category. Classify the relationship: **supersede** (new replaces old) → attach `supersedes = <old-sid>`, after add run `maestro spec supersede`; **conflict** (genuine dispute) → set `confidence="low"` and log conflict note; **independent** → no metadata
|
|
50
50
|
6. **Provenance tracking** — every routed item MUST be logged in harvest-log.jsonl with fragment ID, target store, and timestamp
|
|
51
51
|
7. **Dry-run safety** — `--dry-run` MUST NOT write any files; preview only
|
|
52
52
|
</invariants>
|
|
@@ -86,8 +86,10 @@ Extraction patterns, classification rules, routing infrastructure, and fragment
|
|
|
86
86
|
| Wiki graph needs linking | `/manage-wiki connect --fix` |
|
|
87
87
|
| Issues created | `/manage-issue list --source harvest` |
|
|
88
88
|
| Specs extracted | `/spec-load --role implement` |
|
|
89
|
-
| Specs extracted (
|
|
89
|
+
| Specs extracted (审查) | `/manage-knowledge-audit --scope spec` — 新写入的 spec 可能与现有条目矛盾或替代 |
|
|
90
|
+
| 查看演化链 | `maestro spec history <sid>` — 确认 supersede 链完整 |
|
|
90
91
|
| Spec 冲突标记已存在 | `maestro spec conflict list` — 查看当前冲突状态 |
|
|
92
|
+
| 知识健康检查 | `maestro spec health` — 悬空/循环 supersedes 校验 |
|
|
91
93
|
| Full phase retrospective | `/quality-retrospective` |
|
|
92
94
|
</completion>
|
|
93
95
|
|
|
@@ -81,15 +81,17 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
81
81
|
|
|
82
82
|
### Conflict Resolution Integration
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
五态决策(扩展自三态 keep/deprecate/delete):
|
|
85
85
|
|
|
86
86
|
| 动作 | 适用场景 | 执行 |
|
|
87
87
|
|------|---------|------|
|
|
88
88
|
| `keep` | 内容正确,无需变更 | 写 audit-log ignore 记录 |
|
|
89
89
|
| `contest` | 矛盾真实存在,需进一步审查 | `maestro spec conflict mark <file> <line> --note "<evidence>"` |
|
|
90
|
-
| `
|
|
90
|
+
| `supersede` | 内容过时,已有更新版本替代 | `maestro spec supersede <old-sid> --by <new-sid>`(保留演化链) |
|
|
91
|
+
| `deprecate` | 内容过时,无替代版本 | 注入 `status="deprecated"` + `maestro spec conflict clear <file> <line>` |
|
|
91
92
|
| `delete` | 内容明确错误 | 移除 entry + `maestro spec conflict clear <file> <line>` |
|
|
92
93
|
|
|
94
|
+
**supersede vs deprecate**: supersede 用于有明确替代条目的场景(建立演化链),deprecate 用于无替代条目的场景。
|
|
93
95
|
**关键**: deprecate/delete 执行时,如果目标条目有 conflict-marker,必须同步调用 `maestro spec conflict clear` 清除标记,避免悬空冲突。
|
|
94
96
|
|
|
95
97
|
### Code-as-Truth 校验(审查核心原则)
|
|
@@ -115,6 +117,9 @@ Follow `~/.maestro/workflows/knowledge-audit.md` Stages 1-8 in order.
|
|
|
115
117
|
| 验证 spec 现状 | `/spec-load --role implement` |
|
|
116
118
|
| 查看冲突标记 | `maestro spec conflict list` |
|
|
117
119
|
| 清除已解决冲突 | `maestro spec conflict clear-all <file>` |
|
|
120
|
+
| 查看演化链 | `maestro spec history <sid>` |
|
|
121
|
+
| 知识健康检查 | `maestro spec health` |
|
|
122
|
+
| 回填存量 sid | `maestro spec backfill-sid` |
|
|
118
123
|
| 周期巡检 | `--scope all --report` |
|
|
119
124
|
</completion>
|
|
120
125
|
|
|
@@ -64,7 +64,7 @@ Each artifact's type determines its outputs at `.workflow/{a.path}/`:
|
|
|
64
64
|
3. **Verdict is data-driven** — NEVER change verdict severity to accommodate user preference without new evidence. Verdicts flow from findings, not negotiation.
|
|
65
65
|
4. **Dimension independence** — each review dimension produces findings independently. One dimension's results MUST NOT suppress or override another's.
|
|
66
66
|
5. **Prior review delta** — when a prior review.json exists for the same phase, findings MUST be compared. Do NOT re-report already-resolved findings as new.
|
|
67
|
-
6. **Spec conflict integrity** — if code contradicts a spec entry, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
67
|
+
6. **Spec conflict integrity** — if code contradicts a spec entry: if the code is the evolved practice (spec outdated), suggest `maestro spec supersede`; if genuinely disputed, flag via `maestro spec conflict mark`. NEVER silently accept the contradiction or edit the spec inline.
|
|
68
68
|
</invariants>
|
|
69
69
|
|
|
70
70
|
<execution>
|
|
@@ -85,7 +85,7 @@ Follow '~/.maestro/workflows/review.md' completely.
|
|
|
85
85
|
- REQUIRED: review.json written with findings, severity distribution, and verdict.
|
|
86
86
|
- REQUIRED: Issues auto-created based on level thresholds.
|
|
87
87
|
- REQUIRED: index.json updated with review status.
|
|
88
|
-
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule), suggest `maestro spec
|
|
88
|
+
- REQUIRED: Spec conflict check — if any finding directly contradicts a loaded spec entry (code behavior ≠ spec rule): if spec is outdated (code evolved), suggest `maestro spec supersede`; if genuinely disputed, suggest `maestro spec conflict mark`. Code is the single source of truth.
|
|
89
89
|
|
|
90
90
|
**Output writes to REVIEW_DIR** (not EXEC_DIR):
|
|
91
91
|
- `REVIEW_DIR/review.json` — findings, severity distribution, verdict
|
|
@@ -23,6 +23,7 @@ $ARGUMENTS -- expects `[--scope <scope>] [--uid <uid>] <category> <content>`
|
|
|
23
23
|
|
|
24
24
|
**Options:**
|
|
25
25
|
- `--description <desc>` — One-line description for search results (falls back to content[:240])
|
|
26
|
+
- `--json` — Output JSON with generated `sid` (needed for supersession: `maestro spec supersede <old-sid> --by <new-sid>`)
|
|
26
27
|
- `--ref <path>` — Create as index entry referencing a knowhow document. If the path exists, only creates the spec index entry. If path doesn't exist, also creates the knowhow file.
|
|
27
28
|
- `--knowhow-type <type>` — Knowhow document type when creating with --ref (asset, blueprint, document, template, recipe, reference, decision)
|
|
28
29
|
|
|
@@ -102,6 +103,9 @@ Follow '~/.maestro/workflows/specs-add.md' completely.
|
|
|
102
103
|
| Condition | Suggestion |
|
|
103
104
|
|-----------|-----------|
|
|
104
105
|
| Verify entry added | `maestro load --type spec --scope <scope> --keyword {keyword}` |
|
|
106
|
+
| New entry replaces old one | `maestro spec supersede <old-sid> --by <new-sid>` |
|
|
107
|
+
| View evolution chain | `maestro spec history <sid>` |
|
|
105
108
|
| Add more entries | `/spec-add <category>` |
|
|
106
109
|
| View all specs | `/spec-load --category <category>` |
|
|
110
|
+
| Check knowledge health | `maestro spec health` |
|
|
107
111
|
</completion>
|
|
@@ -100,7 +100,7 @@ export declare function vectorSearch(queryVector: Float32Array, index: Embedding
|
|
|
100
100
|
* Falls back to flat cosine scan when zvec is unavailable or feature flag is set.
|
|
101
101
|
*/
|
|
102
102
|
export declare function vectorSearchZvec(queryVector: Float32Array, dir: string, limit: number): Promise<VectorSearchResult[]>;
|
|
103
|
-
export declare function saveEmbeddingIndex(index: EmbeddingIndex, dir: string): void
|
|
103
|
+
export declare function saveEmbeddingIndex(index: EmbeddingIndex, dir: string): Promise<void>;
|
|
104
104
|
export declare function loadEmbeddingIndex(dir: string): EmbeddingIndex | null;
|
|
105
105
|
export interface DocForEmbedding {
|
|
106
106
|
id: string;
|
|
@@ -109,7 +109,7 @@ export interface DocForEmbedding {
|
|
|
109
109
|
tags: string[];
|
|
110
110
|
body?: string;
|
|
111
111
|
}
|
|
112
|
-
export declare function hashDocContent(d: DocForEmbedding): string;
|
|
112
|
+
export declare function hashDocContent(d: DocForEmbedding, enrichedText?: string): string;
|
|
113
113
|
/**
|
|
114
114
|
* Split a document into multiple chunks for embedding.
|
|
115
115
|
* Short docs (<500 chars body) produce a single chunk.
|
|
@@ -198,8 +198,6 @@ async function callEmbeddingApi(texts, config) {
|
|
|
198
198
|
}
|
|
199
199
|
if (firstErr) {
|
|
200
200
|
const filled = results.filter(Boolean).length;
|
|
201
|
-
if (filled === 0)
|
|
202
|
-
throw firstErr;
|
|
203
201
|
if (filled < texts.length)
|
|
204
202
|
throw firstErr;
|
|
205
203
|
}
|
|
@@ -472,12 +470,6 @@ const ZVEC_DIR = 'embedding.zvec';
|
|
|
472
470
|
export function vectorSearch(queryVector, index, limit) {
|
|
473
471
|
if (index.dimension && queryVector.length !== index.dimension)
|
|
474
472
|
return [];
|
|
475
|
-
// Feature flag: force flat cosine scan (bypass zvec)
|
|
476
|
-
if (process.env.MAESTRO_EMBEDDING_FLAT_SCAN) {
|
|
477
|
-
return flatCosineSearch(queryVector, index, limit);
|
|
478
|
-
}
|
|
479
|
-
// Sync path — zvec requires async setup, so use flat scan here.
|
|
480
|
-
// For zvec-accelerated search, callers should use vectorSearchZvec.
|
|
481
473
|
return flatCosineSearch(queryVector, index, limit);
|
|
482
474
|
}
|
|
483
475
|
/**
|
|
@@ -533,7 +525,7 @@ const SQLITE_FILE = 'embedding-index.db';
|
|
|
533
525
|
import { createRequire } from 'node:module';
|
|
534
526
|
const _require = createRequire(import.meta.url);
|
|
535
527
|
const BINARY_FILE = 'embedding-index.bin';
|
|
536
|
-
export function saveEmbeddingIndex(index, dir) {
|
|
528
|
+
export async function saveEmbeddingIndex(index, dir) {
|
|
537
529
|
mkdirSync(dir, { recursive: true });
|
|
538
530
|
// --- Binary format (kept for backward compat and feature flag fallback) ---
|
|
539
531
|
const dim = index.dimension;
|
|
@@ -573,10 +565,8 @@ export function saveEmbeddingIndex(index, dir) {
|
|
|
573
565
|
const tmpPath = join(dir, BINARY_FILE + '.tmp');
|
|
574
566
|
writeFileSync(tmpPath, buf);
|
|
575
567
|
renameSync(tmpPath, join(dir, BINARY_FILE));
|
|
576
|
-
// --- zvec collection save
|
|
577
|
-
saveZvecIndex(index, dir)
|
|
578
|
-
// zvec save failed — binary format still available as fallback
|
|
579
|
-
});
|
|
568
|
+
// --- zvec collection save ---
|
|
569
|
+
await saveZvecIndex(index, dir);
|
|
580
570
|
// Remove legacy files
|
|
581
571
|
for (const f of [CACHE_FILE, SQLITE_FILE, SQLITE_FILE + '-shm', SQLITE_FILE + '-wal', SQLITE_FILE + '-journal']) {
|
|
582
572
|
try {
|
|
@@ -586,14 +576,26 @@ export function saveEmbeddingIndex(index, dir) {
|
|
|
586
576
|
catch { /* ignore */ }
|
|
587
577
|
}
|
|
588
578
|
}
|
|
579
|
+
let _zvecSaving = false;
|
|
589
580
|
/**
|
|
590
581
|
* Save embedding index to zvec collection format.
|
|
591
582
|
* Creates/replaces a zvec collection at `dir/embedding.zvec`.
|
|
592
583
|
*/
|
|
593
584
|
async function saveZvecIndex(index, dir) {
|
|
585
|
+
if (_zvecSaving)
|
|
586
|
+
return;
|
|
594
587
|
const zvec = await getZvec();
|
|
595
588
|
if (!zvec)
|
|
596
589
|
return;
|
|
590
|
+
_zvecSaving = true;
|
|
591
|
+
try {
|
|
592
|
+
await _saveZvecIndexInner(zvec, index, dir);
|
|
593
|
+
}
|
|
594
|
+
finally {
|
|
595
|
+
_zvecSaving = false;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
async function _saveZvecIndexInner(zvec, index, dir) {
|
|
597
599
|
const collectionPath = join(dir, ZVEC_DIR);
|
|
598
600
|
const dim = index.dimension;
|
|
599
601
|
// Remove existing collection directory if present
|
|
@@ -692,7 +694,7 @@ export function loadEmbeddingIndex(dir) {
|
|
|
692
694
|
if (existsSync(dbPath)) {
|
|
693
695
|
try {
|
|
694
696
|
const idx = loadFromSqlite(dir);
|
|
695
|
-
saveEmbeddingIndex(idx, dir);
|
|
697
|
+
void saveEmbeddingIndex(idx, dir);
|
|
696
698
|
return idx;
|
|
697
699
|
}
|
|
698
700
|
catch { /* fall through */ }
|
|
@@ -702,7 +704,7 @@ export function loadEmbeddingIndex(dir) {
|
|
|
702
704
|
if (existsSync(jsonPath)) {
|
|
703
705
|
try {
|
|
704
706
|
const idx = loadFromLegacyJson(jsonPath);
|
|
705
|
-
saveEmbeddingIndex(idx, dir);
|
|
707
|
+
void saveEmbeddingIndex(idx, dir);
|
|
706
708
|
return idx;
|
|
707
709
|
}
|
|
708
710
|
catch {
|
|
@@ -848,9 +850,11 @@ function loadFromLegacyJson(filePath) {
|
|
|
848
850
|
buildTimeMs: raw.buildTimeMs,
|
|
849
851
|
};
|
|
850
852
|
}
|
|
851
|
-
export function hashDocContent(d) {
|
|
852
|
-
const
|
|
853
|
-
|
|
853
|
+
export function hashDocContent(d, enrichedText) {
|
|
854
|
+
const parts = [d.title, d.summary, d.tags.join(','), d.body ?? ''];
|
|
855
|
+
if (enrichedText)
|
|
856
|
+
parts.push(enrichedText);
|
|
857
|
+
return createHash('md5').update(parts.join('|')).digest('hex');
|
|
854
858
|
}
|
|
855
859
|
/**
|
|
856
860
|
* Extract meaningful content from a markdown body: first paragraph + heading lines,
|
|
@@ -938,7 +942,7 @@ export async function buildEmbeddingIndex(docs, existingIndex, precomputedHashes
|
|
|
938
942
|
const apiMode = isApiMode();
|
|
939
943
|
const config = apiMode ? null : await detectDevice();
|
|
940
944
|
const t0 = Date.now();
|
|
941
|
-
const currentHashes = precomputedHashes ?? docs.map(hashDocContent);
|
|
945
|
+
const currentHashes = precomputedHashes ?? docs.map(d => hashDocContent(d));
|
|
942
946
|
// Split all docs into chunks (1:N doc-to-chunk mapping)
|
|
943
947
|
const allChunkIds = [];
|
|
944
948
|
const allChunkDocIds = [];
|
|
@@ -957,34 +961,21 @@ export async function buildEmbeddingIndex(docs, existingIndex, precomputedHashes
|
|
|
957
961
|
}
|
|
958
962
|
let vectors;
|
|
959
963
|
const activeModel = getModelId();
|
|
960
|
-
|
|
961
|
-
|
|
964
|
+
const activeDim = apiMode ? (loadEmbeddingApiConfig()?.dimensions ?? 0) : 384;
|
|
965
|
+
// Model, dimensions, or mode changed → discard all cached vectors, force full rebuild
|
|
966
|
+
const modelMatch = existingIndex
|
|
967
|
+
&& existingIndex.modelId === activeModel
|
|
968
|
+
&& (activeDim === 0 || existingIndex.dimension === activeDim);
|
|
962
969
|
if (modelMatch && existingIndex.docIds.length > 0) {
|
|
963
|
-
// Build existing chunk cache: chunkId → { vector, parentDocId }
|
|
964
970
|
const existingChunkMap = new Map();
|
|
965
|
-
const existingDocHashes = new Map();
|
|
966
|
-
// Reconstruct per-doc hashes from existing index
|
|
967
971
|
if (existingIndex.chunkDocIds && existingIndex.contentHashes) {
|
|
968
972
|
for (let i = 0; i < existingIndex.docIds.length; i++) {
|
|
969
973
|
existingChunkMap.set(existingIndex.docIds[i], existingIndex.vectors[i]);
|
|
970
974
|
}
|
|
971
|
-
// contentHashes are per-doc; find unique doc→hash mapping
|
|
972
|
-
const seen = new Set();
|
|
973
|
-
for (let i = 0; i < existingIndex.chunkDocIds.length; i++) {
|
|
974
|
-
const parentId = existingIndex.chunkDocIds[i];
|
|
975
|
-
if (!seen.has(parentId) && existingIndex.contentHashes[i] !== undefined) {
|
|
976
|
-
// contentHashes in chunk-based index: stored per-doc in the order of docChunkRanges
|
|
977
|
-
seen.add(parentId);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
975
|
}
|
|
981
976
|
else {
|
|
982
|
-
// Legacy index without chunkDocIds — docIds are direct doc IDs
|
|
983
977
|
for (let i = 0; i < existingIndex.docIds.length; i++) {
|
|
984
978
|
existingChunkMap.set(existingIndex.docIds[i], existingIndex.vectors[i]);
|
|
985
|
-
if (existingIndex.contentHashes?.[i]) {
|
|
986
|
-
existingDocHashes.set(existingIndex.docIds[i], existingIndex.contentHashes[i]);
|
|
987
|
-
}
|
|
988
979
|
}
|
|
989
980
|
}
|
|
990
981
|
// Determine which docs changed (hash comparison at doc level)
|