@dforce2055/dai 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/.env.example +30 -0
- package/CHANGELOG.md +46 -0
- package/CODE_OF_CONDUCT.md +37 -0
- package/CONTRIBUTING.md +66 -0
- package/LICENSE +674 -0
- package/README.md +288 -0
- package/SECURITY.md +37 -0
- package/VERSION +1 -0
- package/cli/dai.mjs +692 -0
- package/cli/lib/ac-hash.mjs +74 -0
- package/cli/lib/args.mjs +23 -0
- package/cli/lib/bootstrap.mjs +74 -0
- package/cli/lib/env.mjs +23 -0
- package/cli/lib/forge-api.mjs +96 -0
- package/cli/lib/forge-url.mjs +61 -0
- package/cli/lib/fsutil.mjs +24 -0
- package/cli/lib/implements.mjs +94 -0
- package/cli/lib/link-us.mjs +59 -0
- package/cli/lib/pm-adapter.mjs +59 -0
- package/cli/lib/pm-clickup.mjs +54 -0
- package/cli/lib/pm-jira.mjs +123 -0
- package/cli/lib/pr.mjs +53 -0
- package/cli/lib/us.mjs +36 -0
- package/docs/EJEMPLO-END-TO-END.md +330 -0
- package/docs/MANIFIESTO.md +114 -0
- package/docs/METODOLOGIA.md +254 -0
- package/docs/PROBAR.md +91 -0
- package/docs/SCRUM-CON-IA.md +190 -0
- package/docs/adr/0001-contrato-ac-hash.md +86 -0
- package/docs/adr/0002-agnostico-del-asistente.md +87 -0
- package/docs/adr/0003-deteccion-y-estampado-son-comandos.md +73 -0
- package/docs/adr/0004-ubicacion-y-schema-implements.md +94 -0
- package/docs/adr/0005-superficie-comandos-y-stamp.md +65 -0
- package/docs/adr/0006-distribucion-y-licencia.md +59 -0
- package/docs/adr/0007-modelo-de-autenticacion.md +63 -0
- package/docs/adr/README.md +19 -0
- package/docs/detalle/01-refinamiento.md +33 -0
- package/docs/detalle/02-planning.md +27 -0
- package/docs/detalle/03-ramas.md +32 -0
- package/docs/detalle/04-tdd.md +35 -0
- package/docs/detalle/05-smoke.md +32 -0
- package/docs/detalle/06-code-review.md +34 -0
- package/docs/detalle/07-merge-trazabilidad.md +33 -0
- package/docs/detalle/08-daily.md +29 -0
- package/docs/detalle/09-review.md +25 -0
- package/docs/detalle/10-retro.md +27 -0
- package/docs/detalle/README.md +20 -0
- package/docs/glosario.md +79 -0
- package/docs/guias/dev.md +66 -0
- package/docs/guias/lead.md +53 -0
- package/docs/guias/po.md +50 -0
- package/governance/branch-naming.md +36 -0
- package/governance/ci-rules.md +57 -0
- package/governance/commit-convention.md +76 -0
- package/index.html +479 -0
- package/install.sh +19 -0
- package/manifest.yaml +76 -0
- package/package.json +55 -0
- package/skills/dai-review/SKILL.md +78 -0
- package/skills/doc-to-backlog/SKILL.md +70 -0
- package/skills/doc-to-backlog/templates/backlog-candidato.md +49 -0
- package/skills/grill-epic/SKILL.md +76 -0
- package/skills/grill-intent/SKILL.md +43 -0
- package/skills/grill-intent/templates/intent.md +36 -0
- package/skills/grill-user-story/SKILL.md +76 -0
- package/skills/grill-user-story/templates/user-story.md +61 -0
- package/skills/link-us/SKILL.md +42 -0
- package/skills/link-us/templates/implements.yaml +16 -0
- package/skills/tdd/SKILL.md +109 -0
- package/skills/tdd/deep-modules.md +33 -0
- package/skills/tdd/interface-design.md +31 -0
- package/skills/tdd/mocking.md +59 -0
- package/skills/tdd/refactoring.md +10 -0
- package/skills/tdd/tests.md +61 -0
- package/templates/adr.md +43 -0
- package/templates/commit-msg +48 -0
- package/templates/definition-of-done.md +50 -0
- package/templates/definition-of-ready.md +51 -0
- package/templates/epica.md +62 -0
- package/templates/formato-us.md +129 -0
- package/templates/pull-request.md +62 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants integration tests, or asks for test-first development.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test-Driven Development
|
|
7
|
+
|
|
8
|
+
## Philosophy
|
|
9
|
+
|
|
10
|
+
**Core principle**: Tests should verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
|
|
11
|
+
|
|
12
|
+
**Good tests** are integration-style: they exercise real code paths through public APIs. They describe _what_ the system does, not _how_ it does it. A good test reads like a specification - "user can checkout with valid cart" tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
|
|
13
|
+
|
|
14
|
+
**Bad tests** are coupled to implementation. They mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behavior hasn't changed. If you rename an internal function and tests fail, those tests were testing implementation, not behavior.
|
|
15
|
+
|
|
16
|
+
See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for mocking guidelines.
|
|
17
|
+
|
|
18
|
+
## Anti-Pattern: Horizontal Slices
|
|
19
|
+
|
|
20
|
+
**DO NOT write all tests first, then all implementation.** This is "horizontal slicing" - treating RED as "write all tests" and GREEN as "write all code."
|
|
21
|
+
|
|
22
|
+
This produces **crap tests**:
|
|
23
|
+
|
|
24
|
+
- Tests written in bulk test _imagined_ behavior, not _actual_ behavior
|
|
25
|
+
- You end up testing the _shape_ of things (data structures, function signatures) rather than user-facing behavior
|
|
26
|
+
- Tests become insensitive to real changes - they pass when behavior breaks, fail when behavior is fine
|
|
27
|
+
- You outrun your headlights, committing to test structure before understanding the implementation
|
|
28
|
+
|
|
29
|
+
**Correct approach**: Vertical slices via tracer bullets. One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behavior matters and how to verify it.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
WRONG (horizontal):
|
|
33
|
+
RED: test1, test2, test3, test4, test5
|
|
34
|
+
GREEN: impl1, impl2, impl3, impl4, impl5
|
|
35
|
+
|
|
36
|
+
RIGHT (vertical):
|
|
37
|
+
RED→GREEN: test1→impl1
|
|
38
|
+
RED→GREEN: test2→impl2
|
|
39
|
+
RED→GREEN: test3→impl3
|
|
40
|
+
...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Workflow
|
|
44
|
+
|
|
45
|
+
### 1. Planning
|
|
46
|
+
|
|
47
|
+
When exploring the codebase, use the project's domain glossary so that test names and interface vocabulary match the project's language, and respect ADRs in the area you're touching.
|
|
48
|
+
|
|
49
|
+
Before writing any code:
|
|
50
|
+
|
|
51
|
+
- [ ] Confirm with user what interface changes are needed
|
|
52
|
+
- [ ] Confirm with user which behaviors to test (prioritize)
|
|
53
|
+
- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
|
|
54
|
+
- [ ] Design interfaces for [testability](interface-design.md)
|
|
55
|
+
- [ ] List the behaviors to test (not implementation steps)
|
|
56
|
+
- [ ] Get user approval on the plan
|
|
57
|
+
|
|
58
|
+
Ask: "What should the public interface look like? Which behaviors are most important to test?"
|
|
59
|
+
|
|
60
|
+
**You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.
|
|
61
|
+
|
|
62
|
+
### 2. Tracer Bullet
|
|
63
|
+
|
|
64
|
+
Write ONE test that confirms ONE thing about the system:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
RED: Write test for first behavior → test fails
|
|
68
|
+
GREEN: Write minimal code to pass → test passes
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This is your tracer bullet - proves the path works end-to-end.
|
|
72
|
+
|
|
73
|
+
### 3. Incremental Loop
|
|
74
|
+
|
|
75
|
+
For each remaining behavior:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
RED: Write next test → fails
|
|
79
|
+
GREEN: Minimal code to pass → passes
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Rules:
|
|
83
|
+
|
|
84
|
+
- One test at a time
|
|
85
|
+
- Only enough code to pass current test
|
|
86
|
+
- Don't anticipate future tests
|
|
87
|
+
- Keep tests focused on observable behavior
|
|
88
|
+
|
|
89
|
+
### 4. Refactor
|
|
90
|
+
|
|
91
|
+
After all tests pass, look for [refactor candidates](refactoring.md):
|
|
92
|
+
|
|
93
|
+
- [ ] Extract duplication
|
|
94
|
+
- [ ] Deepen modules (move complexity behind simple interfaces)
|
|
95
|
+
- [ ] Apply SOLID principles where natural
|
|
96
|
+
- [ ] Consider what new code reveals about existing code
|
|
97
|
+
- [ ] Run tests after each refactor step
|
|
98
|
+
|
|
99
|
+
**Never refactor while RED.** Get to GREEN first.
|
|
100
|
+
|
|
101
|
+
## Checklist Per Cycle
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
[ ] Test describes behavior, not implementation
|
|
105
|
+
[ ] Test uses public interface only
|
|
106
|
+
[ ] Test would survive internal refactor
|
|
107
|
+
[ ] Code is minimal for this test
|
|
108
|
+
[ ] No speculative features added
|
|
109
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Deep Modules
|
|
2
|
+
|
|
3
|
+
From "A Philosophy of Software Design":
|
|
4
|
+
|
|
5
|
+
**Deep module** = small interface + lots of implementation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────┐
|
|
9
|
+
│ Small Interface │ ← Few methods, simple params
|
|
10
|
+
├─────────────────────┤
|
|
11
|
+
│ │
|
|
12
|
+
│ │
|
|
13
|
+
│ Deep Implementation│ ← Complex logic hidden
|
|
14
|
+
│ │
|
|
15
|
+
│ │
|
|
16
|
+
└─────────────────────┘
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Shallow module** = large interface + little implementation (avoid)
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
┌─────────────────────────────────┐
|
|
23
|
+
│ Large Interface │ ← Many methods, complex params
|
|
24
|
+
├─────────────────────────────────┤
|
|
25
|
+
│ Thin Implementation │ ← Just passes through
|
|
26
|
+
└─────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
When designing interfaces, ask:
|
|
30
|
+
|
|
31
|
+
- Can I reduce the number of methods?
|
|
32
|
+
- Can I simplify the parameters?
|
|
33
|
+
- Can I hide more complexity inside?
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Interface Design for Testability
|
|
2
|
+
|
|
3
|
+
Good interfaces make testing natural:
|
|
4
|
+
|
|
5
|
+
1. **Accept dependencies, don't create them**
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// Testable
|
|
9
|
+
function processOrder(order, paymentGateway) {}
|
|
10
|
+
|
|
11
|
+
// Hard to test
|
|
12
|
+
function processOrder(order) {
|
|
13
|
+
const gateway = new StripeGateway();
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. **Return results, don't produce side effects**
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// Testable
|
|
21
|
+
function calculateDiscount(cart): Discount {}
|
|
22
|
+
|
|
23
|
+
// Hard to test
|
|
24
|
+
function applyDiscount(cart): void {
|
|
25
|
+
cart.total -= discount;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **Small surface area**
|
|
30
|
+
- Fewer methods = fewer tests needed
|
|
31
|
+
- Fewer params = simpler test setup
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# When to Mock
|
|
2
|
+
|
|
3
|
+
Mock at **system boundaries** only:
|
|
4
|
+
|
|
5
|
+
- External APIs (payment, email, etc.)
|
|
6
|
+
- Databases (sometimes - prefer test DB)
|
|
7
|
+
- Time/randomness
|
|
8
|
+
- File system (sometimes)
|
|
9
|
+
|
|
10
|
+
Don't mock:
|
|
11
|
+
|
|
12
|
+
- Your own classes/modules
|
|
13
|
+
- Internal collaborators
|
|
14
|
+
- Anything you control
|
|
15
|
+
|
|
16
|
+
## Designing for Mockability
|
|
17
|
+
|
|
18
|
+
At system boundaries, design interfaces that are easy to mock:
|
|
19
|
+
|
|
20
|
+
**1. Use dependency injection**
|
|
21
|
+
|
|
22
|
+
Pass external dependencies in rather than creating them internally:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Easy to mock
|
|
26
|
+
function processPayment(order, paymentClient) {
|
|
27
|
+
return paymentClient.charge(order.total);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Hard to mock
|
|
31
|
+
function processPayment(order) {
|
|
32
|
+
const client = new StripeClient(process.env.STRIPE_KEY);
|
|
33
|
+
return client.charge(order.total);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**2. Prefer SDK-style interfaces over generic fetchers**
|
|
38
|
+
|
|
39
|
+
Create specific functions for each external operation instead of one generic function with conditional logic:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// GOOD: Each function is independently mockable
|
|
43
|
+
const api = {
|
|
44
|
+
getUser: (id) => fetch(`/users/${id}`),
|
|
45
|
+
getOrders: (userId) => fetch(`/users/${userId}/orders`),
|
|
46
|
+
createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// BAD: Mocking requires conditional logic inside the mock
|
|
50
|
+
const api = {
|
|
51
|
+
fetch: (endpoint, options) => fetch(endpoint, options),
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The SDK approach means:
|
|
56
|
+
- Each mock returns one specific shape
|
|
57
|
+
- No conditional logic in test setup
|
|
58
|
+
- Easier to see which endpoints a test exercises
|
|
59
|
+
- Type safety per endpoint
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Refactor Candidates
|
|
2
|
+
|
|
3
|
+
After TDD cycle, look for:
|
|
4
|
+
|
|
5
|
+
- **Duplication** → Extract function/class
|
|
6
|
+
- **Long methods** → Break into private helpers (keep tests on public interface)
|
|
7
|
+
- **Shallow modules** → Combine or deepen
|
|
8
|
+
- **Feature envy** → Move logic to where data lives
|
|
9
|
+
- **Primitive obsession** → Introduce value objects
|
|
10
|
+
- **Existing code** the new code reveals as problematic
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Good and Bad Tests
|
|
2
|
+
|
|
3
|
+
## Good Tests
|
|
4
|
+
|
|
5
|
+
**Integration-style**: Test through real interfaces, not mocks of internal parts.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// GOOD: Tests observable behavior
|
|
9
|
+
test("user can checkout with valid cart", async () => {
|
|
10
|
+
const cart = createCart();
|
|
11
|
+
cart.add(product);
|
|
12
|
+
const result = await checkout(cart, paymentMethod);
|
|
13
|
+
expect(result.status).toBe("confirmed");
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Characteristics:
|
|
18
|
+
|
|
19
|
+
- Tests behavior users/callers care about
|
|
20
|
+
- Uses public API only
|
|
21
|
+
- Survives internal refactors
|
|
22
|
+
- Describes WHAT, not HOW
|
|
23
|
+
- One logical assertion per test
|
|
24
|
+
|
|
25
|
+
## Bad Tests
|
|
26
|
+
|
|
27
|
+
**Implementation-detail tests**: Coupled to internal structure.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// BAD: Tests implementation details
|
|
31
|
+
test("checkout calls paymentService.process", async () => {
|
|
32
|
+
const mockPayment = jest.mock(paymentService);
|
|
33
|
+
await checkout(cart, payment);
|
|
34
|
+
expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Red flags:
|
|
39
|
+
|
|
40
|
+
- Mocking internal collaborators
|
|
41
|
+
- Testing private methods
|
|
42
|
+
- Asserting on call counts/order
|
|
43
|
+
- Test breaks when refactoring without behavior change
|
|
44
|
+
- Test name describes HOW not WHAT
|
|
45
|
+
- Verifying through external means instead of interface
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// BAD: Bypasses interface to verify
|
|
49
|
+
test("createUser saves to database", async () => {
|
|
50
|
+
await createUser({ name: "Alice" });
|
|
51
|
+
const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
|
|
52
|
+
expect(row).toBeDefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// GOOD: Verifies through interface
|
|
56
|
+
test("createUser makes user retrievable", async () => {
|
|
57
|
+
const user = await createUser({ name: "Alice" });
|
|
58
|
+
const retrieved = await getUser(user.id);
|
|
59
|
+
expect(retrieved.name).toBe("Alice");
|
|
60
|
+
});
|
|
61
|
+
```
|
package/templates/adr.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ARCHITECTURE DECISION RECORD (ADR) · dai
|
|
3
|
+
─────────────────────────────────────────────────────────────────
|
|
4
|
+
Registra UNA decisión de fondo, con su contexto y sus consecuencias.
|
|
5
|
+
Es inmutable una vez aceptada: si la decisión cambia, se escribe un
|
|
6
|
+
ADR NUEVO que "supersede" a este (no se edita el viejo).
|
|
7
|
+
|
|
8
|
+
Los ADR son la forma de enmendar el MANIFIESTO y de cerrar las
|
|
9
|
+
decisiones abiertas de la metodología. Numerar secuencial: 0001, 0002…
|
|
10
|
+
Nombre de archivo: NNNN-slug-corto.md
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
# ADR-NNNN — <título de la decisión>
|
|
14
|
+
|
|
15
|
+
- **Estado:** propuesto | aceptado | supersedido por `ADR-XXXX`
|
|
16
|
+
- **Fecha:** YYYY-MM-DD
|
|
17
|
+
- **Decide:** <rol/persona con autoridad para la decisión>
|
|
18
|
+
|
|
19
|
+
## Contexto
|
|
20
|
+
|
|
21
|
+
Qué situación obliga a decidir. Las fuerzas en juego (restricciones, dolores,
|
|
22
|
+
requisitos). Lo suficiente para que alguien que cae de nuevo entienda por qué esto
|
|
23
|
+
no era obvio. Sin todavía elegir.
|
|
24
|
+
|
|
25
|
+
## Decisión
|
|
26
|
+
|
|
27
|
+
Lo que decidimos, en presente afirmativo: *"Usamos X."* Clara y sin ambigüedad.
|
|
28
|
+
|
|
29
|
+
## Consecuencias
|
|
30
|
+
|
|
31
|
+
Qué se vuelve más fácil y qué más difícil por haber decidido esto. Lo bueno **y**
|
|
32
|
+
lo que aceptamos pagar. Incluye las obligaciones nuevas (p. ej. "el CI ahora debe…").
|
|
33
|
+
|
|
34
|
+
## Alternativas consideradas
|
|
35
|
+
|
|
36
|
+
- **<Opción B>** — por qué se descartó.
|
|
37
|
+
- **<Opción C>** — por qué se descartó.
|
|
38
|
+
|
|
39
|
+
<!--
|
|
40
|
+
Un buen ADR se lee en 2 minutos. Si necesita más, probablemente son varias
|
|
41
|
+
decisiones: pártelo. La sección más valiosa es "Consecuencias" — es lo que el
|
|
42
|
+
yo-del-futuro va a agradecer cuando se pregunte "¿por qué hicimos esto?".
|
|
43
|
+
-->
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# commit-msg · dai · valida que el mensaje siga Conventional Commits
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# Formato: <tipo>(<scope>)!: <resumen>
|
|
6
|
+
# tipo obligatorio · scope opcional · "!" opcional (breaking change)
|
|
7
|
+
# resumen en imperativo, minúscula, sin punto final, hasta 72 caracteres
|
|
8
|
+
#
|
|
9
|
+
# Cero dependencias: POSIX sh + grep. No necesita dai, node ni commitlint.
|
|
10
|
+
# Instalación: ver governance/commit-convention.md (husky o git hook pelado).
|
|
11
|
+
# =============================================================================
|
|
12
|
+
|
|
13
|
+
msg_file="$1"
|
|
14
|
+
# Primera línea que no sea comentario (git antepone líneas '#').
|
|
15
|
+
subject=$(grep -vE '^\s*#' "$msg_file" | sed '/./,$!d' | head -1)
|
|
16
|
+
|
|
17
|
+
# Dejar pasar merges, reverts, fixup/squash y commits de bots (🤖).
|
|
18
|
+
case "$subject" in
|
|
19
|
+
"Merge "*|"Revert "*|"fixup! "*|"squash! "*|"🤖"*) exit 0 ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9._/-]+\))?!?: .{1,72}$'
|
|
23
|
+
|
|
24
|
+
if printf '%s' "$subject" | grep -qE "$pattern"; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo ""
|
|
29
|
+
echo " ✗ Mensaje de commit inválido"
|
|
30
|
+
echo " ───────────────────────────────────────────────"
|
|
31
|
+
echo " tu mensaje: $subject"
|
|
32
|
+
echo ""
|
|
33
|
+
echo " formato: <tipo>(<scope>): <resumen>"
|
|
34
|
+
echo " tipos: feat · fix · docs · style · refactor · perf"
|
|
35
|
+
echo " test · build · ci · chore · revert"
|
|
36
|
+
echo " reglas: resumen en imperativo, minúscula, sin punto final, ≤72"
|
|
37
|
+
echo " '!' tras el scope marca un breaking change"
|
|
38
|
+
echo ""
|
|
39
|
+
echo " ejemplos: feat(cart): rechaza finalizar un carrito vacío"
|
|
40
|
+
echo " fix(auth): corrige el refresh del token"
|
|
41
|
+
echo " docs: aclara los niveles N1/N2/N3"
|
|
42
|
+
echo " refactor(api)!: unifica el contrato de /orders"
|
|
43
|
+
echo ""
|
|
44
|
+
echo " traza: si el commit implementa una US, referénciala en el"
|
|
45
|
+
echo " cuerpo (p. ej. \"US: ABC-482\") — el link vive en el"
|
|
46
|
+
echo " implements.yaml, pero mencionarlo ayuda a leer el historial."
|
|
47
|
+
echo ""
|
|
48
|
+
exit 1
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
DEFINITION OF DONE (DoD) · dai
|
|
3
|
+
─────────────────────────────────────────────────────────────────
|
|
4
|
+
El contrato de cierre del CÓMO: cuándo una implementación está
|
|
5
|
+
realmente terminada. Cubre los pasos 4–7 de SCRUM-CON-IA.
|
|
6
|
+
|
|
7
|
+
Es configurable por organización (sobre todo el ítem de despliegue),
|
|
8
|
+
pero los ítems de trazabilidad y tests NO se negocian.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
# Definition of Done — ¿la implementación está terminada?
|
|
12
|
+
|
|
13
|
+
> "Terminada" no es "compila". Es testeable, trazable, revisada y con el estado
|
|
14
|
+
> derivado, no reportado a mano.
|
|
15
|
+
|
|
16
|
+
## Checklist
|
|
17
|
+
|
|
18
|
+
### Tests (TDD)
|
|
19
|
+
- [ ] Cada criterio de aceptación tiene su **test** y está **verde**. *([Art. 3](../docs/MANIFIESTO.md#art-3))*
|
|
20
|
+
- [ ] Los tests verifican por la **interfaz pública**, no espían lo interno.
|
|
21
|
+
- [ ] El **smoke** end-to-end del flujo pasa.
|
|
22
|
+
|
|
23
|
+
### Trazabilidad (el link)
|
|
24
|
+
- [ ] Existe `implements.yaml` con `id`, `version` y `ac_hash`. *(Art. 9)*
|
|
25
|
+
- [ ] El **`ac_hash` coincide** con el de la US vigente (no se implementó una versión atrasada). *(Art. 11)*
|
|
26
|
+
- [ ] La rama sigue la convención (`feature/ABC-###-<slug>`) → ver `governance/branch-naming.md`.
|
|
27
|
+
|
|
28
|
+
### Revisión
|
|
29
|
+
- [ ] Pasó el **primer pase de IA** (`dai-review`): sin problemas de correctitud.
|
|
30
|
+
- [ ] Un **partner aprobó** el PR/MR (en N1, auto-review honesto). *(Art. 5, Art. 15)*
|
|
31
|
+
- [ ] Cumple los estándares del repo (lint, tipos, convenciones).
|
|
32
|
+
|
|
33
|
+
### Cierre
|
|
34
|
+
- [ ] El change se promovió (`opsx:apply` → `opsx:archive`) si aplica.
|
|
35
|
+
- [ ] El **CI estampó la cobertura** en el gestor (no la escribió una persona). *(Art. 10)*
|
|
36
|
+
- [ ] La US quedó en estado **implementada**.
|
|
37
|
+
|
|
38
|
+
## Configurable: ¿"done" incluye desplegado?
|
|
39
|
+
|
|
40
|
+
Cada organización define hasta dónde llega su DoD según su **nivel de ceremonia**
|
|
41
|
+
(**N1** dev solo · **N2** equipo compacto · **N3** organización grande — ver
|
|
42
|
+
[glosario](../docs/glosario.md)):
|
|
43
|
+
|
|
44
|
+
| | El DoD termina en… |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **N1 / N2** | mergeado + cobertura estampada. El deploy es aparte. |
|
|
47
|
+
| **N3** | mergeado + **desplegado en el ambiente acordado** (p. ej. `test`), con el CD reportando la versión viva por ambiente. |
|
|
48
|
+
|
|
49
|
+
> **Implementación ≠ despliegue.** El CI dice "el repo implementó `@v3`"; el CD dice
|
|
50
|
+
> "`@v3` está viva en `pre`". El DoD elige cuál de los dos es el corte de "terminado".
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
DEFINITION OF READY (DoR) · dai
|
|
3
|
+
─────────────────────────────────────────────────────────────────
|
|
4
|
+
El contrato del gate ENTRE el QUÉ y el CÓMO: cuándo una User Story
|
|
5
|
+
está lista para entrar a un sprint / ser implementada.
|
|
6
|
+
|
|
7
|
+
Lo verifica una persona (y la IA puede pre-chequearlo). Si un ítem
|
|
8
|
+
no se cumple, la US NO entra: vuelve a grill-user-story o grill-intent.
|
|
9
|
+
Es la contracara del Definition of Done.
|
|
10
|
+
-->
|
|
11
|
+
|
|
12
|
+
# Definition of Ready — ¿la US está lista para implementarse?
|
|
13
|
+
|
|
14
|
+
> Una US que no cumple esto no se planifica. No es burocracia: es lo que evita
|
|
15
|
+
> arrancar a codear sobre un QUÉ vago ([Art. 7](../docs/MANIFIESTO.md#art-7) — no vibe coding).
|
|
16
|
+
|
|
17
|
+
## Checklist
|
|
18
|
+
|
|
19
|
+
### Identidad y forma (linkeable)
|
|
20
|
+
- [ ] Tiene **ID estable** (ticket del gestor, p. ej. `ABC-###`). *(Art. 8)*
|
|
21
|
+
- [ ] Tiene **`spec_version`** (`v1` al nacer).
|
|
22
|
+
- [ ] Tiene **autor** identificado.
|
|
23
|
+
- [ ] Sigue el formato canónico (`templates/formato-us.md`).
|
|
24
|
+
|
|
25
|
+
### Problema validado (Gate 0)
|
|
26
|
+
- [ ] Pasó `grill-intent`: el **problema** fue desafiado y el veredicto es `a-spec`.
|
|
27
|
+
- [ ] Se sabe **quién** siente el dolor (un rol concreto, no "el usuario").
|
|
28
|
+
- [ ] Se sabe el **costo de no hacerlo** (por qué ahora).
|
|
29
|
+
|
|
30
|
+
### Criterios testeables
|
|
31
|
+
- [ ] Los **criterios de aceptación** están en **Gherkin** (Dado/Cuando/Entonces).
|
|
32
|
+
- [ ] **Cada** criterio puede volverse un **test**. *(Art. 3 — testeable o no existe)*
|
|
33
|
+
- [ ] Ningún criterio menciona tablas, endpoints ni framework (eso es CÓMO).
|
|
34
|
+
|
|
35
|
+
### Alcance y contexto
|
|
36
|
+
- [ ] Hay **flujos**: happy path + al menos una excepción.
|
|
37
|
+
- [ ] Está explícito el **fuera de scope**.
|
|
38
|
+
- [ ] Las **dependencias** (otras US, sistemas, decisiones) están listadas.
|
|
39
|
+
|
|
40
|
+
### Tamaño (INVEST)
|
|
41
|
+
- [ ] Es **chica**: entra en un sprint. Si desborda, se **parte** antes de entrar.
|
|
42
|
+
- [ ] Es **independiente**: no depende de otra US a medias.
|
|
43
|
+
|
|
44
|
+
## Regla de calibración por nivel
|
|
45
|
+
|
|
46
|
+
- **N1 (dev solo):** el DoR se auto-verifica; el `proposal.md` de OpenSpec hace de US.
|
|
47
|
+
Igual se exige: criterios testeables + fuera de scope. Lo demás se aligera.
|
|
48
|
+
- **N2 (equipo compacto):** DoR completo, verificado por el que agarra la US.
|
|
49
|
+
- **N3 (federado):** DoR completo + firma del PO + Gate 0 formal registrado.
|
|
50
|
+
|
|
51
|
+
> El link no se negocia; la ceremonia alrededor sí (Art. 13, Art. 15).
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
FORMATO DE ÉPICA · dai
|
|
3
|
+
─────────────────────────────────────────────────────────────────
|
|
4
|
+
Una épica es un bloque grande de valor de negocio que se parte en
|
|
5
|
+
varias User Stories. Es funcional y de alto nivel: define el ALCANCE,
|
|
6
|
+
no el detalle ni el CÓMO.
|
|
7
|
+
|
|
8
|
+
La épica NO se implementa directamente: agrupa. Las US que la componen
|
|
9
|
+
son las que viajan por el flujo (grill-intent → grill-user-story → ...).
|
|
10
|
+
El link QUÉ↔CÓMO vive a nivel US, no de épica.
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
# 🔗 Metadata
|
|
14
|
+
|
|
15
|
+
| Campo | Valor |
|
|
16
|
+
|-------|-------|
|
|
17
|
+
| **ID** | `ABC-###` (épica en el gestor) |
|
|
18
|
+
| **Autor** | quién la definió |
|
|
19
|
+
| **Estado** | `abierta` \| `en curso` \| `cerrada` |
|
|
20
|
+
| **US que la componen** | `ABC-###`, `ABC-###` … _(se completa a medida que se parten)_ |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# <Título de la épica>
|
|
25
|
+
|
|
26
|
+
Orientado a la capacidad de negocio grande. Una frase.
|
|
27
|
+
|
|
28
|
+
## Objetivo de negocio
|
|
29
|
+
|
|
30
|
+
Qué resultado de negocio persigue esta épica. Por qué importa ahora. 2–4 líneas.
|
|
31
|
+
|
|
32
|
+
## Alcance
|
|
33
|
+
|
|
34
|
+
Qué entra y qué **no** entra en esta épica. El límite grueso que después las US
|
|
35
|
+
respetan.
|
|
36
|
+
|
|
37
|
+
- **Dentro** — <capacidades que sí cubre>
|
|
38
|
+
- **Fuera** — <lo que explícitamente queda para otra épica>
|
|
39
|
+
|
|
40
|
+
## User Stories (partición)
|
|
41
|
+
|
|
42
|
+
Lista viva de las US en las que se parte. Cada una es independiente y cabe en un
|
|
43
|
+
sprint (INVEST). No es el detalle: es el índice.
|
|
44
|
+
|
|
45
|
+
- [ ] `ABC-###` — <título corto de la US>
|
|
46
|
+
- [ ] `ABC-###` — <título corto de la US>
|
|
47
|
+
|
|
48
|
+
## Métricas de éxito
|
|
49
|
+
|
|
50
|
+
Cómo sabremos que la épica agregó valor (indicadores de negocio, no de construcción).
|
|
51
|
+
|
|
52
|
+
- <métrica observable>
|
|
53
|
+
|
|
54
|
+
## Dependencias y riesgos
|
|
55
|
+
|
|
56
|
+
- <otra épica / sistema / decisión que tiene que existir antes o en paralelo>
|
|
57
|
+
|
|
58
|
+
<!--
|
|
59
|
+
REGLA: si una "US" no cabe en un sprint, probablemente sea una épica y haya que
|
|
60
|
+
partirla. Si una "épica" no se puede partir en US independientes, probablemente
|
|
61
|
+
sea una sola US grande. El corte es el sprint.
|
|
62
|
+
-->
|