spec + ADR annotations + dormant-code cleanup
- .sf/REQUIREMENTS.md: today's R-entries (R066..R090) covering parallel-rescue targets — bus deliver verify, drift detection gate, PDD typed contracts, lane split, Wiggums detector family, repo supervisor design. - ADR-014/019/020: SF-first banners (operator direction: get SF working before ACE/wire-architecture changes land downstream). - docs/records + drafts: 2026-05-07 strategy + cli-agent survey index refresh; SF/ACE pattern draft annotations. - roadmap-mutations.js removed (dormant — never imported; reachable shape verified against handler-relative + dynamic import audit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d2ff4e84ba
commit
e93d17a3b4
10 changed files with 68 additions and 136 deletions
|
|
@ -942,3 +942,47 @@ ADR-0000 declares SF a **purpose-to-software compiler**. R036–R040 codify that
|
|||
- Supporting slices: M039/S07, M048/S05
|
||||
- Validation: unmapped
|
||||
- Notes: Operator's codex tool stays available unchanged — R075 is the SF-internal capability that runs without operator. Model-router exclusion rule: skip worker model + same vendor family. Self-feedback shape: `kind='adversarial-finding'`, severity from review verdict, occurredIn anchors review target. R066 firewall consumes high-severity findings as a quarantine signal. Budget governance: per-cycle token cap (e.g. 5% of unit token budget) + per-week cap (e.g. 100 reviews) configurable via preferences. System-lane task (R057) so reviews run concurrent with unit execution rather than serial. Sibling to R053 (repeated self-feedback kind detector) — when same finding kind recurs N times, escalates to operator notification.
|
||||
|
||||
### R087 — Typed PDD Contracts via engine-types.js
|
||||
- Class: capability
|
||||
- Status: active
|
||||
- Description: Per ADR-0000, the 8 PDD fields (Purpose, Consumer, Contract, FailureBoundary, Evidence, NonGoals, Invariants, Assumptions) and the 7-dimension RunControlPolicy (confidence, risk, reversibility, blastRadius, cost, legal, customerImpact) become TypeScript interfaces in engine-types.js (currently empty stub: export {};). Per ADR-0075, GateResult shape is also exported from engine-types.js. All engine/policy/validator/planner code imports these typed contracts as the canonical leaf-node — turns ADR-0000 prose into compile-time contracts. plan-milestone/plan-slice/plan-task tool handlers validate input against PDDFields; UokGateRunner consumes GateResult; routing policy reads RunControlPolicy.
|
||||
- Why it matters: ADR-0000 specifies the 8 PDD fields + run-control policy but they exist only in prose. Codex doctrine review 2026-05-17: "PDD eight-field gate not enforced by plan-milestone or plan-slice." R036-R040 (M030) cover data-level anchoring; R087 adds the typed schema fix at the code level. Pairs with R086 (dormant code triage) since engine-types.js IS one of the dormant files M058 wires in.
|
||||
- Source: codex-doctrine-review-2026-05-17 + supervisor-deep-audit-2026-05-17
|
||||
- Primary owning slice: M058/S05
|
||||
- Supporting slices: M030/S01
|
||||
- Validation: unmapped
|
||||
- Notes: engine-types.js header explicitly says "All engine/policy interfaces depend on these types." File is purpose-built for this content; stub never filled. M030 R036 purposeAnchor data-level enforcement gets stronger when backed by typed PDDFields. Compile-time at import boundary; runtime at tool input boundary.
|
||||
|
||||
### R088 — Pre-Removal Test-Import Safety Gate
|
||||
- Class: capability
|
||||
- Status: active
|
||||
- Description: UokGate per ADR-0075 (type=policy, id=removal-safety) that fires BEFORE any file removal proposed by the autonomous loop or triggered by R086 dormant-code triage. Greps tests/* for static + dynamic-import references; scans file content for external-integration env-var signatures (TWILIO_, ELEVENLABS_, STRIPE_, DISCORD_, SENDGRID_, etc.). Returns outcome=manual-attention with cited test paths or env-var matches when found.
|
||||
- Why it matters: Operator-supervisor 2026-05-17 removed web/app/api/voice/ that turned out to be Twilio IVR on-call infrastructure with src/tests/integration/web-voice-ivr-contract.test.ts as paired contract test. R086 dormant-code-triage catches after removal; R088 prevents BEFORE. Without R088, autonomous removal repeats the same operator mistake at scale.
|
||||
- Source: operator-supervisor-mistake-recovered-2026-05-17
|
||||
- Primary owning slice: M058/S12
|
||||
- Supporting slices: M048/S05
|
||||
- Validation: unmapped
|
||||
- Notes: Sibling to R082 (drift detector UokGate). M048/S05 (smoke-fixture + last-green ledger) catches destructive autonomous changes in general; R088 specifically guards removal-safety.
|
||||
|
||||
### R089 — Migrate Voice IVR On-Call Infra to Central Cloud Ops
|
||||
- Class: capability
|
||||
- Status: active
|
||||
- Description: Migrate web/app/api/voice/ + voice/prompt/ routes + src/tests/integration/web-voice-ivr-contract.test.ts (Twilio IVR + ElevenLabs voice synthesis + on-call paging) out of SF to central cloud-ops repo/service. SF is per-project autonomous compiler (ADR-0000); operator-paging infra is org-level. Migrate first, verify cloud-ops endpoint, then remove from SF (gated by R088 pre-removal safety gate).
|
||||
- Why it matters: Current placement in SF is historical drift. Voice infrastructure does not belong in a per-project compiler codebase. Migration to the right home + removal from SF is the correct fix.
|
||||
- Source: operator-direction-2026-05-17
|
||||
- Primary owning slice: M058/S13
|
||||
- Supporting slices: M058/S14
|
||||
- Validation: unmapped
|
||||
- Notes: Files: web/app/api/voice/route.ts, web/app/api/voice/prompt/route.ts, src/tests/integration/web-voice-ivr-contract.test.ts, related env-var docs (TWILIO_, ELEVENLABS_). Removal from SF gated by R089/S13 (migration done) AND R088 (pre-removal safety gate green).
|
||||
|
||||
### R090 — Planning-Execute Lane Split
|
||||
- Class: capability
|
||||
- Status: active
|
||||
- Description: Two concurrent lanes in the autonomous dispatcher: PLANNING (discuss/plan/research/reassess for ANY milestone, writes only to .sf/+DB, file-conflict-free) and EXECUTE (execute-task + complete-*, exclusive worktree, N=1). Planning queue stays ahead so execute never waits on plan gating. Subset of R046 (full multi-unit lanes via M033); much smaller blast radius, ships much earlier.
|
||||
- Why it matters: Today execute waits ~10-20 min for next plan-slice to finish before starting next execute. Splitting lanes ~2x throughput on planning-heavy slices. Safer than R046 full parallel; only planning runs concurrent with execute, never two executes.
|
||||
- Source: operator-direction-2026-05-17
|
||||
- Primary owning slice: M059/S01
|
||||
- Supporting slices: M059/S02, M059/S03
|
||||
- Validation: unmapped
|
||||
- Notes: Planning writes bounded to .sf/{sf.db, runtime/, milestones/}; never source. Permission-profile enforces. R082 drift detector watches the boundary. M033/R046 eventually generalizes; R090 is the safe near-term cut.
|
||||
|
|
|
|||
|
|
@ -276,4 +276,4 @@ If a task cannot be described this way, it is underspecified.
|
|||
- GitHub Spec Kit — spec-first authoring patterns.
|
||||
- Ousterhout, *A Philosophy of Software Design* — deep modules, contract pattern.
|
||||
- Trail of Bits — anti-rationalisation rules.
|
||||
- ACE — original Iron Law / Purpose Gate framing this doc adapts.
|
||||
- Iron Law / Purpose Gate framing — concept adapted from external prior art (originally an ACE concept; preserved here as SF doctrine independent of ACE runtime).
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# ADR-014: Singularity Knowledge + Agent Platform stack
|
||||
|
||||
**Date**: 2026-04-29
|
||||
**Status:** proposed (deferred; Phase 4 cancelled per ADR-019). No active implementation work; future federation work uses Singularity Memory primitive per ADR-012.
|
||||
**Status:** proposed (deferred; Phase 4 cancelled per ADR-019). No active implementation work; future federation work uses Singularity Memory primitive per ADR-012; SF-first amendment 2026-05-17 — see R084
|
||||
**Revised**: 2026-05-02 — Phase 4 cancelled, see [ADR-019](./ADR-019-workspace-vm-convergence.md)
|
||||
|
||||
## Context
|
||||
|
|
@ -104,6 +104,8 @@ Phase 4 was originally planned as a "central persistent-agent runtime" built on
|
|||
|
||||
**What replaced it:** Persistent agents now live as **Firecracker VM snapshots managed by ACE**'s orchestration layer. A "persistent agent" is a named VM snapshot: restore it, and the agent wakes with its full memory and context intact. singularity-memory's scope is now strictly the knowledge layer (Phases 0–3). See ADR-019 § "ADR-014 Phase 4 is reassigned" for the authoritative statement.
|
||||
|
||||
> **2026-05-17 amendment — SF-first.** ACE is not currently operational; SF runs standalone. The Phase 4 reassignment to ACE's Firecracker VMs is suspended. Persistent-agent capability (code-reviewer, memory-curator, security-auditor, build-watch) re-homes in SF per R084 (Persistent Agent Runtime in SF). When ACE becomes operational, the original reassignment can be revisited.
|
||||
|
||||
### Historical: Original Phase 4 Plan
|
||||
|
||||
> *The content below is the original Phase 4 design, preserved as a historical record. It is **not** the current plan.*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# ADR-019: Workspace VM Convergence Architecture
|
||||
|
||||
**Status:** Proposed
|
||||
> **2026-05-17 reframe — SF-first.** ACE exists as a peer project but is not currently operational. SF must work standalone. The convergence described here is forward-looking; SF's near-term roadmap does NOT depend on ACE being available. Phase 4 persistent-agent reassignment to ACE (originally written here) is suspended — persistent-agent capability is re-homed in SF per R084 (Persistent Agent Runtime in SF). When ACE becomes operational, this ADR's convergence path can be reactivated.
|
||||
|
||||
**Status:** Proposed — convergence forward-looking; SF-first per 2026-05-17 banner
|
||||
**Date:** 2026-05-01
|
||||
**Revised:** 2026-05-02 — wire-format scope superseded by ADR-020
|
||||
**Deciders:** Mikael Hugo
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
## Context
|
||||
|
||||
> **2026-05-17 note — SF-first.** ACE is not currently operational. The wire-format table rows that touch ACE (ACE host → ACE tools, ACE host → singularity-memory, SF → ACE worker, ACE worker VM → host, Claude Code → ACE) describe the forward-looking architecture and are not active. SF's current internal wire is @singularity-forge/rpc-client (stdio JSON-RPC) for SF↔SF child processes; first-party SF→singularity-memory remains gRPC when wired. ACE rows reactivate when ACE becomes operational.
|
||||
|
||||
The first-party services that make up the singularity stack — SF
|
||||
(`singularity-forge`), ACE (`ace-coder`), `singularity-memory`, and the
|
||||
future `singularity-*` services — need a wire format for talking to each
|
||||
|
|
@ -89,15 +91,15 @@ other services — it does not expose a gRPC API of its own.
|
|||
|
||||
This is the canonical reference for which wire goes where.
|
||||
|
||||
| Caller | Callee | Wire | Why |
|
||||
|--------|--------|------|-----|
|
||||
| ACE host → ACE tools | in-process Python imports | function call | type-safe, zero overhead |
|
||||
| ACE host → singularity-memory | typed Python client (gen from Go API) | HTTP/gRPC | typed, fast, refactorable |
|
||||
| SF → singularity-memory | typed TS client (gen from Go API) | HTTP/gRPC | same, in TS |
|
||||
| SF → ACE worker | existing JSON-RPC stdio (`rpc-client`) | stdio JSON-RPC | already in production, language-agnostic |
|
||||
| ACE worker VM → host | direct gRPC over tailnet | gRPC | typed, low-latency |
|
||||
| Claude Code / Cursor → singularity-memory | MCP façade | MCP | external tool, no shared types |
|
||||
| Claude Code → ACE | MCP façade (temporary) | MCP | external coder helping build, until self-hosting |
|
||||
| Caller | Callee | Wire | Why | Status |
|
||||
|--------|--------|------|-----|--------|
|
||||
| ACE host → ACE tools | in-process Python imports | function call | type-safe, zero overhead | Future (ACE not operational) |
|
||||
| ACE host → singularity-memory | typed Python client (gen from Go API) | HTTP/gRPC | typed, fast, refactorable | Future (ACE not operational) |
|
||||
| SF → singularity-memory | typed TS client (gen from Go API) | HTTP/gRPC | same, in TS | Active |
|
||||
| SF → ACE worker | existing JSON-RPC stdio (`rpc-client`) | stdio JSON-RPC | already in production, language-agnostic | Future (ACE not operational) |
|
||||
| ACE worker VM → host | direct gRPC over tailnet | gRPC | typed, low-latency | Future (ACE not operational) |
|
||||
| Claude Code / Cursor → singularity-memory | MCP façade | MCP | external tool, no shared types | Active |
|
||||
| Claude Code → ACE | MCP façade (temporary) | MCP | external coder helping build, until self-hosting | Future (ACE not operational) |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SF → ACE Coder Pattern Reference
|
||||
|
||||
**Status:** Draft — no active consumer. Parked here for when ACE Coder maintainers pull on convergence; SF's own priorities take precedence until then.
|
||||
**Status:** Draft — no active consumer. Parked here for when ACE Coder maintainers pull on convergence; SF's own priorities take precedence until then. SF-first reaffirmed 2026-05-17 (ACE not currently operational).
|
||||
|
||||
**Purpose:** Document six proven SF patterns that ACE Coder can adopt to stay conceptually compatible without collapsing the Forge/ACE split. Each pattern includes its SF implementation, the value it protects, and a concrete adoption path for ACE.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# SF + ACE Full-Stack Reference Survey — 2026-05-07
|
||||
|
||||
> **Historical record — annotated 2026-05-17.** This survey assumed ACE was operational at the time of writing. Per 2026-05-17 operator decision, SF runs standalone; ACE is not currently operational. Survey content is preserved as historical context; do not treat its ACE references as current architecture.
|
||||
|
||||
This record compares local coding-agent, orchestration, retrieval, model, and
|
||||
platform-engineering references under `/home/mhugo/code/` plus selected indexed
|
||||
public references against the intended SF+ACE full-stack flow. It is planning
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# Strategy Alignment — 2026-05-07
|
||||
|
||||
> **Historical record — annotated 2026-05-17.** This survey assumed ACE was operational at the time of writing. Per 2026-05-17 operator decision, SF runs standalone; ACE is not currently operational. Survey content is preserved as historical context; do not treat its ACE references as current architecture.
|
||||
|
||||
Aligned the top-level SF docs and roadmap framing around the current architecture and end goal.
|
||||
|
||||
## Canonical direction
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ Repo-memory audits, decision ledgers, context-gardening notes, and records-keepe
|
|||
| Date | Note | Summary |
|
||||
|------|------|---------|
|
||||
| 2026-05-01 | [repo-vcs and notifications](./2026-05-01-repo-vcs-and-notifications.md) | repo-vcs skill landed; notification specs drafted; JSDoc annotations added; placeholder docs filled |
|
||||
| 2026-05-07 | [SF + ACE full-stack reference survey](./2026-05-07-cli-agent-code-survey.md) | repo-wise map of coding agents, spec systems, orchestration systems, retrieval tools, model references, and platform/golden-path systems; priority pulls are execution permissions, typed machine events, DB-first state, generated human exports, trust gating, orchestration, cumulative diffs, eval pipelines, and MCP-client-only lifecycle hardening |
|
||||
| 2026-05-07 | [SF + ACE full-stack reference survey](./2026-05-07-cli-agent-code-survey.md) | repo-wise map of coding agents, spec systems, orchestration systems, retrieval tools, model references, and platform/golden-path systems; priority pulls are execution permissions, typed machine events, DB-first state, generated human exports, trust gating, orchestration, cumulative diffs, eval pipelines, and MCP-client-only lifecycle hardening (historical; ACE not operational, SF-first per 2026-05-17) |
|
||||
| 2026-05-07 | [strategy alignment](./2026-05-07-strategy-alignment.md) | aligned top-level docs and roadmap framing around Forge as product, UOK as kernel, and external CLIs as sharpening inputs |
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
/**
|
||||
* Roadmap Mutations — shared utilities for modifying roadmap checkbox state.
|
||||
*
|
||||
* Extracts the duplicated "flip slice checkbox" pattern that existed in
|
||||
* doctor.ts, mechanical-completion.ts, and auto-recovery.ts.
|
||||
*/
|
||||
import { readFileSync } from "node:fs";
|
||||
import { atomicWriteSync } from "./atomic-write.js";
|
||||
import { clearParseCache } from "./files.js";
|
||||
import { resolveMilestoneFile } from "./paths.js";
|
||||
/**
|
||||
* Mark a slice as done ([x]) in the milestone roadmap.
|
||||
* Idempotent — no-op if already checked or if the slice isn't found.
|
||||
*
|
||||
* @returns true if the roadmap was modified, false if no change was needed
|
||||
*/
|
||||
export function markSliceDoneInRoadmap(basePath, mid, sid) {
|
||||
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
||||
if (!roadmapFile) return false;
|
||||
let content;
|
||||
try {
|
||||
content = readFileSync(roadmapFile, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
// Try checkbox format first: "- [ ] **S01: Title**"
|
||||
let updated = content.replace(
|
||||
new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${sid}:`, "m"),
|
||||
`$1[x] **${sid}:`,
|
||||
);
|
||||
// If checkbox format didn't match, try prose format: "## S01: Title" -> "## S01: \u2713 Title"
|
||||
if (updated === content) {
|
||||
updated = content.replace(
|
||||
new RegExp(
|
||||
`^(#{1,4}\\s+(?:\\*{0,2})(?:Slice\\s+)?${sid}\\*{0,2}[:\\s.\\u2014\\u2013-]+\\s*)(.+)`,
|
||||
"m",
|
||||
),
|
||||
(match, prefix, title) => {
|
||||
// Already marked done — no-op
|
||||
if (
|
||||
/^[\u2713\u2705]/.test(title) ||
|
||||
/[\u2705]\s*$/.test(title) ||
|
||||
/\(Complete\)\s*$/i.test(title)
|
||||
)
|
||||
return match;
|
||||
return `${prefix}\u2713 ${title}`;
|
||||
},
|
||||
);
|
||||
}
|
||||
if (updated === content) return false;
|
||||
atomicWriteSync(roadmapFile, updated);
|
||||
clearParseCache();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Mark a slice as not done ([ ]) in the milestone roadmap.
|
||||
* Idempotent — no-op if already unchecked or if the slice isn't found.
|
||||
*
|
||||
* @returns true if the roadmap was modified, false if no change was needed
|
||||
*/
|
||||
export function markSliceUndoneInRoadmap(basePath, mid, sid) {
|
||||
const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
|
||||
if (!roadmapFile) return false;
|
||||
let content;
|
||||
try {
|
||||
content = readFileSync(roadmapFile, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const updated = content.replace(
|
||||
new RegExp(`^(\\s*-\\s+)\\[x\\]\\s+\\*\\*${sid}:`, "m"),
|
||||
`$1[ ] **${sid}:`,
|
||||
);
|
||||
if (updated === content) return false;
|
||||
atomicWriteSync(roadmapFile, updated);
|
||||
clearParseCache();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Mark a task as done ([x]) in the slice plan.
|
||||
* Idempotent — no-op if already checked or if the task isn't found.
|
||||
*
|
||||
* @returns true if the plan was modified, false if no change was needed
|
||||
*/
|
||||
export function markTaskDoneInPlan(_basePath, planPath, tid) {
|
||||
let content;
|
||||
try {
|
||||
content = readFileSync(planPath, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const updated = content.replace(
|
||||
new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${tid}:`, "m"),
|
||||
`$1[x] **${tid}:`,
|
||||
);
|
||||
if (updated === content) return false;
|
||||
atomicWriteSync(planPath, updated);
|
||||
clearParseCache();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Mark a task as not done ([ ]) in the slice plan.
|
||||
* Idempotent — no-op if already unchecked or if the task isn't found.
|
||||
*
|
||||
* @returns true if the plan was modified, false if no change was needed
|
||||
*/
|
||||
export function markTaskUndoneInPlan(_basePath, planPath, tid) {
|
||||
let content;
|
||||
try {
|
||||
content = readFileSync(planPath, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const updated = content.replace(
|
||||
new RegExp(`^(\\s*-\\s+)\\[x\\]\\s+\\*\\*${tid}:`, "mi"),
|
||||
`$1[ ] **${tid}:`,
|
||||
);
|
||||
if (updated === content) return false;
|
||||
atomicWriteSync(planPath, updated);
|
||||
clearParseCache();
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue