Commit graph

2 commits

Author SHA1 Message Date
Randall Stillwell
dab939bcd5 feat(mcp): agent-pipeline bridge — 6 lifecycle tools + convoy_events + L1/L3 scaffolding
Implements the Phase 2a Echodo bridge described in agent-pipeline's
v0.4 plan (.cursor/plans/pipeline_v0.4_design_+_echodo_54a3bdb7). Echodo
becomes the projection layer over the local .convoys/ tree; local files
remain source of truth per the local-first contract.

MCP lifecycle tools (apps/mcp-server/src/tools/):
- create-convoy.ts: registers create_convoy. Creates a Drizzle `project`
  object with status="draft" + appends initial "## Status log" to the
  description. Takes workspace_slug + slug + title + classification +
  skip_flags + success_metric + idea_markdown + repo.
- create-brief.ts: registers create_brief. Creates a `task` child of the
  convoy project. Takes convoyId + briefNumber + title + files_allowlist
  + depends_on + acceptance_criteria + brief_markdown.
- transition-convoy-status.ts: registers transition_convoy_status. Enforces
  the 9-status state machine from plan §7.3 with valid transitions +
  actor-permission gates. Appends an audit entry to the description's
  ## Status log per transition.
- log-convoy-event.ts: registers log_convoy_event. Inserts events into the
  new convoy_events table (one row per role hand-off, with classification,
  skip-flags, duration, stack-class, outcome, multitask-group metadata).
- query-manifest-status.ts: registers query_manifest_status (stub —
  depends on the Phase 4 pipeline_drift_reports table; documented).
- reconcile-from-files.ts: registers reconcile_from_files implementing the
  local-first recovery path. Reads .convoys/.pending-mcp-sync.jsonl from
  the given repoPath, replays queued log_convoy_event + transition_convoy_status
  calls, updates the outbox file on success/failure. Resolves the SPOF risk:
  failed MCP calls during offline windows reconcile when the bridge returns.

Database (packages/database/):
- src/schema/convoy_events.ts: new Drizzle schema. Columns: id, workspaceId,
  convoyId, convoySlug, role, brief, classification, skipFlags, durationS,
  stackClass, repo, outcome, multitaskGroup, metadata, ts. 4 indexes for
  per-workspace + per-convoy + role-filtered reads.
- src/schema/index.ts: re-exports the new table.
- migrations/0010_wandering_the_professor.sql + meta snapshot: generated
  via drizzle-kit generate. Pure-additive (CREATE TABLE + indexes + FKs).
- package.json: db:migrate / db:push / db:studio now use node --env-file
  to load ../../.env (consistent with the existing mcp-server tsx pattern).
  db:generate stays as-is (offline operation, no env needed).

L1 + L3 agent-pipeline scaffolding installed per
agent-pipeline/skills/bootstrap-agent-context v0.5.0:
- .agent-context-manifest.yml: tracks 17 artifacts at pipeline version
  0.5.0 with sha256 hashes. 4 artifacts flagged customized:true (no-go-zones,
  CODEOWNERS, pr-health-rollup.yml, echodo.config.json) — adapted from
  templates for Echodo's monorepo + Drizzle + Coolify + workspace_slug.
- .convoys/README.md: explains convoy file convention.
- .cursor/agents/echodo.config.json: workspace_slug=convoys-tasks (the
  workspace created in Echodo UI). Fallback policy: local-only.
- .cursor/rules/no-go-zones.mdc: adapted for Drizzle migrations, Coolify
  deploy infra, mcp-server boundaries.
- .github/CODEOWNERS: @rstillw as sole maintainer; targeted rules for
  apps/, packages/, auth, deploy infra, DB schema, MCP server, agent
  context.
- .github/PULL_REQUEST_TEMPLATE.md: pipeline PR template.
- .github/workflows/agent-context-drift.yml: drift monitor against upstream
  agent-pipeline.
- .github/workflows/pr-health-rollup.yml: adapted for tasks' pnpm monorepo
  + Coolify deploy (no per-PR preview by default).
- scripts/log-convoy-event.sh: convoy event logger shim.
- scripts/wt.sh: worktree helper stub (deprecated — points at Cursor 3.2
  native worktrees).
- .gitignore: excludes .convoys/.metrics.jsonl + .convoys/.pending-mcp-sync.jsonl
  (local agent analytics + MCP outbox).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 20:59:45 -05:00
Randall Stillwell
48defb2ffd test(ci): bootstrap vitest + GitHub Actions and lock in 3-gate quality bar
First Path-B task. Path A landed daily-driver features without a
test runner; Path B is "harden so the next batch of changes can't
silently regress what just shipped." Step 1 is making `pnpm test`
real and gating CI on it.

Test runner:
* Install vitest + @vitest/coverage-v8 at the workspace root.
* Add vitest.config.ts (environment: "node", no JSDOM) + test /
  test:watch scripts to packages/shared, packages/database,
  packages/ai. Wire `test` into turbo.json with dependsOn: ^build
  for future-proofing; add `pnpm test` to root package.json.

Three real tests (no snapshot theater — verified by mutation):
* packages/shared/src/utils/id.test.ts: asserts generateId() matches
  the RFC 4122 v4 regex and produces 1000 distinct values. Mutating
  generateId() to a constant fails both assertions.
* packages/shared/src/types/objects.test.ts: pins objectTypes and
  objectStatuses arrays. These back the zod enum on objects.create
  and the "open tasks" count on the workspace-home dashboard; a
  silent reorder/rename would otherwise corrupt the dashboard math.
* packages/database/src/markdown-backlog/parse.test.ts: covers
  parseBacklogMarkdown across three shapes (well-formed Task,
  no-frontmatter Plan with path inference, malformed YAML that
  must NOT throw — the importer runs in a file watcher). Plus
  hashFileContents determinism.
* packages/ai/src/actions/index.test.ts: five tests across the
  prompt builders (summarize/expand/rewrite × 3 tones / translate /
  generateFromPrompt). Pure functions; no model mocking needed.

CI:
* .github/workflows/ci.yml runs on pull_request and push to main.
  Node 20, pnpm 9 pinned explicitly (per AGENTS.md). Uses
  setup-node's built-in pnpm cache. Steps: install --frozen-lockfile,
  lint, type-check, test. Concurrency group cancels superseded runs
  on non-main branches.

Docs:
* AGENTS.md: drop the "no test runner configured" disclaimer.
  Document pnpm test / test:watch. Update the PR-readiness rule
  from `pnpm lint && pnpm type-check` to
  `pnpm lint && pnpm type-check && pnpm test`.

All 14 tests pass; lint + type-check still green across all 6
packages. The CI workflow's first run is gated on the operator
pushing this branch — that's the only acceptance criterion left
unverified in this commit.

Closes plans/Plan-multitenant-saas-hardening/Epic-test-foundation/
Task-bootstrap-vitest-and-ci.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 09:23:55 -05:00