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>
8.2 KiB
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
- Define
RequirementsManifestschema derived from the AST - Walk all dependency nodes across supported languages
- Emit setup scripts per package manager (apt, pip, npm, cargo, vcpkg)
- Cross-reference manifest against an EnvironmentSnapshot to get a gap report
- 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.tomlrequires-python,.python-version,setup.py - Node.js:
package.jsonengines.node,.nvmrc - Rust:
rust-toolchain.toml - C++: CMake
CMAKE_CXX_STANDARD - Java:
pom.xmlmaven.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