feat(loop): Phase 1 Agent Hub lite durable system-of-record - #14
Merged
Merged
Conversation
Stand up the .loop/ durable substrate for the LabOS craft loop (Phase 1 of the loop operational plan). Local tooling only: no changes to src/, no third-party installs, no deploy. What this adds (all under .loop/): - schema.sql: DDL for work_items, stages, stage_transitions, item_events, decisions, guardrails, notes, budget. State machine encoded as data (stages + allowed stage_transitions); illegal transitions rejected at the CLI/db layer (moveItem throws, leaves state unchanged). - db.ts: shared DB layer over node:sqlite (built-in, zero installs, no native compile). Owns STAGES + ALLOWED_TRANSITIONS, moveItem/appendEvent, budget helpers. - seed.ts: the FIRST MISSION backlog (13 work_items: 7 microcopy + 1 glyph + 2 design-law + 3 frontend-mastery, all at backlog), 5 locked decisions, 7 guardrails (protect-list verbatim), budget (iter 150k, mission 2M, spent 0, paused false). protect_touch=1 on CRAFT-LAW-02 (Brain-adjacent). - hub.ts: thin CLI (init, seed, next, move, event, budget, status). - smoke.ts: model-free smoke test (pi-factory pattern; no model/API calls); 21 assertions, incl. illegal transition backlog->deployed REJECTED. - STATE.md + LOOP.md: human-readable kill switch + budget ledger + substrate doc. - tsconfig.json + package.json (type:module): isolate the tooling from the Next.js app build. Isolation: app tsconfig now excludes .loop/, so the **/*.ts glob no longer pulls the tooling into the Next.js typecheck/build. Verified: app tsc --noEmit clean, next build 9/9 pages, 0 .loop files in the app tsc set, loop:smoke green. The hub.sqlite DB is gitignored run-state; all other .loop/ artifacts are committed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
Phase 1 of the loop operational plan: stand up the
.loop/durable system-of-record (Agent Hub lite) for the LabOS craft loop. Local tooling only. No changes tosrc/, no third-party installs, no deploy. It only touches.loop/,package.json(scripts),.gitignore, and the apptsconfig.json(oneexcludeentry for isolation).Spec:
04-loop-operational-plan.mdSections 1.2 (schema), 1.3 (seed), 4 (kill switch), and the Phase 1 acceptance in Section 6. Locked decisions + protect-list seeded verbatim from.kernel/KERNEL.md.Schema (
.loop/schema.sql)Tables:
work_items · stages · stage_transitions · item_events · decisions · guardrails · notes · budget.The stage state machine is encoded as data:
stages(ordered, withterminalflags) +stage_transitions(the allowed edges). The transition set isbacklog → in_progress → built → verified → merged → deployedplusblocked/abandonedoff-ramps. Illegal transitions are rejected in the db/CLI layer (moveItem()checks the edge againstALLOWED_TRANSITIONS, throws on any edge not listed, and leaves state unchanged). Enforcing in the CLI layer (rather than a SQL trigger) keeps the rejection message useful and the loop's precheck exit codes clean.Seed (
.loop/seed.ts)stage=backlog—CRAFT-MICRO-01..07(microcopy; the known three are"mints"→"records","Explore freely"→"Explore the prototype", retire"co-pilot"; the remaining 4 left asTODO-enumerate (Phase 2)),CRAFT-GLYPH-01,CRAFT-LAW-01/02,CRAFT-FE-01/02/03.protect_touch=1onCRAFT-LAW-02(Brain-adjacent).locked=1): 5-cup architecture, biopharma-first, lead-with-reproducibility, REAL-vs-DEMO integrity boundary, loop-mission-v1.iter_token_cap=150000,mission_token_cap=2000000,tokens_spent_total=0,paused=false.The plan labels the mission "the 10-item FIRST MISSION" (Sections 4/6) and the Phase 1 acceptance says "asserts 10 work_items at backlog". But the enumerated backlog (Section 1.3.A + the dispatch instruction) is 7 microcopy + 1 glyph + 2 design-law + 3 frontend-mastery = 13 distinct items. These two can't both be literally true. I seeded all 13 named items (dropping any would violate the explicit "seed
CRAFT-*" instruction) and the smoke test asserts the true enumerated count of 13 plus the per-category breakdown (7/1/2/3). The substantive Phase 1 guarantee — every seeded item starts at backlog — holds either way. Please confirm 13 is the intended backlog size, or tell me which 3 to roll up to reach 10.SQLite library + isolation
node:sqlite(built-inDatabaseSync, stable since Node 24; repo runs Node 25.9). Chosen overbetter-sqlite3because it needs zero third-party installs and zero native compile (no node-gyp), satisfying the "no installs / minimal deps" constraint. Node 25 also runs the.loop/*.tsfiles directly via native type-stripping, so the tooling adds no dev dependencies at all.tsconfig.jsonincludeuses a**/*.tsglob that would otherwise pull.loop/*.tsinto the app typecheck/build. Fixed by adding.loopto the apptsconfig.jsonexclude. The tooling gets its own.loop/tsconfig.json(Node-targeted, ESM,node:sqlitetypes) and a.loop/package.jsonwith"type": "module"to scope ESM to.loop/only. Verified: 0.loopfiles in the apptscfile set (tsc --listFiles).Verification (all green)
tsc --noEmitnext buildnpm run loop:typechecknpm run loop:smoke(model-free)package.jsondescription, out of scope)hub.sqlite+-wal/-shmignored; not stagedSmoke assertions (no model/API calls; runs against a throwaway temp DB):
Files
Added:
.loop/schema.sql,.loop/db.ts,.loop/seed.ts,.loop/hub.ts,.loop/smoke.ts,.loop/STATE.md,.loop/LOOP.md,.loop/tsconfig.json,.loop/package.json.Changed:
package.json(loop:* scripts),tsconfig.json(exclude.loop),.gitignore(ignore the DB).Phase 2 hand-off
CRAFT-MICRO-04..07havedetail = "TODO-enumerate (Phase 2): ..."— the 4 un-enumerated microcopy strings need their exact source string +file:linefilled in by the Frontend Developer in Phase 2.Do not merge — for independent maker/checker review; the EM merges.
🤖 Generated with Claude Code