agent-eng 0.1.0
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/README.md +85 -0
- package/bin/agent-eng.js +5 -0
- package/package.json +24 -0
- package/src/index.js +74 -0
- package/src/init.js +80 -0
- package/src/templates/CLAUDE.md +34 -0
- package/src/templates/architecture/decisions/0001-how-we-work.md +63 -0
- package/src/templates/architecture/decisions/_template.md +41 -0
- package/src/templates/architecture/overview.md +25 -0
- package/src/templates/conventions/java.md +110 -0
- package/src/templates/conventions/python.md +107 -0
- package/src/templates/conventions/typescript.md +95 -0
- package/src/templates/orchestration.yaml +67 -0
- package/src/templates/prompts/architect.md +61 -0
- package/src/templates/prompts/planner.md +78 -0
- package/src/templates/prompts/reviewer.md +67 -0
- package/src/templates/specs/_template.md +55 -0
- package/src/templates/tickets/_template.md +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# agent-eng
|
|
2
|
+
|
|
3
|
+
Scaffold a structured agentic engineering workflow into any project. Run one command to set up the directory structure, system prompts, templates, and conventions for AI-assisted development with separated roles (Architect, Planner, Executor, Reviewer).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx agent-eng init
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This creates the following structure in your project:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
├── CLAUDE.md # Project instructions for AI agents
|
|
15
|
+
├── orchestration.yaml # Machine-readable workflow definition
|
|
16
|
+
├── architecture/
|
|
17
|
+
│ ├── overview.md # High-level architecture overview
|
|
18
|
+
│ └── decisions/
|
|
19
|
+
│ ├── _template.md # ADR template
|
|
20
|
+
│ └── 0001-how-we-work.md # Seed ADR: the workflow itself
|
|
21
|
+
├── prompts/
|
|
22
|
+
│ ├── architect.md # System prompt for the Architect role
|
|
23
|
+
│ ├── planner.md # System prompt for the Planner role
|
|
24
|
+
│ └── reviewer.md # System prompt for the Reviewer role
|
|
25
|
+
├── specs/
|
|
26
|
+
│ └── _template.md # Feature specification template
|
|
27
|
+
├── tickets/
|
|
28
|
+
│ └── _template.md # Work ticket template
|
|
29
|
+
└── conventions/
|
|
30
|
+
├── typescript.md # TypeScript coding standards
|
|
31
|
+
├── python.md # Python coding standards
|
|
32
|
+
└── java.md # Java coding standards
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Initialize with all conventions (default)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
agent-eng init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Pick specific conventions
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
agent-eng init --conventions typescript,python
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Initialize in a specific directory
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
agent-eng init --dir ./my-project
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Overwrite existing files
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
agent-eng init --force
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## The Workflow
|
|
62
|
+
|
|
63
|
+
The scaffolded workflow separates AI-assisted engineering into four roles:
|
|
64
|
+
|
|
65
|
+
| Role | What it does | What it produces |
|
|
66
|
+
|------|-------------|-----------------|
|
|
67
|
+
| **Architect** | Analyzes requirements, asks clarifying questions, evaluates alternatives | Architecture Decision Records (ADRs) |
|
|
68
|
+
| **Planner** | Reads ADRs and specs, decomposes work into focused chunks | Tickets with acceptance criteria |
|
|
69
|
+
| **Executor** | Implements tickets following conventions, proposes plan first | Code and PRs |
|
|
70
|
+
| **Reviewer** | Validates code against acceptance criteria and ADRs | Approval or actionable feedback |
|
|
71
|
+
|
|
72
|
+
Each role has a dedicated system prompt in `prompts/` that you can load into your AI assistant to set the context for that type of work.
|
|
73
|
+
|
|
74
|
+
## After Initialization
|
|
75
|
+
|
|
76
|
+
1. **Review `CLAUDE.md`** — Customize the project instructions for your specific project
|
|
77
|
+
2. **Pick your conventions** — Keep the ones that match your stack, remove the rest
|
|
78
|
+
3. **Start with the Architect** — Load `prompts/architect.md` and create your first ADR for a design decision
|
|
79
|
+
4. **Plan the work** — Load `prompts/planner.md` and decompose your ADR into tickets
|
|
80
|
+
5. **Execute** — Pick up a ticket and implement it following your conventions
|
|
81
|
+
6. **Review** — Load `prompts/reviewer.md` to validate the work
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT
|
package/bin/agent-eng.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-eng",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffold a structured agentic engineering workflow for AI-assisted development",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agent-eng": "./bin/agent-eng.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"ai",
|
|
15
|
+
"agents",
|
|
16
|
+
"workflow",
|
|
17
|
+
"cli",
|
|
18
|
+
"scaffold",
|
|
19
|
+
"adr",
|
|
20
|
+
"architecture"
|
|
21
|
+
],
|
|
22
|
+
"author": "swarpi",
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { init } from "./init.js";
|
|
2
|
+
|
|
3
|
+
const HELP = `
|
|
4
|
+
agent-eng — scaffold an agentic engineering workflow
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
agent-eng init [options] Set up the workflow in the current directory
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--conventions <list> Comma-separated list: typescript,python,java (default: all)
|
|
11
|
+
--dir <path> Target directory (default: current directory)
|
|
12
|
+
--force Overwrite existing files
|
|
13
|
+
-h, --help Show this help
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
agent-eng init
|
|
17
|
+
agent-eng init --conventions typescript,python
|
|
18
|
+
agent-eng init --dir ./my-project --conventions java
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export function run(args) {
|
|
22
|
+
const command = args[0];
|
|
23
|
+
|
|
24
|
+
if (!command || command === "-h" || command === "--help") {
|
|
25
|
+
console.log(HELP.trim());
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (command === "init") {
|
|
30
|
+
const options = parseInitArgs(args.slice(1));
|
|
31
|
+
init(options);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.error(`Unknown command: ${command}`);
|
|
36
|
+
console.log('Run "agent-eng --help" for usage.');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseInitArgs(args) {
|
|
41
|
+
const options = {
|
|
42
|
+
conventions: ["typescript", "python", "java"],
|
|
43
|
+
dir: process.cwd(),
|
|
44
|
+
force: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < args.length; i++) {
|
|
48
|
+
switch (args[i]) {
|
|
49
|
+
case "--conventions":
|
|
50
|
+
options.conventions = args[++i]?.split(",").map((s) => s.trim()) ?? [];
|
|
51
|
+
break;
|
|
52
|
+
case "--dir":
|
|
53
|
+
options.dir = args[++i];
|
|
54
|
+
break;
|
|
55
|
+
case "--force":
|
|
56
|
+
options.force = true;
|
|
57
|
+
break;
|
|
58
|
+
case "-h":
|
|
59
|
+
case "--help":
|
|
60
|
+
console.log(HELP.trim());
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const valid = new Set(["typescript", "python", "java"]);
|
|
66
|
+
for (const c of options.conventions) {
|
|
67
|
+
if (!valid.has(c)) {
|
|
68
|
+
console.error(`Unknown convention: ${c}. Choose from: ${[...valid].join(", ")}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return options;
|
|
74
|
+
}
|
package/src/init.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const TEMPLATES = join(__dirname, "templates");
|
|
7
|
+
|
|
8
|
+
const STRUCTURE = [
|
|
9
|
+
"architecture/overview.md",
|
|
10
|
+
"architecture/decisions/_template.md",
|
|
11
|
+
"architecture/decisions/0001-how-we-work.md",
|
|
12
|
+
"prompts/architect.md",
|
|
13
|
+
"prompts/planner.md",
|
|
14
|
+
"prompts/reviewer.md",
|
|
15
|
+
"specs/_template.md",
|
|
16
|
+
"tickets/_template.md",
|
|
17
|
+
"orchestration.yaml",
|
|
18
|
+
"CLAUDE.md",
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export function init(options) {
|
|
22
|
+
const target = resolve(options.dir);
|
|
23
|
+
const created = [];
|
|
24
|
+
const skipped = [];
|
|
25
|
+
|
|
26
|
+
for (const file of STRUCTURE) {
|
|
27
|
+
const dest = join(target, file);
|
|
28
|
+
const src = join(TEMPLATES, file);
|
|
29
|
+
|
|
30
|
+
if (existsSync(dest) && !options.force) {
|
|
31
|
+
skipped.push(file);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
36
|
+
cpSync(src, dest);
|
|
37
|
+
created.push(file);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const convention of options.conventions) {
|
|
41
|
+
const file = `conventions/${convention}.md`;
|
|
42
|
+
const dest = join(target, file);
|
|
43
|
+
const src = join(TEMPLATES, file);
|
|
44
|
+
|
|
45
|
+
if (existsSync(dest) && !options.force) {
|
|
46
|
+
skipped.push(file);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
51
|
+
cpSync(src, dest);
|
|
52
|
+
created.push(file);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log("");
|
|
56
|
+
console.log("✔ Agentic workflow initialized");
|
|
57
|
+
console.log("");
|
|
58
|
+
|
|
59
|
+
if (created.length > 0) {
|
|
60
|
+
console.log("Created:");
|
|
61
|
+
for (const f of created) {
|
|
62
|
+
console.log(` ${f}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (skipped.length > 0) {
|
|
67
|
+
console.log("");
|
|
68
|
+
console.log("Skipped (already exist, use --force to overwrite):");
|
|
69
|
+
for (const f of skipped) {
|
|
70
|
+
console.log(` ${f}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log("");
|
|
75
|
+
console.log("Next steps:");
|
|
76
|
+
console.log(" 1. Review CLAUDE.md and customize for your project");
|
|
77
|
+
console.log(" 2. Pick the conventions that match your stack");
|
|
78
|
+
console.log(" 3. Start with the Architect: create your first ADR");
|
|
79
|
+
console.log("");
|
|
80
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Project
|
|
2
|
+
|
|
3
|
+
This project uses a structured agentic engineering workflow. Before starting any work, read this document and the relevant references below.
|
|
4
|
+
|
|
5
|
+
## Workflow
|
|
6
|
+
|
|
7
|
+
This project separates AI-assisted work into four roles. Each role has a dedicated system prompt in `prompts/`.
|
|
8
|
+
|
|
9
|
+
| Role | Prompt | Responsibility |
|
|
10
|
+
|------|--------|----------------|
|
|
11
|
+
| **Architect** | `prompts/architect.md` | Analyze requirements, ask clarifying questions, produce ADRs |
|
|
12
|
+
| **Planner** | `prompts/planner.md` | Decompose specs and ADRs into actionable tickets |
|
|
13
|
+
| **Executor** | _(you, the coding agent)_ | Implement tickets following conventions |
|
|
14
|
+
| **Reviewer** | `prompts/reviewer.md` | Validate code against acceptance criteria and ADRs |
|
|
15
|
+
|
|
16
|
+
## Before Starting Any Ticket
|
|
17
|
+
|
|
18
|
+
1. Read the ticket fully, including all linked documents
|
|
19
|
+
2. Read any referenced ADRs in `architecture/decisions/`
|
|
20
|
+
3. Check if there's a relevant spec in `specs/`
|
|
21
|
+
4. Propose a plan before writing code — get alignment first
|
|
22
|
+
5. If the ticket touches an existing ADR's scope, verify the decision still holds
|
|
23
|
+
|
|
24
|
+
## Key Directories
|
|
25
|
+
|
|
26
|
+
- `architecture/decisions/` — Architecture Decision Records (ADRs)
|
|
27
|
+
- `specs/` — Feature specifications
|
|
28
|
+
- `tickets/` — Work items with acceptance criteria
|
|
29
|
+
- `conventions/` — Language and framework coding standards
|
|
30
|
+
- `prompts/` — System prompts for each agent role
|
|
31
|
+
|
|
32
|
+
## Conventions
|
|
33
|
+
|
|
34
|
+
Check `conventions/` for language-specific standards. Always follow the conventions for the language you're working in.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# ADR-0001: How We Work with AI Agents
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted
|
|
4
|
+
**Date:** 2026-05-04
|
|
5
|
+
**Author:** swarpi
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Working with AI coding assistants can be highly productive, but without structure it often leads to:
|
|
10
|
+
- Inconsistent code quality and style
|
|
11
|
+
- Decisions made without considering alternatives
|
|
12
|
+
- Lost context between sessions
|
|
13
|
+
- No clear separation between planning and execution
|
|
14
|
+
|
|
15
|
+
We need a workflow that maximizes the benefits of AI assistance while maintaining engineering rigor.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
We adopt a role-based workflow with four distinct agent modes:
|
|
20
|
+
|
|
21
|
+
1. **Architect** — Focuses on design decisions. Produces ADRs. Asks clarifying questions before deciding. Has read access to the codebase but does not write code.
|
|
22
|
+
|
|
23
|
+
2. **Planner** — Takes specs and ADRs as input. Decomposes work into tickets with clear acceptance criteria. Does not implement.
|
|
24
|
+
|
|
25
|
+
3. **Executor** — Implements tickets. Follows conventions. References the ticket and relevant ADRs. Proposes a plan before coding.
|
|
26
|
+
|
|
27
|
+
4. **Reviewer** — Reviews diffs against acceptance criteria and linked ADRs. Checks for convention violations. Does not fix issues directly — flags them for the executor.
|
|
28
|
+
|
|
29
|
+
All significant decisions are recorded as ADRs. All work items are tickets with acceptance criteria. Conventions are documented per-language.
|
|
30
|
+
|
|
31
|
+
## Consequences
|
|
32
|
+
|
|
33
|
+
### Positive
|
|
34
|
+
|
|
35
|
+
- Clear separation of concerns reduces cognitive overload per session
|
|
36
|
+
- ADRs create a searchable decision history
|
|
37
|
+
- Tickets with acceptance criteria make "done" unambiguous
|
|
38
|
+
- Conventions prevent style drift across sessions
|
|
39
|
+
- Role separation allows using different models for different tasks (e.g., larger model for architecture, faster model for execution)
|
|
40
|
+
|
|
41
|
+
### Negative
|
|
42
|
+
|
|
43
|
+
- More upfront documentation work
|
|
44
|
+
- Overhead may feel excessive for small changes
|
|
45
|
+
- Requires discipline to follow the process
|
|
46
|
+
|
|
47
|
+
### Neutral
|
|
48
|
+
|
|
49
|
+
- This is a personal workflow; team adoption would require additional coordination conventions
|
|
50
|
+
|
|
51
|
+
## Alternatives Considered
|
|
52
|
+
|
|
53
|
+
### Unstructured chat-based development
|
|
54
|
+
|
|
55
|
+
Just talk to the AI and let it write code directly. Rejected because it leads to inconsistent decisions and lost context.
|
|
56
|
+
|
|
57
|
+
### Heavy-process frameworks (e.g., full Agile ceremony)
|
|
58
|
+
|
|
59
|
+
Too heavyweight for a solo developer. We take the useful parts (clear acceptance criteria, documented decisions) without the ceremony.
|
|
60
|
+
|
|
61
|
+
### Separate human architect with AI executor
|
|
62
|
+
|
|
63
|
+
Keeps all design decisions with the human. Rejected because AI architects can surface alternatives humans wouldn't consider, and documenting the reasoning in ADRs preserves human oversight.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ADR-NNNN: Title
|
|
2
|
+
|
|
3
|
+
**Status:** Proposed | Accepted | Deprecated | Superseded by ADR-NNNN
|
|
4
|
+
**Date:** YYYY-MM-DD
|
|
5
|
+
**Author:** Name
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
What is the issue that we're seeing that motivates this decision or change?
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
What is the change that we're proposing and/or doing?
|
|
14
|
+
|
|
15
|
+
## Consequences
|
|
16
|
+
|
|
17
|
+
What becomes easier or more difficult to do because of this change?
|
|
18
|
+
|
|
19
|
+
### Positive
|
|
20
|
+
|
|
21
|
+
- Benefit 1
|
|
22
|
+
- Benefit 2
|
|
23
|
+
|
|
24
|
+
### Negative
|
|
25
|
+
|
|
26
|
+
- Tradeoff 1
|
|
27
|
+
- Tradeoff 2
|
|
28
|
+
|
|
29
|
+
### Neutral
|
|
30
|
+
|
|
31
|
+
- Side effect that is neither positive nor negative
|
|
32
|
+
|
|
33
|
+
## Alternatives Considered
|
|
34
|
+
|
|
35
|
+
### Alternative 1
|
|
36
|
+
|
|
37
|
+
Description and why it was rejected.
|
|
38
|
+
|
|
39
|
+
### Alternative 2
|
|
40
|
+
|
|
41
|
+
Description and why it was rejected.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Architecture Overview
|
|
2
|
+
|
|
3
|
+
This document provides a high-level view of the system architecture.
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
1. **Separation of concerns** — Different cognitive tasks get different prompts and contexts
|
|
8
|
+
2. **Written artifacts** — Decisions, plans, and reviews are documented, not just discussed
|
|
9
|
+
3. **Verify before execute** — Plans are reviewed before implementation begins
|
|
10
|
+
4. **Single source of truth** — Each piece of information lives in one canonical place
|
|
11
|
+
|
|
12
|
+
## The Flow
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Requirement → Architect → ADR/Spec → Planner → Tickets → Executor → Code → Reviewer → Merged
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Artifact Types
|
|
19
|
+
|
|
20
|
+
| Artifact | Purpose | Location |
|
|
21
|
+
|----------|---------|----------|
|
|
22
|
+
| ADR | Record architectural decisions | `architecture/decisions/` |
|
|
23
|
+
| Spec | Define feature requirements | `specs/` |
|
|
24
|
+
| Ticket | Actionable work item | `tickets/` |
|
|
25
|
+
| Convention | Language/framework standards | `conventions/` |
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Java Conventions
|
|
2
|
+
|
|
3
|
+
## Runtime and Build
|
|
4
|
+
|
|
5
|
+
- **Java version**: 21 (LTS)
|
|
6
|
+
- **Build tool**: Gradle with Kotlin DSL (`build.gradle.kts`)
|
|
7
|
+
- **Framework**: Spring Boot 3.x (unless otherwise specified)
|
|
8
|
+
|
|
9
|
+
## Code Style
|
|
10
|
+
|
|
11
|
+
### Modern Java Features
|
|
12
|
+
|
|
13
|
+
- **Records** over POJOs for immutable data
|
|
14
|
+
- **Pattern matching** with `switch` expressions and `instanceof`
|
|
15
|
+
- **Virtual threads** for concurrent I/O (Project Loom)
|
|
16
|
+
- **Sealed classes** for closed hierarchies
|
|
17
|
+
- **No Lombok** — use records and IDE generation instead
|
|
18
|
+
|
|
19
|
+
```java
|
|
20
|
+
public record User(String id, String name, String email) {}
|
|
21
|
+
|
|
22
|
+
public sealed interface Result<T> permits Success, Failure {
|
|
23
|
+
record Success<T>(T value) implements Result<T> {}
|
|
24
|
+
record Failure<T>(String error) implements Result<T> {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
String describe(Object obj) {
|
|
28
|
+
return switch (obj) {
|
|
29
|
+
case User u -> "User: " + u.name();
|
|
30
|
+
case String s -> "String: " + s;
|
|
31
|
+
case null -> "null";
|
|
32
|
+
default -> "Unknown";
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Null Handling
|
|
38
|
+
|
|
39
|
+
- Prefer `Optional<T>` for return types that may be absent
|
|
40
|
+
- Use `@Nullable` and `@NonNull` annotations from JSpecify
|
|
41
|
+
- Avoid returning `null` from public methods
|
|
42
|
+
|
|
43
|
+
```java
|
|
44
|
+
public Optional<User> findUser(String id) {
|
|
45
|
+
return Optional.ofNullable(repository.get(id));
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Dependency Injection
|
|
50
|
+
|
|
51
|
+
- Constructor injection (not field injection)
|
|
52
|
+
- Final fields for injected dependencies
|
|
53
|
+
- `@RequiredArgsConstructor` is forbidden (no Lombok)
|
|
54
|
+
|
|
55
|
+
```java
|
|
56
|
+
@Service
|
|
57
|
+
public class UserService {
|
|
58
|
+
private final UserRepository repository;
|
|
59
|
+
private final EmailService emailService;
|
|
60
|
+
|
|
61
|
+
public UserService(UserRepository repository, EmailService emailService) {
|
|
62
|
+
this.repository = repository;
|
|
63
|
+
this.emailService = emailService;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Streams and Collections
|
|
69
|
+
|
|
70
|
+
- Prefer immutable collections: `List.of()`, `Set.of()`, `Map.of()`
|
|
71
|
+
- Use streams for transformations, not side effects
|
|
72
|
+
- Avoid nested streams; extract to methods
|
|
73
|
+
|
|
74
|
+
```java
|
|
75
|
+
var activeUsers = users.stream()
|
|
76
|
+
.filter(User::isActive)
|
|
77
|
+
.toList();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## File Organization
|
|
81
|
+
|
|
82
|
+
- One public class per file
|
|
83
|
+
- Package-private classes for implementation details
|
|
84
|
+
- Test classes in parallel `src/test/java` hierarchy
|
|
85
|
+
|
|
86
|
+
## Naming
|
|
87
|
+
|
|
88
|
+
- `camelCase` for methods, variables, parameters
|
|
89
|
+
- `PascalCase` for classes, interfaces, enums, records
|
|
90
|
+
- `SCREAMING_SNAKE_CASE` for constants
|
|
91
|
+
- Interfaces: noun or adjective, no `I` prefix
|
|
92
|
+
- Implementations: descriptive name, not `Impl` suffix
|
|
93
|
+
|
|
94
|
+
## Async / Concurrency
|
|
95
|
+
|
|
96
|
+
- Use virtual threads for blocking I/O (not reactive)
|
|
97
|
+
- `CompletableFuture` for async composition when needed
|
|
98
|
+
- Prefer structured concurrency (preview feature) when stable
|
|
99
|
+
|
|
100
|
+
```java
|
|
101
|
+
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
|
102
|
+
executor.submit(() -> processRequest(request));
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Testing
|
|
107
|
+
|
|
108
|
+
- JUnit 5 with AssertJ for assertions
|
|
109
|
+
- Mockito for mocking (sparingly)
|
|
110
|
+
- Testcontainers for integration tests
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Python Conventions
|
|
2
|
+
|
|
3
|
+
## Tooling
|
|
4
|
+
|
|
5
|
+
- **Package/project manager**: uv (not pip, poetry, or pipenv)
|
|
6
|
+
- **Formatter/Linter**: Ruff
|
|
7
|
+
- **Type checker**: Pyright (strict mode)
|
|
8
|
+
- **Test runner**: pytest
|
|
9
|
+
|
|
10
|
+
## Project Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv init project-name
|
|
14
|
+
cd project-name
|
|
15
|
+
uv add --dev ruff pyright pytest
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Code Style
|
|
19
|
+
|
|
20
|
+
### Type Hints
|
|
21
|
+
|
|
22
|
+
- Type hints on all function signatures
|
|
23
|
+
- Use `from __future__ import annotations` for forward references
|
|
24
|
+
- Use `typing` module for generics and unions
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
from typing import TypeVar, Sequence
|
|
29
|
+
|
|
30
|
+
T = TypeVar("T")
|
|
31
|
+
|
|
32
|
+
def first(items: Sequence[T]) -> T | None:
|
|
33
|
+
return items[0] if items else None
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Functions
|
|
37
|
+
|
|
38
|
+
- Prefer pure functions over methods when no state is needed
|
|
39
|
+
- Use dataclasses or named tuples for structured data
|
|
40
|
+
- Avoid mutable default arguments
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from dataclasses import dataclass
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True)
|
|
46
|
+
class User:
|
|
47
|
+
id: str
|
|
48
|
+
name: str
|
|
49
|
+
email: str
|
|
50
|
+
|
|
51
|
+
def get_user(user_id: str) -> User | None:
|
|
52
|
+
...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Error Handling
|
|
56
|
+
|
|
57
|
+
- Use explicit exception types
|
|
58
|
+
- Prefer returning `None` or a result type over raising for expected cases
|
|
59
|
+
- Document raised exceptions in docstrings
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
class ParseError(Exception):
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
def parse_config(raw: str) -> Config:
|
|
66
|
+
"""Parse configuration from string.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
ParseError: If the configuration is invalid.
|
|
70
|
+
"""
|
|
71
|
+
...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Imports
|
|
75
|
+
|
|
76
|
+
- Use absolute imports
|
|
77
|
+
- Group: standard library, third-party, local
|
|
78
|
+
- One import per line for `from` imports with multiple items
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import json
|
|
82
|
+
from pathlib import Path
|
|
83
|
+
|
|
84
|
+
import httpx
|
|
85
|
+
|
|
86
|
+
from myproject.config import settings
|
|
87
|
+
from myproject.models import User
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## File Organization
|
|
91
|
+
|
|
92
|
+
- One module per file, named after the primary class/function
|
|
93
|
+
- Use `__init__.py` for package exports only
|
|
94
|
+
- Co-locate tests in `tests/` directory mirroring `src/` structure
|
|
95
|
+
|
|
96
|
+
## Naming
|
|
97
|
+
|
|
98
|
+
- `snake_case` for functions, variables, modules
|
|
99
|
+
- `PascalCase` for classes
|
|
100
|
+
- `SCREAMING_SNAKE_CASE` for constants
|
|
101
|
+
- `_private` prefix for internal names
|
|
102
|
+
|
|
103
|
+
## Async
|
|
104
|
+
|
|
105
|
+
- Use `asyncio` for concurrent I/O
|
|
106
|
+
- Prefer `async/await` over callbacks
|
|
107
|
+
- Use `asyncio.gather` for concurrent operations
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# TypeScript Conventions
|
|
2
|
+
|
|
3
|
+
## Compiler Settings
|
|
4
|
+
|
|
5
|
+
- **Strict mode**: Always enable `"strict": true` in tsconfig
|
|
6
|
+
- **Target**: ES2022 or later
|
|
7
|
+
- **Module**: ESNext with bundler module resolution
|
|
8
|
+
|
|
9
|
+
## Tooling
|
|
10
|
+
|
|
11
|
+
- **Formatter/Linter**: Biome (not ESLint + Prettier)
|
|
12
|
+
- **Test runner**: Vitest
|
|
13
|
+
- **Package manager**: pnpm preferred, npm acceptable
|
|
14
|
+
|
|
15
|
+
## Code Style
|
|
16
|
+
|
|
17
|
+
### Types
|
|
18
|
+
|
|
19
|
+
- Prefer `interface` for object shapes, `type` for unions/intersections
|
|
20
|
+
- Always annotate function parameters and return types
|
|
21
|
+
- Use `unknown` over `any`; narrow with type guards
|
|
22
|
+
- Prefer `readonly` for immutable data
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
interface User {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
email: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getUser(id: string): Promise<User | null> {
|
|
32
|
+
// ...
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Functions
|
|
37
|
+
|
|
38
|
+
- Prefer arrow functions for callbacks and short functions
|
|
39
|
+
- Use named function declarations for top-level functions
|
|
40
|
+
- Avoid classes unless modeling stateful entities
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// Preferred: named function at module level
|
|
44
|
+
function calculateTotal(items: Item[]): number {
|
|
45
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Preferred: arrow for inline callbacks
|
|
49
|
+
const activeUsers = users.filter((u) => u.isActive);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Error Handling
|
|
53
|
+
|
|
54
|
+
- Use explicit error types, not `catch (e: any)`
|
|
55
|
+
- Prefer returning `Result<T, E>` types over throwing for expected failures
|
|
56
|
+
- Reserve exceptions for unexpected/unrecoverable errors
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
|
|
60
|
+
|
|
61
|
+
function parseConfig(raw: string): Result<Config, ParseError> {
|
|
62
|
+
// ...
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Imports
|
|
67
|
+
|
|
68
|
+
- Use named imports, avoid default exports
|
|
69
|
+
- Group imports: external, then internal, then relative
|
|
70
|
+
- Use `type` imports for type-only imports
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { readFile } from "node:fs/promises";
|
|
74
|
+
import type { Config } from "@/types";
|
|
75
|
+
import { parseConfig } from "./parser";
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## File Organization
|
|
79
|
+
|
|
80
|
+
- One primary export per file
|
|
81
|
+
- Co-locate tests: `foo.ts` and `foo.test.ts` in the same directory
|
|
82
|
+
- Use `index.ts` only for re-exports, not implementation
|
|
83
|
+
|
|
84
|
+
## Naming
|
|
85
|
+
|
|
86
|
+
- `camelCase` for variables, functions, parameters
|
|
87
|
+
- `PascalCase` for types, interfaces, classes, enums
|
|
88
|
+
- `SCREAMING_SNAKE_CASE` for constants
|
|
89
|
+
- Prefix booleans with `is`, `has`, `should`, `can`
|
|
90
|
+
|
|
91
|
+
## Async
|
|
92
|
+
|
|
93
|
+
- Always use `async/await` over raw Promises
|
|
94
|
+
- Handle all promise rejections
|
|
95
|
+
- Use `Promise.all` for independent concurrent operations
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Agentic Workflow
|
|
2
|
+
description: Four-role pipeline for AI-assisted software engineering
|
|
3
|
+
|
|
4
|
+
agents:
|
|
5
|
+
- id: architect
|
|
6
|
+
title: Architect
|
|
7
|
+
tagline: Shapes the system before anything is built
|
|
8
|
+
description: Asks clarifying questions and explores alternatives before any code is written. Produces Architecture Decision Records (ADRs) and detailed specs.
|
|
9
|
+
outputs:
|
|
10
|
+
- ADRs
|
|
11
|
+
- Specs
|
|
12
|
+
- Constraints
|
|
13
|
+
color: indigo
|
|
14
|
+
docLink: /prompts/architect.md
|
|
15
|
+
|
|
16
|
+
- id: planner
|
|
17
|
+
title: Planner
|
|
18
|
+
tagline: Decomposes specs into actionable work
|
|
19
|
+
description: Takes ADRs and specs as input. Decomposes the work into discrete, actionable tickets with clear acceptance criteria.
|
|
20
|
+
outputs:
|
|
21
|
+
- Tickets
|
|
22
|
+
- Milestones
|
|
23
|
+
- Criteria
|
|
24
|
+
color: indigo
|
|
25
|
+
docLink: /prompts/planner.md
|
|
26
|
+
|
|
27
|
+
- id: executor
|
|
28
|
+
title: Executor
|
|
29
|
+
tagline: Implements with intent and discipline
|
|
30
|
+
description: Implements tickets following established conventions. Always proposes a plan before touching the codebase.
|
|
31
|
+
outputs:
|
|
32
|
+
- Code
|
|
33
|
+
- PRs
|
|
34
|
+
- Plan docs
|
|
35
|
+
color: indigo
|
|
36
|
+
docLink: /conventions/typescript.md
|
|
37
|
+
|
|
38
|
+
- id: reviewer
|
|
39
|
+
title: Reviewer
|
|
40
|
+
tagline: Validates against acceptance criteria
|
|
41
|
+
description: Validates code against the original acceptance criteria. Flags issues back to the Executor and provides final approval.
|
|
42
|
+
outputs:
|
|
43
|
+
- Feedback
|
|
44
|
+
- Approval
|
|
45
|
+
- Notes
|
|
46
|
+
color: amber
|
|
47
|
+
docLink: /prompts/reviewer.md
|
|
48
|
+
|
|
49
|
+
connections:
|
|
50
|
+
- from: architect
|
|
51
|
+
to: planner
|
|
52
|
+
artifact: ADRs · Specs
|
|
53
|
+
|
|
54
|
+
- from: planner
|
|
55
|
+
to: executor
|
|
56
|
+
artifact: Tickets
|
|
57
|
+
|
|
58
|
+
- from: executor
|
|
59
|
+
to: reviewer
|
|
60
|
+
artifact: Code
|
|
61
|
+
|
|
62
|
+
- from: reviewer
|
|
63
|
+
to: executor
|
|
64
|
+
artifact: Feedback
|
|
65
|
+
type: feedback
|
|
66
|
+
|
|
67
|
+
layout: diamond
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Architect System Prompt
|
|
2
|
+
|
|
3
|
+
You are an architect agent. Your role is to make design decisions and produce Architecture Decision Records (ADRs).
|
|
4
|
+
|
|
5
|
+
## Responsibilities
|
|
6
|
+
|
|
7
|
+
1. **Analyze requirements** — Understand what needs to be built and why
|
|
8
|
+
2. **Ask clarifying questions** — Before deciding, surface ambiguities and gather context
|
|
9
|
+
3. **Consider alternatives** — Evaluate at least 2-3 approaches before recommending one
|
|
10
|
+
4. **Produce ADRs** — Document decisions using the template in `architecture/decisions/_template.md`
|
|
11
|
+
5. **Reference existing decisions** — Check `architecture/decisions/` for relevant prior ADRs
|
|
12
|
+
|
|
13
|
+
## Constraints
|
|
14
|
+
|
|
15
|
+
- You have **read access** to the codebase but **do not write code**
|
|
16
|
+
- You produce ADRs, not implementations
|
|
17
|
+
- You ask questions before making decisions, not after
|
|
18
|
+
- You document tradeoffs, not just the chosen path
|
|
19
|
+
|
|
20
|
+
## Process
|
|
21
|
+
|
|
22
|
+
1. Read the request or spec carefully
|
|
23
|
+
2. Review existing ADRs that might be relevant
|
|
24
|
+
3. List clarifying questions (if any) before proceeding
|
|
25
|
+
4. Once you have enough context, draft an ADR with:
|
|
26
|
+
- Clear context explaining the problem
|
|
27
|
+
- Your recommended decision
|
|
28
|
+
- Consequences (positive, negative, neutral)
|
|
29
|
+
- Alternatives you considered and why they were rejected
|
|
30
|
+
5. Present the ADR for review before it's finalized
|
|
31
|
+
|
|
32
|
+
## Output Format
|
|
33
|
+
|
|
34
|
+
When producing an ADR, use the template format with proper frontmatter:
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
# ADR-NNNN: Title
|
|
38
|
+
|
|
39
|
+
**Status:** Proposed
|
|
40
|
+
**Date:** YYYY-MM-DD
|
|
41
|
+
**Author:** ...
|
|
42
|
+
|
|
43
|
+
## Context
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
## Decision
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
## Consequences
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
## Alternatives Considered
|
|
53
|
+
...
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Anti-patterns to Avoid
|
|
57
|
+
|
|
58
|
+
- Making decisions without documenting alternatives
|
|
59
|
+
- Jumping to implementation details
|
|
60
|
+
- Ignoring existing ADRs that set relevant precedents
|
|
61
|
+
- Deciding before asking clarifying questions
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Planner System Prompt
|
|
2
|
+
|
|
3
|
+
You are a planner agent. Your role is to decompose specs and ADRs into actionable tickets.
|
|
4
|
+
|
|
5
|
+
## Responsibilities
|
|
6
|
+
|
|
7
|
+
1. **Read specs and ADRs** — Understand what needs to be built and the constraints
|
|
8
|
+
2. **Decompose work** — Break features into small, focused tickets
|
|
9
|
+
3. **Define acceptance criteria** — Each ticket must have testable completion criteria
|
|
10
|
+
4. **Sequence work** — Order tickets to minimize blocked dependencies
|
|
11
|
+
5. **Scope appropriately** — Each ticket should be completable in one focused session
|
|
12
|
+
|
|
13
|
+
## Constraints
|
|
14
|
+
|
|
15
|
+
- You produce **tickets**, not code
|
|
16
|
+
- Each ticket should be **independently mergeable** where possible
|
|
17
|
+
- Acceptance criteria must be **specific and testable**
|
|
18
|
+
- Link tickets to relevant ADRs and specs
|
|
19
|
+
|
|
20
|
+
## Process
|
|
21
|
+
|
|
22
|
+
1. Read the spec or feature request
|
|
23
|
+
2. Identify the relevant ADRs and conventions
|
|
24
|
+
3. Break the work into logical chunks:
|
|
25
|
+
- Start with infrastructure/setup if needed
|
|
26
|
+
- Core functionality next
|
|
27
|
+
- Edge cases and polish last
|
|
28
|
+
4. For each chunk, create a ticket with:
|
|
29
|
+
- Clear context linking to the spec
|
|
30
|
+
- A one-sentence goal
|
|
31
|
+
- Testable acceptance criteria (checkboxes)
|
|
32
|
+
- Explicit out-of-scope items
|
|
33
|
+
5. Review the full set for gaps and dependencies
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
Use the ticket template from `tickets/_template.md`:
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
# Ticket: Title
|
|
41
|
+
|
|
42
|
+
**Status:** Todo
|
|
43
|
+
**Priority:** P1
|
|
44
|
+
**Estimate:** M
|
|
45
|
+
**Related:** ADR-0001, Spec: Feature Name
|
|
46
|
+
|
|
47
|
+
## Context
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
## Goal
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
## Acceptance Criteria
|
|
54
|
+
- [ ] ...
|
|
55
|
+
|
|
56
|
+
## Out of Scope
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
## Notes
|
|
60
|
+
...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Sizing Guidelines
|
|
64
|
+
|
|
65
|
+
| Size | Scope |
|
|
66
|
+
|------|-------|
|
|
67
|
+
| XS | Single-file change, <30 min |
|
|
68
|
+
| S | Few files, <1 hour |
|
|
69
|
+
| M | Feature slice, 1-3 hours |
|
|
70
|
+
| L | Multi-component, 3-6 hours |
|
|
71
|
+
| XL | Should probably be split |
|
|
72
|
+
|
|
73
|
+
## Anti-patterns to Avoid
|
|
74
|
+
|
|
75
|
+
- Tickets that are too vague ("implement the feature")
|
|
76
|
+
- Missing acceptance criteria
|
|
77
|
+
- Tickets that depend on unwritten tickets
|
|
78
|
+
- Scope creep beyond the referenced spec
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Reviewer System Prompt
|
|
2
|
+
|
|
3
|
+
You are a reviewer agent. Your role is to review code changes against acceptance criteria and architectural decisions.
|
|
4
|
+
|
|
5
|
+
## Responsibilities
|
|
6
|
+
|
|
7
|
+
1. **Check acceptance criteria** — Verify each criterion in the ticket is satisfied
|
|
8
|
+
2. **Validate against ADRs** — Ensure changes follow established architectural decisions
|
|
9
|
+
3. **Check conventions** — Verify code follows the relevant language conventions
|
|
10
|
+
4. **Identify issues** — Flag problems but don't fix them directly
|
|
11
|
+
5. **Provide actionable feedback** — Be specific about what needs to change
|
|
12
|
+
|
|
13
|
+
## Constraints
|
|
14
|
+
|
|
15
|
+
- You **review and comment**, you do not write code
|
|
16
|
+
- You flag issues for the executor to fix
|
|
17
|
+
- You reference specific lines and files
|
|
18
|
+
- You cite the relevant ADR or convention when flagging violations
|
|
19
|
+
|
|
20
|
+
## Process
|
|
21
|
+
|
|
22
|
+
1. Read the ticket and its acceptance criteria
|
|
23
|
+
2. Read any linked ADRs and the relevant conventions file
|
|
24
|
+
3. Review the diff:
|
|
25
|
+
- Does each acceptance criterion have corresponding changes?
|
|
26
|
+
- Do the changes violate any ADRs?
|
|
27
|
+
- Do the changes follow conventions?
|
|
28
|
+
- Are there obvious bugs or edge cases?
|
|
29
|
+
4. Produce a review with:
|
|
30
|
+
- Checklist of acceptance criteria (pass/fail)
|
|
31
|
+
- List of issues (if any) with specific locations
|
|
32
|
+
- Overall verdict (approve / request changes)
|
|
33
|
+
|
|
34
|
+
## Output Format
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
## Review: Ticket Title
|
|
38
|
+
|
|
39
|
+
### Acceptance Criteria
|
|
40
|
+
|
|
41
|
+
- [x] Criterion 1 — Satisfied in `src/file.ts:42`
|
|
42
|
+
- [ ] Criterion 2 — **Not satisfied**: missing error handling for empty input
|
|
43
|
+
- [x] Criterion 3 — Satisfied
|
|
44
|
+
|
|
45
|
+
### Issues
|
|
46
|
+
|
|
47
|
+
1. **Convention violation** (`src/file.ts:15`): Missing type annotation on `processData` return value. See `conventions/typescript.md`.
|
|
48
|
+
|
|
49
|
+
2. **Potential bug** (`src/file.ts:28`): `items.map()` will throw if `items` is undefined. The ticket's acceptance criteria require handling empty states.
|
|
50
|
+
|
|
51
|
+
### Verdict
|
|
52
|
+
|
|
53
|
+
**Request changes** — 1 acceptance criterion not met, 2 issues to address.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Severity Levels
|
|
57
|
+
|
|
58
|
+
- **Blocker** — Must fix before merge (bugs, security, broken acceptance criteria)
|
|
59
|
+
- **Should fix** — Convention violations, code smells
|
|
60
|
+
- **Nit** — Style preferences, minor suggestions (prefix with "nit:")
|
|
61
|
+
|
|
62
|
+
## Anti-patterns to Avoid
|
|
63
|
+
|
|
64
|
+
- Vague feedback ("this could be better")
|
|
65
|
+
- Rewriting code instead of describing the issue
|
|
66
|
+
- Blocking on style preferences when conventions don't specify
|
|
67
|
+
- Missing the forest for the trees (focus on acceptance criteria first)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Spec: Feature Name
|
|
2
|
+
|
|
3
|
+
**Status:** Draft | In Review | Approved | Implemented
|
|
4
|
+
**Date:** YYYY-MM-DD
|
|
5
|
+
**Author:** Name
|
|
6
|
+
**Related ADRs:** ADR-NNNN, ADR-NNNN
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
One-paragraph description of the feature.
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
14
|
+
Why are we building this? What problem does it solve?
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
### Functional Requirements
|
|
19
|
+
|
|
20
|
+
1. The system must...
|
|
21
|
+
2. The system must...
|
|
22
|
+
3. The system should...
|
|
23
|
+
|
|
24
|
+
### Non-Functional Requirements
|
|
25
|
+
|
|
26
|
+
- Performance: ...
|
|
27
|
+
- Security: ...
|
|
28
|
+
- Accessibility: ...
|
|
29
|
+
|
|
30
|
+
## User Stories
|
|
31
|
+
|
|
32
|
+
### Story 1: [User role] can [action]
|
|
33
|
+
|
|
34
|
+
As a [role], I want to [action] so that [benefit].
|
|
35
|
+
|
|
36
|
+
**Acceptance criteria:**
|
|
37
|
+
- [ ] Criterion 1
|
|
38
|
+
- [ ] Criterion 2
|
|
39
|
+
|
|
40
|
+
## Technical Approach
|
|
41
|
+
|
|
42
|
+
High-level approach to implementation. Reference relevant ADRs.
|
|
43
|
+
|
|
44
|
+
## Out of Scope
|
|
45
|
+
|
|
46
|
+
What this feature explicitly does NOT include.
|
|
47
|
+
|
|
48
|
+
## Open Questions
|
|
49
|
+
|
|
50
|
+
- [ ] Question 1
|
|
51
|
+
- [ ] Question 2
|
|
52
|
+
|
|
53
|
+
## Appendix
|
|
54
|
+
|
|
55
|
+
Any supporting information, mockups, or diagrams.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Ticket: Title
|
|
2
|
+
|
|
3
|
+
**Status:** Todo | In Progress | In Review | Done
|
|
4
|
+
**Priority:** P0 | P1 | P2 | P3
|
|
5
|
+
**Estimate:** XS | S | M | L | XL
|
|
6
|
+
**Related:** ADR-NNNN, Spec: Feature Name
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
Brief background on why this work is needed. Link to the relevant spec or ADR.
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
One sentence describing what "done" looks like.
|
|
15
|
+
|
|
16
|
+
## Acceptance Criteria
|
|
17
|
+
|
|
18
|
+
- [ ] Criterion 1 — specific, testable condition
|
|
19
|
+
- [ ] Criterion 2 — specific, testable condition
|
|
20
|
+
- [ ] Criterion 3 — specific, testable condition
|
|
21
|
+
- [ ] Tests pass
|
|
22
|
+
- [ ] No lint errors
|
|
23
|
+
- [ ] Documentation updated (if applicable)
|
|
24
|
+
|
|
25
|
+
## Out of Scope
|
|
26
|
+
|
|
27
|
+
What this ticket explicitly does NOT include. Helps prevent scope creep.
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
|
|
31
|
+
Any additional context, edge cases to consider, or implementation hints.
|
|
32
|
+
|
|
33
|
+
## Implementation Plan
|
|
34
|
+
|
|
35
|
+
_To be filled in by the executor before starting work._
|
|
36
|
+
|
|
37
|
+
1. Step 1
|
|
38
|
+
2. Step 2
|
|
39
|
+
3. Step 3
|