Skip to content

Commit b387c56

Browse files
committed
SpecFlow OSS
0 parents  commit b387c56

463 files changed

Lines changed: 106569 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/commands/document.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Create comprehensive documentation for a new feature or component:
2+
3+
1. Read `CLAUDE.md` and `agents/IMPLEMENTATION.md` to understand current state
4+
2. Create feature documentation in `agents/plans/<feature>/`
5+
3. Include:
6+
- **Overview**: Purpose and scope
7+
- **Architecture**: How it fits in the system
8+
- **State Management**: State machine usage (if applicable)
9+
- **API**: Endpoints and schemas (if applicable)
10+
- **Database**: Firestore collections and documents (if applicable)
11+
- **Testing**: Test strategy and coverage
12+
- **Dependencies**: External services or libraries
13+
- **Edge Cases**: Known limitations and gotchas
14+
4. Update `agents/IMPLEMENTATION.md` with implementation status
15+
5. Use references to code, not code duplication
16+
6. Keep it concise and scannable (aim for 100-200 lines)
17+
18+
Focus on what developers need to know to work with this feature.

.claude/commands/review-backend.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
You are an expert reviewer for this AI SDLC accelerator codebase. Your job is to find real bugs, not style issues.
2+
3+
## Context
4+
5+
This backend uses a strict state machine architecture. The canonical sources of truth are:
6+
- `backend/app/schemas/estimation_enums.py``EstimationStatus`, `EstimationCheckpoint`, `WorkspaceStatus`, `CHECKPOINT_ORDER`
7+
- `backend/app/state/` — the ONLY place allowed to write status/checkpoint/workspace_phases to Firestore
8+
- `backend/app/state/transitions.py` — legal transitions
9+
- `CLAUDE.md` — Steel Commandments (especially I–X)
10+
11+
## Steps
12+
13+
1. If no PR number given, run `gh pr list` and ask which one to review.
14+
2. Run `gh pr diff <number>` to get the full diff.
15+
3. Run `gh pr view <number>` for the description.
16+
17+
## What to check — in this exact priority order
18+
19+
### 🔴 CRITICAL — These are production bugs if missed
20+
21+
**1. Enum contract violations (`estimation_enums.py`)**
22+
- Was `EstimationStatus` modified (values added, removed, renamed, reordered)?
23+
- Was `EstimationCheckpoint` modified?
24+
- Was `CHECKPOINT_ORDER` list changed? This controls checkpoint ordering validation — any change breaks `advance_checkpoint()` for all in-flight estimations.
25+
- Was `WorkspaceStatus` modified?
26+
- Flag ANY change to this file. Even adding a new value can break running estimations that don't know about it.
27+
28+
**2. Direct Firestore writes outside `backend/app/state/`** (Commandment VII)
29+
Look for any of these patterns outside `backend/app/state/`:
30+
- `db.update("estimations", ...)` or `db.set("estimations", ...)` with `status`, `checkpoint`, `workspace_phases`, or `workspace_phases_deployment`
31+
- `self._esm._db.` accessed from service or workflow files
32+
- `self.db.update(...)` writing status/checkpoint fields directly
33+
- String literals like `{"status": "running"}` or `{"checkpoint": "generation_done"}` written directly
34+
The CI guard (`ci/check_state_writes.sh`) catches most but not all patterns. Review manually too.
35+
36+
**3. Missing checkpoint advancement**
37+
Every major workflow step that completes a logical phase MUST advance `EstimationCheckpoint` via `estimation_service.update_checkpoint()` or `_esm.advance_checkpoint()`. Check:
38+
- Does each new workflow step call `update_checkpoint` at the end?
39+
- Is the checkpoint value from `EstimationCheckpoint` (never a bare string)?
40+
- Is the checkpoint consistent with `CHECKPOINT_ORDER`? (must go forward)
41+
- For LOCAL_ONLY vs INTEGRATION_TESTS_READY paths: does each path advance to the correct checkpoint? (e.g. LOCAL_ONLY skips `DEPLOY_AND_E2E_DONE`)
42+
43+
**4. Missing `state_history` append** (Commandment IX)
44+
Any new state machine method that writes to Firestore must append to `state_history` with: `status`, `at` (UTC), `triggered_by`, `metadata`. Check `_record_phase_progress_for_field`, `init_deployment_phases`, and any new methods added in `backend/app/state/`.
45+
46+
**5. Workspace safety violations** (Commandments I–VI)
47+
- Does `fail()` or `stuck_detected()` release any workspace? It must NOT — only `failed_at` timestamp side-effect is allowed.
48+
- Does any code path touch an ALLOCATED workspace from a background job? Only `stuck_detected()` on the estimation is allowed.
49+
- Does `complete()` still require `outputs_archived == True` AND archive branch confirmed before releasing workspaces?
50+
- On retry: if `code_archived == False`, does it reuse the same `workspace_ids`? Never fall back to fresh workspaces silently.
51+
52+
### 🟡 HIGH — Logic bugs that cause silent corruption
53+
54+
**6. Brittle status/checkpoint string comparisons**
55+
Look for:
56+
- `if status == "running":` — must use `EstimationStatus.RUNNING`
57+
- `if checkpoint == "generation_done":` — must use `EstimationCheckpoint.GENERATION_DONE`
58+
- `doc.get("status") == "failed"` — same issue
59+
- Resume logic using raw dict string keys for status comparisons (using `.get("last_completed_phase", 0)` for data fields is fine; comparing status values is not)
60+
61+
**7. Invalid transition action names in `_validate_transition` / `_require_running`**
62+
- Is a method using `_validate_transition(doc, "advance_checkpoint", ...)` when it's not actually advancing a checkpoint? The action name appears in error messages and logs — misuse produces misleading diagnostics.
63+
- New state machine methods that only need a RUNNING guard should use `_require_running(doc, "method_name", generation_id)`.
64+
65+
**8. Checkpoint order violations**
66+
- Is `advance_checkpoint()` called with a checkpoint that could go backward? (e.g., `GENERATION_DONE` after `ESTIMATION_DONE`)
67+
- On retry/resume: does the code respect the saved checkpoint and resume forward from it? Does it ever reset checkpoint to an earlier value?
68+
69+
**9. `init_*` methods that aren't idempotent**
70+
Any init method called before a loop (like `init_deployment_phases`) must be a no-op if already initialized, to survive retries. Check that new init methods guard against overwriting existing progress.
71+
72+
### 🔴 CRITICAL — Graceful failure and audit logging
73+
74+
**12. Hard stoppers in non-essential operations**
75+
Non-essential operations (P10Y estimation, archiving, notifications, metric collection, telemetry) must NEVER crash the workflow. Check:
76+
- Does any new non-essential step propagate an unhandled exception that would abort the whole estimation run?
77+
- Are errors caught, logged with `logger.warning`/`logger.error`, and stored in the relevant Firestore audit fields (e.g. `state_history`, error context on the estimation/workspace doc)?
78+
- `assert` statements are forbidden outside of tests — they raise `AssertionError` (stripped with `-O`) and produce opaque crashes. Replace with a typed exception and a clear message.
79+
- Background tasks (archiving, notifications) must catch and log their own exceptions so a failure does not surface to the caller or abort an in-progress estimation.
80+
81+
### 🟠 MEDIUM — Robustness issues
82+
83+
**10. Resume logic correctness**
84+
For any new phase loop (generation or deployment):
85+
- Does `last_completed >= total_phases` correctly skip already-done workspaces?
86+
- Does `last_completed > 0` correctly set `start_phase = last_completed + 1`?
87+
- Is `total_phases` read from the stored checkpoint data (not recalculated), so a retry with a different plan doesn't corrupt resume?
88+
89+
**11. `workspace_ids` assumptions**
90+
- Does new code assume `workspace_ids` is always populated? It may be empty before allocation.
91+
- Is `workspace_ids` ever modified outside of the allocation path?
92+
93+
### 🟡 HIGH — CLAUDE.md coding pattern adherence
94+
95+
**13. Coding pattern violations**
96+
Check new code against the mandatory patterns from `CLAUDE.md`:
97+
- **Pydantic/dataclasses/OOP over raw dicts and strings** — new data passed between functions should use typed models, not bare `dict`/`str`.
98+
- **Enums over string literals** — any new status, type, or category value must be an `Enum` member, not a bare string.
99+
- **SRP / Open-Closed** — new classes should have a single responsibility; extensions should not require modifying existing classes.
100+
- **Imports at the top of the file** — no lazy imports inside functions or methods.
101+
- **Small functions / DRY** — flag functions that duplicate logic already present elsewhere, or that are doing more than one thing.
102+
- **No raw collections as public API** — functions returning `dict`/`list` for structured data should return a typed model instead.
103+
- **Model with the right paradigm for clarity** — choose the tool that makes the domain intent obvious at the call site: pure functions for stateless transforms, magic methods for natural domain operations (`current + delta` via `__add__` instead of manual field construction), OOP for encapsulating state and invariants. Flag code that uses a weaker paradigm when a stronger one would eliminate boilerplate and make the intent self-evident.
104+
105+
## What NOT to flag
106+
107+
- Minor inefficiencies (extra dict copy, redundant log line)
108+
- Test structure preferences
109+
- Docstring/comment quality on unchanged code
110+
- The `progress` field — this is explicitly exempt from the state machine write guard (it's owned by the workflow display layer)
111+
112+
## Output format
113+
114+
Group findings by severity. For each finding:
115+
- File and line number
116+
- The exact problematic code snippet
117+
- Why it's a bug (reference the relevant Commandment or rule above)
118+
- The correct fix
119+
120+
End with a one-line verdict: **APPROVED**, **APPROVED WITH NITS**, or **CHANGES REQUIRED**.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Parity: same intent as Cursor `/review` (`.cursor/commands/review.md`). For PR-style `gh` review, use `review-backend.md`.
2+
3+
Review code changes against SpecFlow project standards:
4+
5+
1. Check that state changes go through `backend/app/state/` machines only
6+
2. Verify no direct Firestore writes for status/checkpoint/workspace_phases
7+
3. Confirm tests still pass (baseline: 584+)
8+
4. Check type hints on all function signatures
9+
5. Verify error handling follows guard clause pattern
10+
6. Confirm logging includes context (request_id, generation_id, etc.)
11+
7. Check async/await usage is correct
12+
8. Verify STEEL COMMANDMENTS compliance (workspace safety)
13+
9. Check for anti-patterns (see `.cursor/rules/backend-python.mdc`)
14+
10. Confirm no absolute paths in generated files
15+
16+
Run `make check` and `make unit-tests` to validate.

.claude/commands/state-machine.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
Debug or modify state machine logic:
2+
3+
1. Understand state machine architecture:
4+
- Read docs/ARCHITECTURE.md (State Machine Layer)
5+
- Read backend/app/state/estimation_state_machine.py
6+
- Read backend/app/state/workspace_state_machine.py
7+
- Read backend/app/state/transitions.py (all valid transitions)
8+
9+
2. Key principles (STEEL COMMANDMENTS):
10+
- State machines are ONLY writers of status/checkpoint
11+
- No code outside backend/app/state/ may write these fields
12+
- CI enforces this: ci/check_state_writes.sh
13+
- Every transition logged in state_history
14+
- Invalid transitions raise immediately
15+
- Checkpoints never go backward
16+
17+
3. Common tasks:
18+
19+
**Add new transition**:
20+
a. Add to ESTIMATION_TRANSITIONS or WORKSPACE_TRANSITIONS in transitions.py
21+
b. Add method to EstimationStateMachine or WorkspaceStateMachine
22+
c. Method must: validate transition, write status, append state_history
23+
d. Add tests to backend/test/test_state/
24+
e. Update docs/ARCHITECTURE.md state diagrams
25+
26+
**Fix invalid transition error**:
27+
a. Check current status in Firestore
28+
b. Review transitions.py for valid paths
29+
c. Check if estimation stuck in FAILED (cannot resume)
30+
d. Use retry with workspace reuse if code not archived
31+
32+
**Debug transition not happening**:
33+
a. Check state_history in Firestore document
34+
b. Look for InvalidEstimationStateError in logs
35+
c. Verify caller using state machine (not direct DB write)
36+
d. Check if CI guard would catch it: `./ci/check_state_writes.sh`
37+
38+
4. State machine methods (EstimationStateMachine):
39+
- create() - PENDING
40+
- begin_allocation() - PENDING → INITIALIZING
41+
- allocation_succeeded() - INITIALIZING → RUNNING
42+
- allocation_failed() - INITIALIZING → FAILED
43+
- advance_checkpoint() - Update progress
44+
- fail() - * → FAILED
45+
- stuck_detected() - Write failed_at, keep workspaces ALLOCATED
46+
- complete() - RUNNING → COMPLETED, archive_and_release()
47+
48+
5. State machine methods (WorkspaceStateMachine):
49+
- allocate() - AVAILABLE → ALLOCATED
50+
- archive_and_release() - ALLOCATED → CLEANING
51+
- allocation_rollback() - INITIALIZING estimation failed
52+
- mark_available() - CLEANING → AVAILABLE
53+
- force_release() - Operator only, audit trail required
54+
55+
6. Testing state machines:
56+
```bash
57+
cd backend && uv run pytest test/test_state/ -v
58+
```
59+
- Test all valid transitions
60+
- Test invalid transitions raise
61+
- Test state_history logging
62+
- Test checkpoint ordering
63+
64+
Reference:
65+
- State machines: backend/app/state/
66+
- Transitions: backend/app/state/transitions.py
67+
- Tests: backend/test/test_state/
68+
- CI guard: ci/check_state_writes.sh
69+
- STEEL COMMANDMENTS: CLAUDE.md (rules VII-X)

.claude/commands/test.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Run full test suite and validation:
2+
3+
1. Run `make unit-tests` in backend directory
4+
2. Check test count (baseline: 584+ passing)
5+
3. Review test output for any warnings or deprecations
6+
4. If tests fail:
7+
- Read test output carefully
8+
- Check if changes broke existing functionality
9+
- Verify mocks are properly configured
10+
- Check async test fixtures
11+
- Review state machine transitions
12+
5. Run `make check` for static analysis (ruff, mypy, vulture)
13+
6. Format code with `make format` if needed
14+
15+
Expected: All tests pass, no linter errors, 584+ tests passing.

.claude/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"enabledPlugins": {
3+
"pyright-lsp@claude-plugins-official": true
4+
}
5+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
name: backend-quality-gate
3+
description: After substantive edits under backend/app, run static checks and optional Radon complexity (matches Makefile and Cursor post-write hook intent).
4+
---
5+
6+
# Backend quality gate (SpecFlow)
7+
8+
Use when finishing or reviewing a change that touches `backend/app/**/*.py`.
9+
10+
## Steps
11+
12+
1. From repo root: `make check` (ruff, mypy, vulture as in Makefile).
13+
2. If the change is non-trivial: `make check-complexity` (summary) or `make check-complexity-diff` against `main` (see `CLAUDE.md` for `METRIC=cc|mi|hal`).
14+
3. For a single file: `make check-complexity-cc FILE=app/...` and `make check-complexity-mi FILE=app/...`.
15+
4. Confirm SRP, DRY, and that state/credential rules match `docs/PATTERNS/INDEX.md` and `.cursor/rules/backend-python.mdc`.
16+
17+
**Note:** Cursor may show ruff/radon inline via `.cursor/hooks.json`; that does not replace `make check` or tests.
18+
19+
## Tests
20+
21+
- `make unit-tests` (required before merge for substantive work)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
name: deploy-requirements
3+
description: Generate a customer-specific deployment requirements document from the template. Takes customer name and known infrastructure details as input. Produces a filled-in requirements spec ready for human review before sending to the customer.
4+
argument-hint: <customer-name> <known details about their infrastructure>
5+
disable-model-invocation: true
6+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash(ls:*), Bash(mkdir:*)
7+
---
8+
9+
# Generate Customer Deployment Requirements Spec
10+
11+
You are a GAIN implementation engineer preparing a deployment requirements document for a customer. This document will be sent to the customer's platform/DevOps team as part of presales and implementation.
12+
13+
## Input
14+
15+
The user provided: $ARGUMENTS
16+
17+
Parse this for:
18+
- **Customer name** (first argument or identifiable from context)
19+
- **Known infrastructure details** (cloud provider, K8s setup, services, integrations, etc.)
20+
21+
## Process
22+
23+
### Step 1: Read the template
24+
25+
Read the template at `docs/operations/deployment-requirements-template.md`. This is your structural reference — every section must appear in the output.
26+
27+
### Step 2: Fill in what you know
28+
29+
From the user's input, fill in all fields where information was provided. Be precise — use exact values given (account IDs, cluster names, URLs, etc.).
30+
31+
For fields where information was **not** provided:
32+
- Leave the field blank with a `<!-- TODO: confirm with customer -->` comment
33+
- If you can make a reasonable inference from context (e.g., AWS implies ECR for registry), fill it in but mark with `<!-- INFERRED: verify with customer -->`
34+
35+
### Step 3: Tailor the document
36+
37+
- Replace all generic references with the customer name
38+
- Remove options that don't apply (e.g., if customer is AWS, remove GCP/Azure examples from tables)
39+
- Keep the section numbering and structure intact
40+
- Preserve the checklist in §9 — update it to reflect customer-specific items
41+
42+
### Step 4: Handle open questions
43+
44+
- Keep §10 (Questions for Customer) but **remove questions that are already answered** by the provided input
45+
- Add any **new customer-specific questions** that arise from the details given (e.g., if they mention a service mesh, ask which one)
46+
- Mark unanswered questions with severity: `[BLOCKING]` if estimation can't start without it, `[NICE-TO-HAVE]` otherwise
47+
48+
### Step 5: Write the output
49+
50+
Save the completed document to:
51+
```
52+
docs/operations/customers/{customer-name}-deployment-requirements.md
53+
```
54+
55+
Use kebab-case for the customer name in the filename.
56+
57+
## Output quality rules
58+
59+
- **Tone:** Professional technical document between companies. No casual language.
60+
- **Completeness:** Every section from the template must appear. Empty sections get a TODO comment, never deleted.
61+
- **Precision:** Use exact values. Don't paraphrase technical details — account IDs, URLs, namespace patterns must be verbatim.
62+
- **Open questions are OK:** This document is used to start the conversation. Gaps marked with TODO are expected and useful — they show the customer exactly what GAIN still needs.
63+
- **No invented details:** If you don't know something, leave it blank with TODO. Never guess account IDs, secret paths, or endpoints.
64+
65+
## Final message
66+
67+
After writing the file, summarize:
68+
1. How many sections are fully filled vs have TODOs
69+
2. List all `[BLOCKING]` open questions
70+
3. The output file path

0 commit comments

Comments
 (0)