Files
nextcraft/.ciagent/ARCHITECTURE.md
T
CIAgent 2c68b44c1a merge: milestone/v0.4-distribution → main (v0.4 Distribution & Bootstrap CLI complete)
The nextcraft bootstrap CLI ships: doctor/bootstrap/verify/dev commands, a
one-liner install script with checksum + version integrity gates, and linux
x64 SEA binaries published on every release going forward (v0.3.2 onward).
Fresh-clone E2E proven; 34 CLI tests + full monorepo gates green.

Escalation note: merge_to_main hook — proceeding per full autonomy + founder
directive D-016 (streamlined install + bootstrap CLI + ongoing binaries,
recorded at P0 SPECIFY).

---ci---
phase: 4
milestone: v0.4
status: complete
requirements:
  covered: [REQ-4-001, REQ-4-002, REQ-4-003, REQ-4-004, REQ-4-005]
  partial: []
---/ci---
2026-09-12 23:17:43 +00:00

31 KiB
Raw Blame History

Nextcraft — ARCHITECTURE.md

Overview

Nextcraft is a TypeScript monorepo (pnpm workspaces + turborepo) with a Next.js application hosting four surfaces (Learner, Marketplace, Employer Dashboard, Admin), a shared component library, typed mock data layer, and shared types package. As of v0.2, a Python FastAPI application (apps/ai-service) hosts six AI tutor agents backed by a provider-agnostic LLM layer.

v0.3 additions (Credential Engines): real credential engines replace v0.2 mock inputs — a sandbox fabric (isolated per-learner coding environments via Linux user/mount/pid/net namespaces), a live build-telemetry pipeline (WebSocket ingest + SQLite-ordered event log), a process-trace grading engine, seeded per-learner variant task generation, and a voice-based oral defense (STT/TTS via a new provider-agnostic voice layer). First real persistence introduced: SQLite (ai_service/telemetry/, grading, variant, defense stores). Lab/Assessor/Proctor agents are re-grounded onto real telemetry/traces. Identity/age-gating (KYC) deferred per founder directive — no security engineer persona; secrets-hygiene checklist only.

v0.4 additions (Distribution & Bootstrap CLI, founder directive D-016): a new apps/cli package — the nextcraft bootstrap CLI (doctor/bootstrap/verify/dev) compiled to a self-contained linux x64 binary via Node SEA (probe-verified: Go/Rust absent, node v24.15.0 SEA-capable), installed by a repo-served one-liner script that resolves the latest Gitea release, downloads binary + sha256 sidecar, verifies, and installs to ~/.local/bin. Every release from v0.4 onward attaches the binary + checksum as release assets (the "ongoing binaries" requirement). The CLI is a thin wrapper: all orchestration logic stays in apps/ai-service/scripts/ (bootstrap.sh/dev.sh) — the CLI composes them via subprocess (A-202), duplicating nothing. Previously-planned v0.4 seams (real STT/TTS, KYC, design/sim envs, seq-lease) move to v0.5.

Confirmed Technology Stack (v0.2)

Technology Version Purpose
Node.js v24.15.0 Runtime (web)
pnpm 12.3.4 Package manager + workspaces
turborepo 2.3.3 Build orchestration
Next.js 15 (App Router) Web application framework
React 19+ UI library
TypeScript 5.x Type system
Tailwind CSS v4 Utility-first CSS
lucide-react latest Icons
recharts latest Charts
@xyflow/react latest Competency graph viewer
Python 3.11.2 Runtime (ai-service)
FastAPI 0.141.x AI service framework
uvicorn 0.52.x ASGI server
pydantic 2.13.x Request/response models, structured outputs
pydantic-settings 2.15.x Settings + env-file loading (replaces python-dotenv)
httpx 0.28.x Async LLM HTTP client (ollama-cloud + local providers)
sqlmodel / sqlalchemy 0.0.24 / 2.x Typed SQLite persistence for the v0.3 engine stores (D-027)
python-multipart 0.0.x Multipart audio upload for the defense answer route (REQ-3-006)
sse-starlette 3.4.x SSE framing, ping keep-alive
pytest 9.x Test runner
pytest-asyncio 1.4.x Async tests (auto mode)
ruff latest Python lint (check-only, no formatter) — pnpm ai:lint
ollama-cloud https://ollama.com/v1 Default LLM provider (OpenAI-compatible, Bearer auth)

Deliberately not used: openai-python SDK (the LLMProvider protocol is the port; raw httpx keeps delta passthrough and ollama-cloud quirk tolerance), python-dotenv (pydantic-settings reads .env natively), respx (httpx MockTransport is built in).

v0.2 Architecture Decisions (from Research)

  1. D-016 SSE envelopemeta event (agent/session/model, flushed before first token) → raw OpenAI-compatible chunk passthrough → optional doneerror event before [DONE] on mid-stream failure. Pre-first-byte failures use proper HTTP status. Headers: Cache-Control: no-cache, X-Accel-Buffering: no.
  2. D-017 httpx direct client — lifespan-managed httpx.AsyncClient (10s connect / 300s read), shared by ollama-cloud and local providers; no SDK.
  3. D-018 Agent frameworkBaseAgent ABC (system_prompt/build_messages/stream_reply/structured_reply) + explicit registry; prompts are versioned code in prompts/.
  4. D-019 Session storeSessionStore protocol + InMemorySessionStore (asyncio.Lock, 20-message window, 500-cap LRU, agent-scoped sessions). DB-migration-ready.
  5. D-020 Structured outputs — 4-layer defense: response_format (auto-degrade) → prompt-embedded schema → fence-strip/first-balanced-object parse → single bounded retry.
  6. D-021 Mock corpus in Pythonai_service/corpus/ pydantic-typed, convention-aligned with TS packages/mock-data (shared IDs, cross-referencing headers); no codegen in v0.2.
  7. D-022 Monorepo integration — zero-dependency shim package.json in apps/ai-service + ai#* turbo passthrough tasks (cache:false, outputs:[]) + root ai:dev/ai:test scripts + idempotent venv bootstrap.
  8. D-023 Testing — pytest-asyncio auto mode; TestClient client.stream() for SSE; httpx MockTransport for byte-exact provider parser tests; scripted mock provider incl. failure modes. Tests never call the cloud.

v0.4 Architecture Decisions (from Research — Distribution & Bootstrap CLI)

  1. D-033 Binary toolchain = Node SEA (probe-verified) — Go and Rust are absent from this box; node v24.15.0 ships SEA support (--experimental-sea-config, postject-free on linux via cp node nextcraft && node sea-config … blob injection with the system dd/npx postject if needed). CLI source lives in apps/cli (TypeScript, compiled to a single CJS bundle by esbuild, then SEA-injected into a copy of the node binary → nextcraft-linux-x64). Fallback if SEA breaks: python3 zipapp (3.11.2 available). No new toolchain deps beyond dev-scoped esbuild.
  2. D-034 CLI = thin wrapper, orchestration stays in scripts/nextcraft composes apps/ai-service/scripts/bootstrap.sh and scripts/dev.sh equivalents via spawn with inherited stdio and timeout guards (A-202/A-209). doctor/bootstrap/verify implement only checking logic (prereqs, env template, health) — never re-implement installs. This keeps one source of truth for bootstrap semantics.
  3. D-035 Install path = repo raw install.sh + Gitea latest-release API — the one-liner curl -fsSL <forge>/coreci/nextcraft/raw/main/scripts/install.sh | bash resolves GET /api/v1/repos/coreci/nextcraft/releases/latest, downloads the nextcraft-linux-x64 + nextcraft-linux-x64.sha256 assets, verifies sha256 (shasum -a 256), installs to ~/.local/bin (PATH hint), and degrades to printed source-bootstrap instructions when no binary asset exists or the platform mismatches (A-203/A-204/A-206).
  4. D-036 Ongoing binaries = ship-workflow asset step — the release pipeline (v0.3's ShipWorkflow.createRelease equivalent, executed as the ship step's asset stage) builds the binary + checksum and attaches both to every Gitea release from v0.4 onward (A-205). Token resolution stays .env*-only (D-006/D-014); binaries are linux x64 only for v0.4 (macOS arm64 deferred — unverifiable on this box).
  5. D-037 CLI package layoutapps/cli is a pnpm workspace package (@nextcraft/cli): src/ (entry, commands/, checks/, lib/), scripts/build-binary.mjs (esbuild bundle → SEA inject), unit tests runnable via pnpm --filter @nextcraft/cli test (node:test, no new test framework). Root package.json gains cli:* passthrough scripts mirroring the ai:* pattern (D-022).

v0.3 Architecture Decisions (from Research — Credential Engines)

  1. D-024 Sandbox isolation = Linux namespaces via unshare — per-learner sandbox runs as a subprocess entered into fresh user+mount+pid+network namespaces (unshare --user --map-root-user --mount --pid --fork --net). Probe-verified on this box: in-namespace uid=0, network fully isolated (0 interfaces), learner writes land in a per-sandbox directory; proc-remount not permitted here but not required. Chosen because no container runtime (docker/podman/bwrap/firejail) exists on the box and there is no sudo. A SandboxBackend protocol abstracts the spawner so a future containerd/runc backend can replace namespace-spawning without touching callers.
  2. D-025 Sandbox scope = coding IDE only (v0.3) — the sandbox fabric provisions a single build environment (shell + filesystem + run/test). REQ-F-021's design-tool and simulation environments are deferred to v0.4; one real build path proves the full credential pipeline (telemetry → trace → grade → defense).
  3. D-026 Telemetry = WebSocket ingest + SQLite ordered event log — in-sandbox capture agent streams structured events over WebSocket to ai_service (/v1/telemetry/ingest); events persisted to SQLite with a per-(learner,task) monotonic seq for gap detection, giving durability + at-least-once delivery + replay without a message broker.
  4. D-027 First persistence = SQLite, protocol-wrapped — introduces a real DB (ai_service/data/*.db) for telemetry traces, grades, variants, and defenses. Access via SQLModel. Every store is a protocol (TraceStore, VariantStore, DefenseStore, GradeStore) with a SQLite implementation — Postgres-migration-ready, mirroring D-019's SessionStore pattern.
  5. D-028 Process-trace grading = hybrid deterministic + LLM — deterministic features (test pass/fail, edit count, error/fix cycles, idle gaps, command categories) computed in code into a compact trace digest; the digest feeds an Assessor-style rubric prompt and returns structured scores via D-020 JSON defense. The LLM never sees the raw trace — only the digest.
  6. D-029 Variant generation = seeded template instantiation — task templates with typed parameter slots; an LLM instantiates a unique variant per learner from a seed; seed+parameters persisted (D-027) for grading fairness and proctoring cross-check.
  7. D-030 Voice = provider-agnostic, mock-first, browser-fallback — a VoiceProvider protocol (mirror of LLMProvider) with STT (OpenAI-compatible /audio/transcriptions) + TTS (/audio/speech) against a configurable endpoint, a deterministic mock (canned transcript/audio) for tests, and browser-native SpeechRecognition/speechSynthesis as a no-key fallback. Voice defense reuses BaseAgent + the existing SSE pipeline (new Examiner agent).
  8. D-031 No new apps — extend ai-service — telemetry, grading, variant, voice, and sandbox orchestration are new modules inside apps/ai-service (sharing the LLM pool, config, and session infra). Only the in-sandbox capture agent is a separate tiny Python process shipped into the namespace. No new top-level apps/ entry.
  9. D-032 Capacity = single-box, 15 concurrent sandboxes — concurrency guard returns 503 when the sandbox pool is full. No queueing, no horizontal scaling in v0.3 (solo-founder/pilot scale).

Components

apps/ai-service — AI Tutor Service (v0.2 NEW)

Component Description Boundaries Depends On
ai_service/main.py FastAPI app factory, lifespan (httpx client pool, provider factory, SandboxManager + reaper loop, SQLite engine stores on app.state), CORS (localhost only, incl. PUT for file writes), /health App entry config, llm, agents, api, engines
ai_service/config.py pydantic-settings Settings (env_prefix="AI_", env_file, SecretStr key) Configuration only None
ai_service/api/ Endpoints: chat.py (POST /v1/chat/stream, SSE), lab.py, assessment.py (POST /v1/assessment/evaluate v0.2 + POST /v1/assessment/grade v0.3), proctor.py, mentor.py, sandboxes.py (lifecycle + files/exec routes, G-5 abuse gates), telemetry.py (WS ingest + trace/gaps reads), variants.py (seeded per-learner variants), defense.py (defense loop, REQ-3-006); deps.py (DI) Composes agents + sessions + engines; never imported by llm/ or agents/ agents, llm, sandbox, telemetry, grading, variants, voice
ai_service/llm/ types.py (Message; ChatDelta/ChoiceDelta removed in P3 — no consumers), base.py (LLMProvider protocol), openai_compat.py (ollama-cloud + local), mock.py (deterministic), factory.py Never imports agents/ or api/ config
ai_service/agents/ base.py (BaseAgent ABC), registry.py, session.py (SessionStore), structured.py (JSON defense), coach/tutor/lab/assessor/proctor/mentor.py + examiner.py (seventh agent, v0.3) Never imports api/ llm, prompts, corpus, telemetry
ai_service/prompts/ Per-agent system prompt constants + render_context functions (str.format_map) Data only None
ai_service/corpus/ Mock engine inputs: learner_context.py, telemetry.py (Lab/Proctor scenarios), artifacts.py (pre-baked artifacts, rubrics, transcripts). Since v0.3 P6 these are DORMANT, test-only fixtures (dormant-header noted) — the live learner path uses real engine inputs Pydantic-typed; aligned with TS packages/mock-data by convention None
scripts/ bootstrap.sh (venv + pip install idempotent), dev.sh (exports keys from .ciagent/.env.secrets → uvicorn), test.sh (pytest), lint.sh (ruff check, v0.2 G-3) Dev entry points pyproject.toml
tests/ conftest.py (mock provider, settings override, TestClient), health, llm (MockTransport parser), agents (framework + per-agent), api (SSE stream tests) Mock provider only — no cloud all

Module boundary rules: llm/ never imports agents/ or api/; agents/ never imports api/; api/ composes both via DI. corpus/ is the only home of mock engine data. Prompts are code — versioned and reviewed in git.

apps/ai-service — v0.3 Credential Engine modules (NEW)

Component Description Boundaries Depends On
ai_service/sandbox/ backend.py (SandboxBackend protocol), unshare_backend.py (userns/mount/pid/net spawner, D-024), manager.py (lifecycle: create/list/snapshot/destroy + concurrency guard D-032), workdir.py (per-sandbox fs layout) Never imports api/ or agents/; spawns subprocesses only config
ai_service/telemetry/ models.py (TelemetryEvent, TraceSpan), store.py (TraceStore protocol + SQLite impl D-027), ingest.py (WebSocket /v1/telemetry/ingest, seq gap detection D-026) Persistence; never imports agents/ config
ai_service/grading/ features.py (deterministic trace digest D-028), engine.py (rubric scoring orchestration), store.py (GradeStore) LLM only via digest; never sees raw trace llm, telemetry, prompts
ai_service/variants/ templates.py (task template library), generator.py (seeded LLM instantiation D-029), store.py (VariantStore) LLM via structured output llm, grading
ai_service/voice/ base.py (VoiceProvider protocol D-030), browser.py (native SR/TTS fallback descriptor), mock.py (deterministic; the real server STT/TTS provider is the v0.4 seam — GRILL CUT-1/G-7), factory.py (provider selection), defense_store.py (DefenseStore: transcripts + integrity signals, D-027) Never imports agents/ or api/ config
ai_service/agents/examiner.py Seventh agent: oral defense examiner; streams over existing SSE, consumes process traces + emits integrity signals reuses BaseAgent (D-018) llm, prompts, telemetry
ai_service/data/*.db SQLite databases (telemetry/grades/variants/defenses) gitignored
scripts/sandbox-agent.py Tiny in-namespace capture process shipped into the sandbox; streams telemetry to ingest standalone stdlib only

Boundary additions: sandbox/, telemetry/, grading/, variants/, voice/ are engine modules — they never import api/ (which composes them via DI) and never import agents/ (agents call engines through narrow interfaces, not vice versa).

apps/cli — Nextcraft Bootstrap CLI (v0.4 NEW)

Component Description Boundaries Depends On
src/index.ts Entry: arg parsing (no deps beyond node stdlib at runtime), command dispatch, --help/--version, exit-code contract (0 ok / 1 failure / 2 usage) CLI surface only commands/
src/commands/ doctor.ts (prereq checks + actionable errors), bootstrap.ts (pnpm install + scripts/bootstrap.sh wrapper + env template copy + key validation), verify.ts (health: venv imports, ports, env, build readiness), dev.ts (thin passthrough to scripts/dev.sh) Compose checks/ + lib/; spawn scripts — never re-implement them checks/, lib/
src/checks/ Pure check functions: check-command.ts (binary-on-PATH + version compare), check-env.ts (template diff, required/optional key classification) Pure logic, unit-testable, no fs side effects at import None
src/lib/ spawn.ts (subprocess with timeout + inherited stdio), log.ts (✓/✗/warn output formatter) Shared utilities None
scripts/build-binary.mjs esbuild → CJS bundle → Node SEA injection → dist/nextcraft-linux-x64 + sha256 sidecar Build-time only esbuild (dev dep)
scripts/install.sh The one-liner install script served from repo raw: Gitea latest-release resolve → download + checksum verify → ~/.local/bin; source-bootstrap fallback Standalone POSIX sh forge API
tests/ node:test unit tests: command dispatch, check logic, env template diff, install-script shellcheck-style assertions Fixtures only — never mutate repo state src/

Boundary rules: the CLI never imports from apps/web, packages/*, or ai_service Python modules — it orchestrates them exclusively via subprocess/filesystem. Runtime deps: node stdlib only (no runtime npm deps; esbuild is dev-only). The binary embeds the bundle; scripts/bootstrap.sh remains the single source of bootstrap truth (D-034).

apps/web — Next.js Application

Component Description Boundaries Depends On
app/(learner)/ Learner surface route group: landing, catalog, competency stack, dashboard, byte viewer, build surface (/build/[competencyId] — real in-browser build), defense surface (/defend/[competencyId] — live oral defense + grading) Learner-only routes and layouts packages/ui, packages/mock-data, packages/types
app/(marketplace)/ Marketplace surface route group: job board, job detail, employer profile, search/filter, pricing Marketplace-only routes and layouts packages/ui, packages/mock-data, packages/types
app/(employer)/ Employer dashboard route group: overview, talent search, candidate profile, posting management Employer-only routes and layouts packages/ui, packages/mock-data, packages/types
app/(admin)/ Admin surface route group: overview, learner management, competency graph viewer, moderation Admin-only routes and layouts packages/ui, packages/mock-data, packages/types
app/layout.tsx Root layout: theme provider, navigation shell, responsive container All routes packages/ui
components/ Surface-specific components (learner/, marketplace/, employer/, admin/) plus shared chrome (navigation-shell, header/footer, role-switcher, theme-provider, breadcrumbs, dark-mode-toggle); v0.3 learner: build-surface, sandbox-terminal (read-only exec output), defense-session App-level components packages/ui
hooks/ use-chat-stream.ts — SSE client hook: fetch + ReadableStream, byte buffering + frame reassembly, idempotent AbortController cleanup; use-sandbox-session.ts (v0.3) — sandbox lifecycle for the build session: create on task open, destroy on unmount, mid-start failure cleanup, 503/403/429 honest surfaces Client components only ai-service SSE / engine API
lib/ sse.ts (shared SSE frame parser — CRLF normalization + : ping immunity, v0.2 G-1), breadcrumbs.ts, format.ts, engine-client.ts (v0.3: typed fetch client for /v1/sandboxes, files/exec, variants, grade, defense, traces) Pure utilities None

packages/ui — Shared Component Library

Component Description Boundaries Depends On
tokens/ Design tokens as TS constants: colors, spacing, radii, shadows, breakpoints (mirrored as Tailwind v4 @theme tokens in apps/web globals.css) Foundation layer — no dependencies None
primitives/ Button, Input, Card, Badge, Avatar (v0.1) + TerminalFrame, TelemetryStatus, MicControl, GradeBadge, TranscriptViewer (v0.3 build/defense surfaces) — each with a Storybook story Atomic UI components tokens, packages/types

Composite/layout/theme components (navigation shell, tables, chat panels, graph viewer, theme provider) live in apps/web/components/ as app-level components, not in packages/ui.

packages/mock-data — Mock Data Layer

Component Description Boundaries Depends On
competency-stacks.ts 5 competency stacks (AI Orchestration Engineer, AI Safety & Governance, Human-AI Product Designer, AI-Augmented Field Operator, Computational Sciences), each with 12-18 competencies Typed mock data packages/types
jobs.ts 20+ mock AI-era job listings with skills, seniority, salary, match scores Typed mock data packages/types
candidates.ts 15+ mock candidate profiles with artifacts, process traces, defense scores, microcredentials Typed mock data packages/types
employers.ts 10+ mock employer profiles with logos, descriptions, open positions Typed mock data packages/types
learner-progress.ts Mock learner progress data: active competencies, completion percentages, recent artifacts Typed mock data packages/types
admin.ts Admin surface mock data: platform metrics, activity feed, system health, learner roster (admin view), moderation queues Typed mock data packages/types
ai-scenarios.ts AI engine-input scenario IDs + display metadata for the learner agent panels; IDs string-identical to ai_service/corpus/ (D-021) Typed mock data packages/types

packages/types — Shared Types

Component Description Boundaries Depends On
domain.ts Competency, CompetencyStack, Microcredential, Artifact, ProcessTrace, OralDefense, AssessmentRubric Domain types None
marketplace.ts Job, Employer, Candidate, JobPosting, TalentMatch, SearchFilter Marketplace types None
user.ts Learner, Admin, EmployerUser, AgeGroup, Role User types None
ui.ts Component props, theme config, breakpoint definitions UI types None
telemetry.ts TelemetryEvent/ExecResult wire shapes for the live build surface (v0.3) Engine types None
variants.ts Variant/TaskTemplate shapes for per-learner task statements (v0.3) Engine types None
grading.ts GradeRecord/RubricScore shapes for live grading display (v0.3) Engine types None
defense.ts DefenseSession/transcript/integrity-signal shapes for the defense surface (v0.3) Engine types None

Data Flow

v0.3 credential flow (current)

[learner build surface /build/*]                [learner defense surface /defend/*]
   file CRUD + Run/Test (HTTP)                     mic MediaRecorder / typed + TTS playback
        │                                                  │
        ▼                                                  ▼
[api/sandboxes files/exec] ──exec──▶ [namespace sandbox]    [api/defense start/answer/finish]
        │                            │ capture agent        │
        │                            ▼ (WS telemetry)      ▼
        │                    [api/telemetry ingest]   [DefenseStore (SQLite)]
        │                            │ SQLite               │ transcript + integrity signals
        │                            ▼                      │
        │                      [TraceStore] ────▶ [GradingEngine: digest (grading/features)
        │                            │                + rubric LLM (D-028)] ──▶ [GradeStore]
        │                            ▼                      ▼
        └──▶ Lab agent (live digest)          Assessor (grade output) / Proctor (integrity)
                                             Examiner agent (SSE) ◀── defense sessions
   variants: [api/variants] ◀── [VariantStore (seeded, D-029)] ── per-learner task statements
  • Lab consumes the live trace digest; Assessor consumes grading-engine output; Proctor consumes telemetry + defense integrity signals (REQ-3-007) — no mock fallback in the learner path (v0.2 corpus scenarios are dormant test-only fixtures).
  • The learner's path is: variant task → in-sandbox build (telemetry streams to SQLite) → grade My Work (rubric scores from the real trace) → oral defense → verdict.
  • Flooded/gapped traces are terminal: ingest closes 1008 and marks INCOMPLETE_FLOODED (G-3); the grader returns UNGRADABLE_TRACE_INCOMPLETE (G-4) — no credential from an incomplete trace.

v0.2 chat flow (complete, still live)

[packages/mock-data + packages/types]      [ai_service/corpus]
        │ (TS, web surfaces)                      │ (Python, agent inputs)
        ▼                                         ▼
[Next.js Route Groups]                    [ai-service agents]
  (learner)/ (marketplace)/                 coach tutor lab assessor proctor mentor
  (employer)/ (admin)/                                │
        │                                             ▼
        │      SSE (fetch + ReadableStream)     [LLMProvider]
        └────── client components ◄───────────────────┤
               http://localhost:8420          ollama-cloud / local / mock
                                               (https://ollama.com/v1)
  • Web surfaces remain server-component-first; client components (chat, filters, graph viewer, dark mode toggle) fetch directly from ai-service over SSE (A-002: no Next.js API-route proxy).
  • The LLM provider layer is a dumb pipe — OpenAI-compatible chunks pass through byte-identically; envelope logic (meta/done/error) lives only in the API layer (D-016).
  • The v0.2 corpus scenarios (ai_service/corpus/) are retained as dormant, test-only fixtures (dormant-header noted); they are no longer inputs to the live learner path.
  • All automated tests use the deterministic mock provider; the cloud is for manual probes only.

Build Order (v0.4)

  1. Bootstrap CLI core — apps/cli package: doctor checks (node/pnpm/python3/git/unshare), bootstrap wrapper (pnpm install + scripts/bootstrap.sh + .env template + key validation), verify health check, dev passthrough; unit tests
  2. Binary build + release pipeline — esbuild bundle → Node SEA binary (nextcraft-linux-x64) + sha256 sidecar; install.sh one-liner (Gitea latest-release resolve + checksum verify + PATH install); release-asset upload wired into the ship flow (ongoing binaries from v0.4 onward)
  3. Install docs + fresh-clone E2E — README quickstart (one-liner → doctor → bootstrap → dev), CLI reference, fresh-clone end-to-end test proving a clean clone reaches a running stack

Build Order (v0.3 — complete)

  1. Sandbox fabric — SandboxBackend protocol + unshare namespace spawner + lifecycle manager (create/list/snapshot/destroy) + concurrency guard + per-sandbox workdir; isolation + resource-limit probes
  2. Live build telemetry — TelemetryEvent models + SQLite TraceStore + WebSocket ingest endpoint + seq gap detection + in-sandbox capture agent
  3. Process-trace grading engine — deterministic feature/digest computation + rubric scoring via LLM structured output + GradeStore; calibrated against v0.2 mock corpora
  4. Variant task generation — template library + seeded LLM instantiation + VariantStore + difficulty normalization anchors
  5. Oral / voice defense — VoiceProvider protocol + STT/TTS + mock + browser fallback + Examiner agent + transcript/integrity-signal capture
  6. Agent re-grounding + learner surface integration — Lab/Assessor/Proctor consume real telemetry/grades/defense signals; learner sandbox mockup → real in-browser build/run (Run/Test buttons executing in a namespace sandbox, read-only exec-output panel — no interactive shell, CUT-2/G-8); assessment mockup → live defense + live grading

Build Order (v0.2 — complete)

  1. AI service scaffolding — apps/ai-service: FastAPI app, config, provider layer (ollama-cloud/local/mock), SSE chat endpoint, pytest harness, turbo integration
  2. Agent framework — BaseAgent, registry, session store, structured output, prompts scaffolding, learner-context corpus
  3. Coach + Tutor agents — full implementations, chat endpoint agent routing
  4. Lab + Assessor agents — telemetry scenarios + pre-baked artifacts corpus, /v1/lab/feedback + /v1/assessment/evaluate
  5. Proctor + Mentor agents — proctor scenarios, /v1/proctor/signals + /v1/mentor/narrative
  6. Learner surface integration — useChatStream hook, agent switcher, streaming/error/loading states, agent output panels across the four learner surfaces

The v0.1 build order (monorepo → types → mock data → tokens → primitives → layout → composites → surfaces → polish) is complete and preserved in git history (tags v0.0.1v0.1.0).


Future Architecture (Post-v0.4, for reference)

v0.4 delivers distribution (CLI + binary releases); later milestones fill in the remaining platform:

  • In-memory sessions → PostgreSQL + Drizzle/SQLModel — SessionStore + v0.3 TraceStore/GradeStore/VariantStore/DefenseStore protocols swap SQLite→Postgres with no API changes
  • userns subprocess sandboxes → containerd/runc backend — D-024 SandboxBackend protocol swap; same lifecycle API
  • Coding-IDE sandbox → design tool + simulation environments — REQ-F-021 full scope (v0.5)
  • Mock provider → per-agent model routing — provider factory already selects by config; per-agent AI_<AGENT>_MODEL overrides
  • No auth → real KYC + sessionsdeferred per founder directive; moved to v0.5 with D-016; REQ-F-017 identity/age-gating lands post-v0.4. Age-gating remains the v0.1 visual flow mockup
  • Mock voice → real server STT/TTS (openai-audio provider) — CUT-1/G-7 seam moved to v0.5 per D-016; VoiceProvider protocol is the drop-in point
  • linux x64 binary → macOS arm64 + auto-update — D-036 defers non-linux targets (unverifiable on this box); nextcraft upgrade (self-replace from latest release) is the natural v0.5+ follow-up
  • Exec-telemetry seq-lease / replay-margin fix — the P6-lesson one-line ACK gap moves to v0.5 per D-016
  • No search → Semantic vector search (pgvector) — Filter UI replaced with vector similarity search
  • No payments → Payment processing — Pricing page replaced with real subscription/payment flows

The monorepo structure (apps/web + apps/ai-service + apps/cli + packages/*) accommodates further apps without restructuring.