Skip to content

feat(loop): Phase 1 Agent Hub lite durable system-of-record - #14

Merged
build-with-dhiraj merged 1 commit into
mainfrom
feat/loop-agent-hub-lite
Jun 23, 2026
Merged

build-with-dhiraj merged 1 commit into
mainfrom
feat/loop-agent-hub-lite

Conversation

@build-with-dhiraj

Copy link
Copy Markdown
Owner

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 to src/, no third-party installs, no deploy. It only touches .loop/, package.json (scripts), .gitignore, and the app tsconfig.json (one exclude entry for isolation).

Spec: 04-loop-operational-plan.md Sections 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, with terminal flags) + stage_transitions (the allowed edges). The transition set is backlog → in_progress → built → verified → merged → deployed plus blocked/abandoned off-ramps. Illegal transitions are rejected in the db/CLI layer (moveItem() checks the edge against ALLOWED_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)

  • work_items: the FIRST MISSION craft backlog at stage=backlogCRAFT-MICRO-01..07 (microcopy; the known three are "mints"→"records", "Explore freely"→"Explore the prototype", retire "co-pilot"; the remaining 4 left as TODO-enumerate (Phase 2)), CRAFT-GLYPH-01, CRAFT-LAW-01/02, CRAFT-FE-01/02/03. protect_touch=1 on CRAFT-LAW-02 (Brain-adjacent).
  • decisions (5, locked=1): 5-cup architecture, biopharma-first, lead-with-reproducibility, REAL-vs-DEMO integrity boundary, loop-mission-v1.
  • guardrails (7, verbatim): GR-HERO, GR-BRAIN-SAFETY, GR-PRIMITIVES, GR-ACTIONBLUE, GR-MCCLEAN, GR-NO-EMDASH, GR-REAL-DEMO.
  • budget: iter_token_cap=150000, mission_token_cap=2000000, tokens_spent_total=0, paused=false.

⚠️ Flag for the EM: work_item count (10 vs 13)

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

  • Driver: node:sqlite (built-in DatabaseSync, stable since Node 24; repo runs Node 25.9). Chosen over better-sqlite3 because 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/*.ts files directly via native type-stripping, so the tooling adds no dev dependencies at all.
  • Isolation from the Next.js build: the app tsconfig.json include uses a **/*.ts glob that would otherwise pull .loop/*.ts into the app typecheck/build. Fixed by adding .loop to the app tsconfig.json exclude. The tooling gets its own .loop/tsconfig.json (Node-targeted, ESM, node:sqlite types) and a .loop/package.json with "type": "module" to scope ESM to .loop/ only. Verified: 0 .loop files in the app tsc file set (tsc --listFiles).

Verification (all green)

Check Result
app tsc --noEmit exit 0
next build exit 0, 9/9 static pages
npm run loop:typecheck exit 0
npm run loop:smoke (model-free) 21 passed, 0 failed
em-dashes in added lines zero (only em-dash in repo is the pre-existing package.json description, out of scope)
DB gitignored hub.sqlite + -wal/-shm ignored; not staged

Smoke assertions (no model/API calls; runs against a throwaway temp DB):

PASS  seed reports the enumerated 13 work_items
PASS  work_items table has 13 rows
PASS  all 13 work_items at stage=backlog
PASS  7 microcopy / 1 glyph / 2 design-law / 3 frontend-mastery items
PASS  CRAFT-LAW-02 flagged protect_touch=1 (Brain-adjacent)
PASS  7 guardrails present
PASS  guardrail ids match the protect-list verbatim
PASS  locked decisions present (>= 5) and every decision is locked = 1
PASS  budget iter=150000 / mission=2000000 / spent=0 / paused=false
PASS  isAllowedTransition(backlog, deployed) === false
PASS  move CRAFT-MICRO-01 backlog -> deployed THROWS (rejected)
PASS  rejected move left CRAFT-MICRO-01 at backlog
PASS  legal move backlog -> in_progress accepted + appended one item_event

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..07 have detail = "TODO-enumerate (Phase 2): ..." — the 4 un-enumerated microcopy strings need their exact source string + file:line filled in by the Frontend Developer in Phase 2.

Do not merge — for independent maker/checker review; the EM merges.

🤖 Generated with Claude Code

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>
@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
labos-prototype Ready Ready Preview, Comment Jun 23, 2026 5:35pm

@build-with-dhiraj
build-with-dhiraj merged commit 6b1184a into main Jun 23, 2026
3 checks passed
@build-with-dhiraj
build-with-dhiraj deleted the feat/loop-agent-hub-lite branch June 23, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant