Add Sprints 111-117: closed-loop iteration epoch

Sprint 111: IterationSession context primitive
Sprint 112: EnvironmentSnapshot and diff
Sprint 113: Build output feedback loop
Sprint 114: Test failure feedback loop
Sprint 115: Requirements derivation from AST
Sprint 116: FeedbackLoopOrchestrator (wires 111-115)
Sprint 117: HiveMind integration (iteration steps as distributed jobs)

These sprints begin Epoch 3 — closed-loop determinism.
Sprints 1-110 made code generation open-loop deterministic.
Sprints 111+ make the full dev workflow (sense→act→observe→repeat)
structurally deterministic, with HiveMind as the execution layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill
2026-02-21 13:27:32 -07:00
parent b1d9cf6540
commit 84bdad8e9e
7 changed files with 1308 additions and 0 deletions

196
sprint115_plan.md Normal file
View File

@@ -0,0 +1,196 @@
# Sprint 115 Plan: Requirements Derivation from AST
## Context
Environment setup is currently manual and implicit. A developer knows their
project needs Python 3.11, numpy, and a running PostgreSQL instance because
they remember building it — not because the system can read that from the code.
Sprint 115 makes requirements derivation deterministic: given an AST, walk all
import/include/dependency nodes and produce a structured `RequirementsManifest`
— a language-agnostic list of what the project needs to run. From that manifest,
generate an idempotent setup script in the appropriate package manager format
(apt, pip, npm, cargo, cmake/vcpkg). Cross-reference the manifest against an
`EnvironmentSnapshot` (Sprint 112) to produce a gap report: what's missing,
what's the wrong version, what's ready.
This is the "environment as code" step: the project's needs become a
machine-readable artifact that any agent can check, compare, and act on.
---
## Goals
1. Define `RequirementsManifest` schema derived from the AST
2. Walk all dependency nodes across supported languages
3. Emit setup scripts per package manager (apt, pip, npm, cargo, vcpkg)
4. Cross-reference manifest against an EnvironmentSnapshot to get a gap report
5. Expose derivation and gap report as MCP tools
---
## Steps
### Step 1379: `RequirementsManifest` schema (12 tests)
Create `editor/src/RequirementsManifest.h`.
Fields: `manifest_id`, `source_file` (optional — if derived from single file),
`workspace` (optional — if derived from full project), `language_runtimes[]`
(name, min_version, source), `packages[]` (name, version_constraint,
package_manager: apt/pip/npm/cargo/vcpkg/brew/unknown),
`system_services[]` (name, port — e.g. postgres:5432, redis:6379),
`env_vars_required[]` (key, description, has_default: bool),
`derived_at`, `schema_version`.
Tests (12): constructable with defaults, manifest_id non-empty, packages
list starts empty, runtimes list starts empty, services list starts empty,
env_vars list starts empty, JSON serialization, JSON deserialization,
package_manager enum round-trips, unknown manager passthrough, schema_version
present, deterministic output.
### Step 1380: Import/include dependency walker (10 tests)
Create `editor/src/DependencyWalker.h`.
Walks an open AST, finds all import/include/require nodes, and extracts
package names. Language-specific strategies:
- Python: `import X`, `from X import Y` → package name is top-level module
- C/C++: `#include <X>` → system header; `#include "X"` → local (skip)
- JavaScript/TypeScript: `require('X')`, `import ... from 'X'` → npm package
- Rust: `extern crate X`, `use X::` → cargo crate
- Java: `import X.Y.Z` → Maven group
Stdlib modules filtered via a known-stdlib list per language (extensible).
Tests (10): Python import extracted, Python stdlib filtered, C++ system header
extracted, C++ local include skipped, JS require extracted, TS import extracted,
Rust extern crate extracted, Java import extracted, batch walk across multiple
files, deterministic output order.
### Step 1381: Runtime version inferrer (10 tests)
Create `editor/src/RuntimeVersionInferrer.h`.
Infers language runtime requirements from project configuration files:
- Python: `pyproject.toml` `requires-python`, `.python-version`, `setup.py`
- Node.js: `package.json` `engines.node`, `.nvmrc`
- Rust: `rust-toolchain.toml`
- C++: CMake `CMAKE_CXX_STANDARD`
- Java: `pom.xml` `maven.compiler.source`
Falls back to "any recent version" if no constraint found (min_version = "").
Tests (10): pyproject.toml version read, .python-version read, package.json
engines read, .nvmrc read, rust-toolchain.toml read, cmake standard read,
pom.xml source read, missing file returns no-constraint, multiple constraints
take strictest, deterministic output.
### Step 1382: Service dependency detector (10 tests)
Create `editor/src/ServiceDependencyDetector.h`.
Detects service dependencies from config files and connection string patterns
in source. Scans `.env`, `config.yaml`, `appsettings.json` for patterns like
`POSTGRES_HOST`, `REDIS_URL`, `MONGO_URI`, `DATABASE_URL`. Maps to
`SystemServiceRecord` (name, port).
Also detects from source: `psycopg2.connect(...)`, `mongoose.connect(...)`,
`redis.Redis(...)` call patterns in the AST.
Tests (10): postgres from .env POSTGRES_HOST, redis from REDIS_URL, mongo
from MONGO_URI, mysql from DATABASE_URL pattern, psycopg2 call in AST,
mongoose call in AST, redis.Redis call in AST, no false positives on
unrelated config, deterministic output, unknown service captured as unknown.
### Step 1383: Setup script generator (10 tests)
Create `editor/src/SetupScriptGenerator.h`.
Given a `RequirementsManifest`, generates an idempotent shell script per
requested package manager. Scripts use guard patterns (apt: check dpkg,
pip: check importlib, npm: check node_modules, cargo: check cargo metadata).
Output: `SetupScript` with fields `package_manager`, `script_text`,
`estimated_packages` (count), `requires_sudo` (bool).
One `whetstone_generate_setup_script` call may return multiple scripts
(one per relevant package manager detected from the manifest).
Tests (10): apt script generated for apt packages, pip script generated,
npm script generated, cargo script generated, idempotent guard present in
all scripts, sudo flag set for apt, not set for pip/npm/cargo, empty package
list produces no-op script, deterministic output, script text is valid shell.
### Step 1384: Requirements gap report (8 tests)
Create `editor/src/RequirementsGapReport.h`.
Cross-references `RequirementsManifest` against `EnvironmentSnapshot`.
Fields: `ready` (bool), `satisfied[]` (package name),
`missing[]` (name + required_version + package_manager),
`version_mismatch[]` (name + required + installed),
`unverifiable[]` (packages where installed version can't be confirmed),
`service_gaps[]` (services in manifest not found in snapshot processes).
Tests (8): ready true when all satisfied, missing package detected, version
mismatch detected, correct version passes, service gap detected, unverifiable
when probe can't confirm, JSON round-trip, deterministic output.
### Step 1385: `whetstone_derive_requirements` MCP tool (8 tests)
Input: `{ "workspace": string?, "files": string[]? }`
Output: `RequirementsManifest` JSON.
Walks all open buffers (or specified files), runs DependencyWalker +
RuntimeVersionInferrer + ServiceDependencyDetector, merges results.
Tests (8): tool registered, packages field present, runtimes field present,
services field present, empty workspace returns empty manifest, single file
mode works, manifest_id returned, deterministic output.
### Step 1386: `whetstone_generate_setup_script` MCP tool (8 tests)
Input: `{ "manifest_id": string?, "manifest": RequirementsManifest? }`
Output: `{ "scripts": SetupScript[] }`
Accepts either a previously derived manifest by ID or an inline manifest.
Tests (8): tool registered, scripts returned, apt script present for C++
project, pip script present for Python project, idempotent guards in output,
empty manifest returns empty scripts, manifest_id lookup works, deterministic.
### Step 1387: `whetstone_verify_requirements` MCP tool (8 tests)
Input: `{ "manifest_id": string, "snapshot_id": string }`
Output: `RequirementsGapReport` JSON.
Loads both from store, computes gap report.
Tests (8): tool registered, ready true when all installed, missing reported,
mismatch reported, service gap reported, missing manifest_id error, missing
snapshot_id error, deterministic output.
### Step 1388: Sprint 115 integration summary + regression (8 tests)
Create `editor/src/Sprint115IntegrationSummary.h`.
End-to-end: open Python project → derive_requirements → snapshot_environment →
verify_requirements → generate_setup_script → verify gap report matches missing
packages in snapshot.
Tests (8): headers constructable, tools registered, end-to-end flow works,
gap report accurate, setup script produced, no header exceeds 600 lines,
deterministic snapshots, full prior regression passes.
---
## Architecture Gate
- Dependency walker uses AST node traversal only — no regex on raw source text
- Service detection from config files uses ConfigFileProbe (Sprint 112) —
no duplicated parsing logic
- Setup scripts are never executed by Whetstone — generation only, execution
is the caller's responsibility
- Max 600 lines per header