@mainahq/core 1.0.3 → 1.1.1
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/package.json +1 -1
- package/src/ai/__tests__/delegation.test.ts +55 -1
- package/src/ai/delegation.ts +5 -3
- package/src/context/__tests__/budget.test.ts +29 -6
- package/src/context/__tests__/engine.test.ts +1 -0
- package/src/context/__tests__/selector.test.ts +23 -3
- package/src/context/__tests__/wiki.test.ts +349 -0
- package/src/context/budget.ts +12 -8
- package/src/context/engine.ts +37 -0
- package/src/context/selector.ts +30 -4
- package/src/context/wiki.ts +296 -0
- package/src/db/index.ts +12 -0
- package/src/feedback/__tests__/capture.test.ts +166 -0
- package/src/feedback/__tests__/signals.test.ts +144 -0
- package/src/feedback/__tests__/tmp-capture-1775575256633-lah0etnzlj/feedback.db +0 -0
- package/src/feedback/__tests__/tmp-capture-1775575256640-2xmjme4qraa/feedback.db +0 -0
- package/src/feedback/capture.ts +102 -0
- package/src/feedback/signals.ts +68 -0
- package/src/index.ts +104 -0
- package/src/init/__tests__/init.test.ts +400 -3
- package/src/init/index.ts +368 -12
- package/src/language/__tests__/__fixtures__/detect/composer.lock +1 -0
- package/src/prompts/defaults/index.ts +3 -1
- package/src/prompts/defaults/wiki-compile.md +20 -0
- package/src/prompts/defaults/wiki-query.md +18 -0
- package/src/stats/__tests__/tool-usage.test.ts +133 -0
- package/src/stats/tracker.ts +92 -0
- package/src/verify/__tests__/pipeline.test.ts +11 -8
- package/src/verify/pipeline.ts +13 -1
- package/src/verify/tools/__tests__/wiki-lint.test.ts +784 -0
- package/src/verify/tools/wiki-lint-runner.ts +38 -0
- package/src/verify/tools/wiki-lint.ts +898 -0
- package/src/wiki/__tests__/compiler.test.ts +389 -0
- package/src/wiki/__tests__/extractors/code.test.ts +99 -0
- package/src/wiki/__tests__/extractors/decision.test.ts +323 -0
- package/src/wiki/__tests__/extractors/feature.test.ts +186 -0
- package/src/wiki/__tests__/extractors/workflow.test.ts +131 -0
- package/src/wiki/__tests__/graph.test.ts +344 -0
- package/src/wiki/__tests__/hooks.test.ts +119 -0
- package/src/wiki/__tests__/indexer.test.ts +285 -0
- package/src/wiki/__tests__/linker.test.ts +230 -0
- package/src/wiki/__tests__/louvain.test.ts +229 -0
- package/src/wiki/__tests__/query.test.ts +316 -0
- package/src/wiki/__tests__/schema.test.ts +114 -0
- package/src/wiki/__tests__/signals.test.ts +474 -0
- package/src/wiki/__tests__/state.test.ts +168 -0
- package/src/wiki/__tests__/tracking.test.ts +118 -0
- package/src/wiki/__tests__/types.test.ts +387 -0
- package/src/wiki/compiler.ts +1075 -0
- package/src/wiki/extractors/code.ts +90 -0
- package/src/wiki/extractors/decision.ts +217 -0
- package/src/wiki/extractors/feature.ts +206 -0
- package/src/wiki/extractors/workflow.ts +112 -0
- package/src/wiki/graph.ts +445 -0
- package/src/wiki/hooks.ts +49 -0
- package/src/wiki/indexer.ts +105 -0
- package/src/wiki/linker.ts +117 -0
- package/src/wiki/louvain.ts +190 -0
- package/src/wiki/prompts/compile-architecture.md +59 -0
- package/src/wiki/prompts/compile-decision.md +66 -0
- package/src/wiki/prompts/compile-entity.md +56 -0
- package/src/wiki/prompts/compile-feature.md +60 -0
- package/src/wiki/prompts/compile-module.md +42 -0
- package/src/wiki/prompts/wiki-query.md +25 -0
- package/src/wiki/query.ts +338 -0
- package/src/wiki/schema.ts +111 -0
- package/src/wiki/signals.ts +368 -0
- package/src/wiki/state.ts +89 -0
- package/src/wiki/tracking.ts +30 -0
- package/src/wiki/types.ts +169 -0
- package/src/workflow/context.ts +26 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Louvain Community Detection — identifies module boundaries in the knowledge graph.
|
|
3
|
+
*
|
|
4
|
+
* Implements the Louvain method for community detection:
|
|
5
|
+
* 1. Start each node in its own community
|
|
6
|
+
* 2. For each node, try moving to a neighbor's community if it improves modularity
|
|
7
|
+
* 3. Repeat until no improvement (convergence)
|
|
8
|
+
* 4. Return communities map + modularity score
|
|
9
|
+
*
|
|
10
|
+
* Deterministic: nodes are sorted before iteration. Handles disconnected components.
|
|
11
|
+
* Scales to 1000+ nodes in < 1 second.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// ─── Types ───────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
export interface LouvainNode {
|
|
17
|
+
id: string;
|
|
18
|
+
community: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface LouvainResult {
|
|
22
|
+
communities: Map<number, string[]>;
|
|
23
|
+
modularity: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ─── Modularity Helpers ─────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Total number of edges (each undirected edge counted once).
|
|
30
|
+
*/
|
|
31
|
+
function totalEdges(adjacency: Map<string, Set<string>>): number {
|
|
32
|
+
let count = 0;
|
|
33
|
+
for (const neighbors of adjacency.values()) {
|
|
34
|
+
count += neighbors.size;
|
|
35
|
+
}
|
|
36
|
+
// Each edge is counted twice in an undirected adjacency list
|
|
37
|
+
return count / 2;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Compute modularity for the current community assignment.
|
|
42
|
+
* Q = (1/2m) * sum_ij [ A_ij - (k_i * k_j) / 2m ] * delta(c_i, c_j)
|
|
43
|
+
*/
|
|
44
|
+
function computeModularity(
|
|
45
|
+
adjacency: Map<string, Set<string>>,
|
|
46
|
+
communityOf: Map<string, number>,
|
|
47
|
+
m: number,
|
|
48
|
+
): number {
|
|
49
|
+
if (m === 0) return 0;
|
|
50
|
+
|
|
51
|
+
let q = 0;
|
|
52
|
+
const twoM = 2 * m;
|
|
53
|
+
|
|
54
|
+
for (const [nodeI, neighbors] of adjacency) {
|
|
55
|
+
const ci = communityOf.get(nodeI) ?? -1;
|
|
56
|
+
const ki = neighbors.size;
|
|
57
|
+
|
|
58
|
+
for (const nodeJ of neighbors) {
|
|
59
|
+
const cj = communityOf.get(nodeJ) ?? -1;
|
|
60
|
+
if (ci !== cj) continue;
|
|
61
|
+
|
|
62
|
+
const kj = adjacency.get(nodeJ)?.size ?? 0;
|
|
63
|
+
// A_ij = 1 since nodeJ is in neighbors of nodeI
|
|
64
|
+
q += 1 - (ki * kj) / twoM;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return q / twoM;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ─── Public API ──────────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Detect communities using the Louvain method.
|
|
75
|
+
* Input: adjacency list (node -> Set<neighbor>).
|
|
76
|
+
* Output: communities map (community ID -> node IDs) + modularity score.
|
|
77
|
+
*
|
|
78
|
+
* Optimized with pre-computed degree map and running community degree totals
|
|
79
|
+
* to avoid O(N) scan per modularity gain computation.
|
|
80
|
+
*/
|
|
81
|
+
export function detectCommunities(
|
|
82
|
+
adjacency: Map<string, Set<string>>,
|
|
83
|
+
): LouvainResult {
|
|
84
|
+
const nodes = [...adjacency.keys()].sort();
|
|
85
|
+
|
|
86
|
+
if (nodes.length === 0) {
|
|
87
|
+
return { communities: new Map(), modularity: 0 };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const m = totalEdges(adjacency);
|
|
91
|
+
|
|
92
|
+
// Pre-compute degrees
|
|
93
|
+
const deg = new Map<string, number>();
|
|
94
|
+
for (const [node, neighbors] of adjacency) {
|
|
95
|
+
deg.set(node, neighbors.size);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Phase 1: Assign each node to its own community
|
|
99
|
+
const communityOf = new Map<string, number>();
|
|
100
|
+
// Track sum of degrees per community for O(1) lookup
|
|
101
|
+
const commSumTot = new Map<number, number>();
|
|
102
|
+
|
|
103
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
104
|
+
const node = nodes[i] ?? "";
|
|
105
|
+
communityOf.set(node, i);
|
|
106
|
+
commSumTot.set(i, deg.get(node) ?? 0);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Phase 2: Iteratively move nodes to improve modularity
|
|
110
|
+
const maxIterations = 100;
|
|
111
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
112
|
+
let improved = false;
|
|
113
|
+
|
|
114
|
+
for (const nodeId of nodes) {
|
|
115
|
+
const currentComm = communityOf.get(nodeId) ?? 0;
|
|
116
|
+
const neighbors = adjacency.get(nodeId) ?? new Set<string>();
|
|
117
|
+
const ki = deg.get(nodeId) ?? 0;
|
|
118
|
+
|
|
119
|
+
if (ki === 0) continue;
|
|
120
|
+
|
|
121
|
+
// Find neighbor communities and count edges into each
|
|
122
|
+
const neighborCommEdges = new Map<number, number>();
|
|
123
|
+
for (const neighbor of neighbors) {
|
|
124
|
+
const nc = communityOf.get(neighbor) ?? -1;
|
|
125
|
+
neighborCommEdges.set(nc, (neighborCommEdges.get(nc) ?? 0) + 1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Current community edges (k_in for current)
|
|
129
|
+
const kInCurrent = neighborCommEdges.get(currentComm) ?? 0;
|
|
130
|
+
// sumTot for current community minus this node's own degree
|
|
131
|
+
const sumTotCurrent = (commSumTot.get(currentComm) ?? 0) - ki;
|
|
132
|
+
|
|
133
|
+
let bestGain = 0;
|
|
134
|
+
let bestComm = currentComm;
|
|
135
|
+
|
|
136
|
+
// Evaluate moving to each neighbor community
|
|
137
|
+
const candidateComms = [...neighborCommEdges.keys()]
|
|
138
|
+
.filter((c) => c !== currentComm)
|
|
139
|
+
.sort((a, b) => a - b);
|
|
140
|
+
|
|
141
|
+
for (const candidateComm of candidateComms) {
|
|
142
|
+
const kInCandidate = neighborCommEdges.get(candidateComm) ?? 0;
|
|
143
|
+
const sumTotCandidate = commSumTot.get(candidateComm) ?? 0;
|
|
144
|
+
|
|
145
|
+
// delta_Q = [k_in_new / m - ki * sumTot_new / (2m^2)]
|
|
146
|
+
// - [k_in_old / m - ki * sumTot_old / (2m^2)]
|
|
147
|
+
const gainNew = kInCandidate / m - (ki * sumTotCandidate) / (2 * m * m);
|
|
148
|
+
const lossCurrent = kInCurrent / m - (ki * sumTotCurrent) / (2 * m * m);
|
|
149
|
+
const netGain = gainNew - lossCurrent;
|
|
150
|
+
|
|
151
|
+
if (netGain > bestGain) {
|
|
152
|
+
bestGain = netGain;
|
|
153
|
+
bestComm = candidateComm;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (bestComm !== currentComm) {
|
|
158
|
+
// Update community assignment and running totals
|
|
159
|
+
commSumTot.set(currentComm, (commSumTot.get(currentComm) ?? 0) - ki);
|
|
160
|
+
commSumTot.set(bestComm, (commSumTot.get(bestComm) ?? 0) + ki);
|
|
161
|
+
communityOf.set(nodeId, bestComm);
|
|
162
|
+
improved = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!improved) break;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Phase 3: Build communities map, renumbering to be contiguous
|
|
170
|
+
const rawCommunities = new Map<number, string[]>();
|
|
171
|
+
for (const [node, comm] of communityOf) {
|
|
172
|
+
const list = rawCommunities.get(comm) ?? [];
|
|
173
|
+
list.push(node);
|
|
174
|
+
rawCommunities.set(comm, list);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Renumber communities to 0..N-1
|
|
178
|
+
const communities = new Map<number, string[]>();
|
|
179
|
+
let idx = 0;
|
|
180
|
+
for (const [, members] of [...rawCommunities.entries()].sort(
|
|
181
|
+
([a], [b]) => a - b,
|
|
182
|
+
)) {
|
|
183
|
+
communities.set(idx, members.sort());
|
|
184
|
+
idx++;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const modularity = computeModularity(adjacency, communityOf, m);
|
|
188
|
+
|
|
189
|
+
return { communities, modularity };
|
|
190
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: compile-architecture
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Architecture Article Compilation
|
|
8
|
+
|
|
9
|
+
Given the following system overview:
|
|
10
|
+
|
|
11
|
+
Modules:
|
|
12
|
+
{module_list}
|
|
13
|
+
|
|
14
|
+
Module dependency graph:
|
|
15
|
+
{dependency_graph}
|
|
16
|
+
|
|
17
|
+
Community clusters (Louvain):
|
|
18
|
+
{communities}
|
|
19
|
+
|
|
20
|
+
Key decisions:
|
|
21
|
+
{key_decisions}
|
|
22
|
+
|
|
23
|
+
Cross-cutting concerns:
|
|
24
|
+
{cross_cutting}
|
|
25
|
+
|
|
26
|
+
Generate an architecture article that:
|
|
27
|
+
1. Provides a high-level overview of the system structure
|
|
28
|
+
2. Describes the module dependency graph and layering
|
|
29
|
+
3. Identifies community clusters and their purposes
|
|
30
|
+
4. Lists key architectural decisions that shaped the system
|
|
31
|
+
5. Notes cross-cutting concerns (error handling, logging, auth patterns)
|
|
32
|
+
6. Highlights potential architectural risks or debt
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
# Architecture Overview
|
|
38
|
+
|
|
39
|
+
## System Structure
|
|
40
|
+
{high-level description of how the system is organized}
|
|
41
|
+
|
|
42
|
+
## Module Map
|
|
43
|
+
{list of modules with brief descriptions and layer assignments}
|
|
44
|
+
|
|
45
|
+
## Dependency Graph
|
|
46
|
+
{description of how modules depend on each other}
|
|
47
|
+
|
|
48
|
+
## Community Clusters
|
|
49
|
+
{groups of tightly-coupled modules with shared purpose}
|
|
50
|
+
|
|
51
|
+
## Key Decisions
|
|
52
|
+
{links to important architectural decisions}
|
|
53
|
+
|
|
54
|
+
## Cross-Cutting Concerns
|
|
55
|
+
{patterns that span multiple modules}
|
|
56
|
+
|
|
57
|
+
## Risks
|
|
58
|
+
{architectural debt or areas needing attention}
|
|
59
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: compile-decision
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Decision Article Compilation
|
|
8
|
+
|
|
9
|
+
Given the following decision record:
|
|
10
|
+
- ID: {decision_id}
|
|
11
|
+
- Title: {decision_title}
|
|
12
|
+
- Status: {status}
|
|
13
|
+
|
|
14
|
+
Context:
|
|
15
|
+
{context}
|
|
16
|
+
|
|
17
|
+
Decision:
|
|
18
|
+
{decision}
|
|
19
|
+
|
|
20
|
+
Rationale:
|
|
21
|
+
{rationale}
|
|
22
|
+
|
|
23
|
+
Alternatives rejected:
|
|
24
|
+
{alternatives_rejected}
|
|
25
|
+
|
|
26
|
+
Entities affected:
|
|
27
|
+
{entity_mentions}
|
|
28
|
+
|
|
29
|
+
Constitution alignment:
|
|
30
|
+
{constitution_alignment}
|
|
31
|
+
|
|
32
|
+
Generate a decision article that:
|
|
33
|
+
1. Clearly states the decision and its current status
|
|
34
|
+
2. Explains the context that motivated the decision
|
|
35
|
+
3. Documents the rationale with specific reasons
|
|
36
|
+
4. Lists alternatives that were considered and why they were rejected
|
|
37
|
+
5. Links to entities and modules affected by this decision
|
|
38
|
+
6. Notes alignment with project constitution
|
|
39
|
+
|
|
40
|
+
## Output Format
|
|
41
|
+
|
|
42
|
+
```markdown
|
|
43
|
+
# {decision_title}
|
|
44
|
+
|
|
45
|
+
**Status:** {proposed|accepted|deprecated|superseded}
|
|
46
|
+
**ID:** {decision_id}
|
|
47
|
+
|
|
48
|
+
## Context
|
|
49
|
+
{what problem or situation prompted this decision}
|
|
50
|
+
|
|
51
|
+
## Decision
|
|
52
|
+
{the actual decision made}
|
|
53
|
+
|
|
54
|
+
## Rationale
|
|
55
|
+
{why this decision was chosen over alternatives}
|
|
56
|
+
|
|
57
|
+
## Alternatives Considered
|
|
58
|
+
{list of rejected alternatives with reasons}
|
|
59
|
+
|
|
60
|
+
## Impact
|
|
61
|
+
- Entities affected: {links to entity articles}
|
|
62
|
+
- Modules affected: {links to module articles}
|
|
63
|
+
|
|
64
|
+
## Constitution Alignment
|
|
65
|
+
{how this decision aligns with project principles}
|
|
66
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: compile-entity
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Entity Article Compilation
|
|
8
|
+
|
|
9
|
+
Given the following entity definition:
|
|
10
|
+
{entity_definition}
|
|
11
|
+
|
|
12
|
+
Located in module `{module_name}` at `{file_path}:{line_number}`:
|
|
13
|
+
{source_context}
|
|
14
|
+
|
|
15
|
+
With the following lifecycle context:
|
|
16
|
+
- Features that modified this entity: {features}
|
|
17
|
+
- Decisions that affect this entity: {decisions}
|
|
18
|
+
- Dependents (who uses this): {dependents}
|
|
19
|
+
- Dependencies (what this uses): {dependencies}
|
|
20
|
+
|
|
21
|
+
Generate an entity article that:
|
|
22
|
+
1. Describes what the entity is and what it does
|
|
23
|
+
2. Shows its type signature or interface
|
|
24
|
+
3. Lists which features introduced or modified it
|
|
25
|
+
4. References relevant architectural decisions
|
|
26
|
+
5. Notes breaking change risk based on dependent count
|
|
27
|
+
|
|
28
|
+
## Output Format
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
# {entity_name}
|
|
32
|
+
|
|
33
|
+
**Kind:** {function|class|interface|type|const|enum}
|
|
34
|
+
**File:** `{file_path}:{line_number}`
|
|
35
|
+
**Module:** [[modules/{module_name}.md]]
|
|
36
|
+
|
|
37
|
+
## Description
|
|
38
|
+
{what this entity does and why it exists}
|
|
39
|
+
|
|
40
|
+
## Signature
|
|
41
|
+
```typescript
|
|
42
|
+
{type_signature_or_definition}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Lifecycle
|
|
46
|
+
- Introduced by: [[features/{feature}.md]]
|
|
47
|
+
- Modified by: {list of feature links}
|
|
48
|
+
- Governed by: {list of decision links}
|
|
49
|
+
|
|
50
|
+
## Dependencies
|
|
51
|
+
- Uses: {list of entity links}
|
|
52
|
+
- Used by: {list of entity links}
|
|
53
|
+
|
|
54
|
+
## Change Risk
|
|
55
|
+
{low|medium|high} — {N} dependents
|
|
56
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: compile-feature
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Feature Article Compilation
|
|
8
|
+
|
|
9
|
+
Given the following feature metadata:
|
|
10
|
+
- ID: {feature_id}
|
|
11
|
+
- Title: {feature_title}
|
|
12
|
+
- Branch: {branch}
|
|
13
|
+
- PR: {pr_number}
|
|
14
|
+
- Merged: {merged}
|
|
15
|
+
|
|
16
|
+
Spec quality score: {spec_quality_score}
|
|
17
|
+
Spec assertions: {spec_assertions}
|
|
18
|
+
|
|
19
|
+
Tasks:
|
|
20
|
+
{task_list}
|
|
21
|
+
|
|
22
|
+
Entities modified:
|
|
23
|
+
{entities_modified}
|
|
24
|
+
|
|
25
|
+
Decisions created:
|
|
26
|
+
{decisions_created}
|
|
27
|
+
|
|
28
|
+
Generate a feature history article that:
|
|
29
|
+
1. Summarizes what the feature does
|
|
30
|
+
2. Lists acceptance criteria from the spec
|
|
31
|
+
3. Shows implementation progress (completed tasks vs total)
|
|
32
|
+
4. Links to entities that were added or modified
|
|
33
|
+
5. Links to decisions that were made during implementation
|
|
34
|
+
6. Notes the branch and PR for traceability
|
|
35
|
+
|
|
36
|
+
## Output Format
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
# {feature_title}
|
|
40
|
+
|
|
41
|
+
**Feature:** {feature_id}
|
|
42
|
+
**Status:** {merged|in-progress|planned}
|
|
43
|
+
**Branch:** `{branch}`
|
|
44
|
+
**PR:** #{pr_number}
|
|
45
|
+
|
|
46
|
+
## Summary
|
|
47
|
+
{what this feature does and why}
|
|
48
|
+
|
|
49
|
+
## Acceptance Criteria
|
|
50
|
+
{list of spec assertions}
|
|
51
|
+
|
|
52
|
+
## Implementation
|
|
53
|
+
{task_list with completion status}
|
|
54
|
+
|
|
55
|
+
## Entities Modified
|
|
56
|
+
{links to entity articles}
|
|
57
|
+
|
|
58
|
+
## Decisions
|
|
59
|
+
{links to decision articles created during this feature}
|
|
60
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: compile-module
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Module Article Compilation
|
|
8
|
+
|
|
9
|
+
Given the following entities in module `{module_name}`:
|
|
10
|
+
{entity_list}
|
|
11
|
+
|
|
12
|
+
And the following dependency relationships:
|
|
13
|
+
{dependencies}
|
|
14
|
+
|
|
15
|
+
Generate a clear, concise module overview article that:
|
|
16
|
+
1. Describes what this module does in 1-2 sentences
|
|
17
|
+
2. Lists key entities grouped by purpose (exports, types, internal helpers)
|
|
18
|
+
3. Shows dependency relationships as a list of imports/exports
|
|
19
|
+
4. Notes which other modules depend on this one (consumers)
|
|
20
|
+
5. Links to related features and decisions using [[path]] notation
|
|
21
|
+
|
|
22
|
+
## Output Format
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# {module_name}
|
|
26
|
+
|
|
27
|
+
{one_line_description}
|
|
28
|
+
|
|
29
|
+
## Purpose
|
|
30
|
+
{2-3 sentences explaining the module's role in the system}
|
|
31
|
+
|
|
32
|
+
## Key Entities
|
|
33
|
+
{grouped list of functions, types, classes with brief descriptions}
|
|
34
|
+
|
|
35
|
+
## Dependencies
|
|
36
|
+
- **Imports from:** {list of modules this depends on}
|
|
37
|
+
- **Exported to:** {list of modules that import from this}
|
|
38
|
+
|
|
39
|
+
## Related
|
|
40
|
+
- Features: {links to feature articles}
|
|
41
|
+
- Decisions: {links to decision articles}
|
|
42
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
task: wiki-query
|
|
3
|
+
tier: mechanical
|
|
4
|
+
version: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Wiki Query Synthesis
|
|
8
|
+
|
|
9
|
+
You are answering a question about a codebase using wiki documentation.
|
|
10
|
+
|
|
11
|
+
Question: {question}
|
|
12
|
+
|
|
13
|
+
Here are relevant wiki articles:
|
|
14
|
+
|
|
15
|
+
{articles}
|
|
16
|
+
|
|
17
|
+
## Instructions
|
|
18
|
+
|
|
19
|
+
1. Provide a clear, concise answer that directly addresses the question
|
|
20
|
+
2. Cite relevant articles using [[article_path]] notation (e.g., [[modules/core.md]])
|
|
21
|
+
3. If the articles don't contain enough information, say so explicitly
|
|
22
|
+
4. Do NOT guess or hallucinate information not present in the articles
|
|
23
|
+
5. If anything is ambiguous, use [NEEDS CLARIFICATION: specific question]
|
|
24
|
+
6. Prioritize accuracy over completeness
|
|
25
|
+
7. Keep the answer focused — avoid restating the entire article content
|