Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Dependencies and package manager noise
node_modules/

# Build outputs
dist/
*.tsbuildinfo

# SDP regenerable extraction output
specs/generated/
generated/

# Test / coverage
coverage/

# Env and local overrides
.env
.env.*
!.env.example

# Editor / OS
.DS_Store
*.swp
.idea/
.vscode/
323 changes: 323 additions & 0 deletions .grok/workflows/migrate-specs-to-sdp.rhai

Large diffs are not rendered by default.

138 changes: 138 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Local Docker helpers for Convex self-hosted backends used by integration tests.
# Ports:
# 3210 = app integration (order-management)
# 3215 = infrastructure integration (platform-*)
# 3220 = interactive development (docker-compose.dev.yml)

set shell := ["bash", "-eu", "-o", "pipefail", "-c"]

convex_image := "ghcr.io/get-convex/convex-backend:c34b8eca2d740de3cde3f6a3ab7d1dc9e98ee7d6"
instance_secret := env_var_or_default("CONVEX_INSTANCE_SECRET", "0135d8598650f8f5cb0f30c34ec2e2bb62793bc28717c8eb6fb577996d50be5f")

# Start app integration backend on port 3210
start:
#!/usr/bin/env bash
set -euo pipefail
name="convex-es-test-backend"
if docker ps --filter "name=^${name}$" --format '{{{{.Names}}' | grep -qx "$name"; then
echo "Backend already running: $name"
exit 0
fi
docker rm -f "$name" >/dev/null 2>&1 || true
docker run -d \
--name "$name" \
-p 3210:3210 \
-p 3211:3211 \
--shm-size=256m \
--tmpfs /convex/data:rw,size=512m,mode=1777 \
--tmpfs /tmp:rw,size=512m,mode=1777 \
-e INSTANCE_SECRET="{{instance_secret}}" \
-e IS_TEST=true \
-e CONVEX_CLOUD_ORIGIN=http://127.0.0.1:3210 \
-e CONVEX_SITE_ORIGIN=http://127.0.0.1:3211 \
"{{convex_image}}"
just _wait-healthy http://127.0.0.1:3210

# Start infrastructure integration backend on port 3215
start-infra:
#!/usr/bin/env bash
set -euo pipefail
name="convex-es-infra-backend"
if docker ps --filter "name=^${name}$" --format '{{{{.Names}}' | grep -qx "$name"; then
echo "Infra backend already running: $name"
exit 0
fi
docker rm -f "$name" >/dev/null 2>&1 || true
docker run -d \
--name "$name" \
-p 3215:3210 \
-p 3216:3211 \
--shm-size=256m \
--tmpfs /convex/data:rw,size=512m,mode=1777 \
--tmpfs /tmp:rw,size=512m,mode=1777 \
-e INSTANCE_SECRET="{{instance_secret}}" \
-e IS_TEST=true \
-e CONVEX_CLOUD_ORIGIN=http://127.0.0.1:3215 \
-e CONVEX_SITE_ORIGIN=http://127.0.0.1:3216 \
"{{convex_image}}"
just _wait-healthy http://127.0.0.1:3215

# Stop app integration backend
stop:
docker rm -f convex-es-test-backend >/dev/null 2>&1 || true

# Stop infrastructure backend
stop-infra:
docker rm -f convex-es-infra-backend >/dev/null 2>&1 || true

# Restart app integration backend with fresh tmpfs state
restart: stop start

# Deploy order-management functions to the app integration backend
deploy-local:
#!/usr/bin/env bash
set -euo pipefail
admin_key="$(docker exec convex-es-test-backend /convex/generate_admin_key.sh | awk '/^convex-self-hosted\|/{print; exit} /^Admin key:/{getline; print; exit}')"
if [[ -z "$admin_key" ]]; then
admin_key="$(docker exec convex-es-test-backend /convex/generate_admin_key.sh | tr -d '\r' | awk 'NF{line=$0} END{print line}')"
fi
cd examples/order-management
CONVEX_DEPLOYMENT= \
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3210 \
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
pnpm exec convex deploy -y --url http://127.0.0.1:3210 --admin-key "$admin_key"
# Container env is not visible to Convex app code; set deployment env explicitly.
CONVEX_DEPLOYMENT= \
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3210 \
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
pnpm exec convex env set IS_TEST true --url http://127.0.0.1:3210 --admin-key "$admin_key"

# Deploy order-management functions to the infrastructure backend
deploy-infra:
#!/usr/bin/env bash
set -euo pipefail
admin_key="$(docker exec convex-es-infra-backend /convex/generate_admin_key.sh | awk '/^convex-self-hosted\|/{print; exit} /^Admin key:/{getline; print; exit}')"
if [[ -z "$admin_key" ]]; then
admin_key="$(docker exec convex-es-infra-backend /convex/generate_admin_key.sh | tr -d '\r' | awk 'NF{line=$0} END{print line}')"
fi
cd examples/order-management
CONVEX_DEPLOYMENT= \
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3215 \
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
pnpm exec convex deploy -y --url http://127.0.0.1:3215 --admin-key "$admin_key"
CONVEX_DEPLOYMENT= \
CONVEX_SELF_HOSTED_URL=http://127.0.0.1:3215 \
CONVEX_SELF_HOSTED_ADMIN_KEY="$admin_key" \
pnpm exec convex env set IS_TEST true --url http://127.0.0.1:3215 --admin-key "$admin_key"

# Full app integration cycle
test-integration: start deploy-local
pnpm --filter order-management test:integration:ci

# Full infrastructure integration cycle (port 3215)
test-infrastructure-isolated: start-infra deploy-infra
CONVEX_URL=http://127.0.0.1:3215 pnpm --filter @libar-dev/platform-core test:integration:ci
CONVEX_URL=http://127.0.0.1:3215 pnpm --filter @libar-dev/platform-store test:integration:ci
CONVEX_URL=http://127.0.0.1:3215 pnpm --filter @libar-dev/platform-bus test:integration:ci

# Start docker-compose.dev.yml (interactive development)
dev-start:
docker compose -f docker/docker-compose.dev.yml up -d

dev-stop:
docker compose -f docker/docker-compose.dev.yml down

_wait-healthy url:
#!/usr/bin/env bash
set -euo pipefail
url="{{url}}"
echo "Waiting for backend at $url ..."
for i in $(seq 1 60); do
if curl -sf "$url" >/dev/null 2>&1 || curl -sf "$url/version" >/dev/null 2>&1; then
echo "Backend healthy: $url"
exit 0
fi
sleep 1
done
echo "Backend failed to become healthy: $url" >&2
exit 1
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,37 @@ This directory contains the platform workspaces that power the Convex event sour
- `packages/` contains the reusable platform packages.
- `examples/order-management/` contains the reference bounded contexts and app wiring.
- `apps/frontend/` contains the frontend, stories, and browser tests.
- `architect/` contains roadmap specs, decisions, generators, and validation inputs.
- `docs-living/` contains generated projections of the architect sources.
- `specs/` is the designated **Libar Software Delivery Protocol (SDP)** corpus root — Specs, Packs, and identity bindings (`*.sdp.md`, `*.pack.sdp.md`, `sdp-bindings.ts`). Executable test scenarios live under `specs/behavior/`; unimplemented backlog under `specs/unimplemented/`.
- `architect/` is a pointer only. The former architect Gherkin corpus was moved to `docs/lineage/architect/`.
- Cucumber `.feature` files under `packages/`, `examples/`, and `apps/` remain runtime tests (not SDP carriers).
- `docs-living/` retains archived generated projections from the retired architect workflow.

## Working rules

- Edit source specs, annotations, and package code.
- Do not hand-edit `docs-living/`.
- Use `pnpm docs:all` after docs or annotation changes.
- Use `pnpm test:coverage` for the package-level coverage gate.
- Author and mature delivery intent under `specs/` (SDP carriers).
- Bind implementation with SDP `codeAnchor` identity bindings (see `specs/platform/sdp-bindings.ts`), not `@architect` tags.
- Do not hand-edit `docs-living/` as a live workflow output.
- Use `pnpm test:packages` / package-level coverage gates for runtime quality.

## Key commands

| Command | Purpose |
| -------------------------------- | --------------------------------------------------------- |
| `pnpm test:packages` | Run the six platform package suites |
| `pnpm test:integration:platform` | Run isolated infrastructure integration tests |
| `pnpm test:coverage` | Enforce measured coverage floors across platform packages |
| `pnpm docs:all` | Refresh generated platform docs |
| Command | Purpose |
| ---------------------- | ---------------------------------------------------- |
| `pnpm test:packages` | Run the six platform package suites |
| `pnpm sdp:build` | Extract the SDP graph and contracts from `specs/` |
| `pnpm sdp:validate` | Run conformance + honesty checks over the one graph |
| `pnpm sdp:view` | Generate the Design Review projection |
| `pnpm sdp:q '…'` | Script the graph (`g` / `graph` / `report` bindings) |
| `pnpm check:sdp-migration` | Guard: no architect dep/scripts; corpus present |

```sh
pnpm sdp:build
pnpm sdp:validate
pnpm exec sdp q --root specs 'return { specs: g.specs().length, packs: g.packs().length, anchors: g.anchors().length }'
```

## Read next

- `specs/README.md` for the corpus map
- `packages/platform-*/README.md` for package-specific usage
- `examples/order-management/README.md` for the reference application
- `../docs/README.md` for the hand-written docs index
4 changes: 0 additions & 4 deletions apps/frontend/convex/admin/intents.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/**
* @architect
* @architect-implements DurableEventsIntegration
* @architect-infra
*
* Intent Admin Functions - CRUD operations for commandIntents table.
*
* Provides dependencies for platform-core's recordIntent, recordCompletion,
Expand Down
4 changes: 0 additions & 4 deletions apps/frontend/convex/admin/poison.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/**
* @architect
* @architect-implements DurableEventsIntegration
* @architect-infra
*
* Poison Event Admin Functions - CRUD operations for poisonEvents table.
*
* Provides dependencies for platform-core's withPoisonEventHandling wrapper.
Expand Down
7 changes: 0 additions & 7 deletions apps/frontend/convex/admin/projections.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
/**
* Admin mutations for projection replay and rebuilding.
*
* @architect
* @architect-pattern EventReplayInfrastructure
* @architect-implements EventReplayInfrastructure
* @architect-status active
* @architect-event-sourcing
* @architect-projection
* @architect-infra
*
* All admin operations use internal mutations for security.
* No public API exposure for admin operations.
Expand Down
4 changes: 0 additions & 4 deletions apps/frontend/convex/admin/rebuildDemo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/**
* @architect
* @architect-implements DurableEventsIntegration
* @architect-projection
*
* Rebuild Demonstration - Projection rebuild from event stream.
*
* Demonstrates the key event sourcing benefit: projections can be
Expand Down
4 changes: 0 additions & 4 deletions apps/frontend/convex/commands/durableOrchestrator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/**
* @architect
* @architect-implements DurableEventsIntegration
* @architect-command
*
* Durable Command Orchestrator - Intent/Completion Bracketing Wrapper
*
* Wraps the standard CommandOrchestrator with durability features:
Expand Down
9 changes: 0 additions & 9 deletions apps/frontend/convex/contexts/agent/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/** @architect */

/**
* @architect-ddd @architect-core
* @architect-pattern AgentAsBoundedContext
* @architect-status roadmap
* @architect-phase 22
* @architect-depends-on IntegrationPatterns,ReactiveProjections
* @architect-brief docs/project-management/aggregate-less-pivot/pattern-briefs/08-agent-as-bc.md
*
* ## Agent as Bounded Context - AI-Driven Event Reactors
*
* Demonstrate AI agent as event reactor pattern with autonomous command emission.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
* - Returns `DCBStateUpdates<InventoryStateUpdate>` (updates per entity)
* - Enables atomic cross-entity invariant validation via executeWithDCB
*
* @architect
* @architect-pattern ExampleAppModernization
* @architect-status roadmap
* @architect-uses DynamicConsistencyBoundaries, ReservationPattern
*
* @since Phase 23 (Example App Modernization - Rule 1)
*/
Expand Down
9 changes: 0 additions & 9 deletions apps/frontend/convex/contexts/inventory/handlers/commands.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/**
* @architect
* @architect-pattern InventoryCommandHandlers
* @architect-status completed
* @architect-command
* @architect-arch-role command-handler
* @architect-arch-context inventory
* @architect-arch-layer application
* @architect-uses InventoryDeciders, InventoryRepository
*
* Inventory command handlers implementing the dual-write pattern.
*
* CRITICAL: Every handler follows this pattern:
Expand Down
9 changes: 0 additions & 9 deletions apps/frontend/convex/contexts/orders/handlers/commands.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/**
* @architect
* @architect-pattern OrderCommandHandlers
* @architect-status completed
* @architect-command
* @architect-arch-role command-handler
* @architect-arch-context orders
* @architect-arch-layer application
* @architect-uses OrderDeciders, OrderRepository
*
* Order command handlers implementing the dual-write pattern.
*
* CRITICAL: Every handler follows this pattern:
Expand Down
4 changes: 0 additions & 4 deletions apps/frontend/convex/dcb/retryExecution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
* command handlers. It shows the self-referential retry pattern where
* the retry mutation schedules itself for re-execution on OCC conflicts.
*
* @architect
* @architect-pattern DurableFunctionAdapters
* @architect-status active
* @architect-infra
*
* ## Pattern Overview
*
Expand Down
6 changes: 0 additions & 6 deletions apps/frontend/convex/eventStore/durableAppend.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
/**
* @architect
* @architect-pattern DurableAppendAction
* @architect-status completed
* @architect-implements DurableEventsIntegration
* @architect-infra
*
* Durable Append - Workpool-backed event append with retry.
*
* Provides the action handler for durableAppendEvent() from platform-core.
Expand Down
8 changes: 0 additions & 8 deletions apps/frontend/convex/infrastructure.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
/**
* @architect
* @architect-pattern OrderManagementInfrastructure
* @architect-status completed
* @architect-infra
* @architect-arch-role infrastructure
* @architect-arch-layer infrastructure
* @architect-uses Workpool, Workflow, EventStore, CommandBus
*
* Infrastructure setup for the order-management application.
*
* Initializes Workpool, Workflow, and other infrastructure components.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
/**
* @architect
* @architect-pattern OrderWithInventoryProjection
* @architect-status completed
* @architect-projection
* @architect-arch-role projection
* @architect-arch-layer application
* @architect-uses OrderCommandHandlers, InventoryCommandHandlers
*
* OrderWithInventoryStatus cross-context projection handlers (app-level).
*
* Combines order status with inventory reservation status for dashboard views.
Expand Down
3 changes: 0 additions & 3 deletions apps/frontend/convex/projections/evolve/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
* import { evolveOrderSummary } from "@convex/projections/evolve";
* ```
*
* @architect
* @architect-implements ReactiveProjections
* @architect-status completed
*/

// Order Summary evolve function
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
* 2. **Deterministic**: Same inputs always produce same outputs
* 3. **Total**: Handles ALL event types (unknown types return state unchanged)
*
* @architect
* @architect-implements ReactiveProjections
* @architect-status completed
*/

// Types for documentation purposes - the evolve function implements EvolveFunction pattern
Expand Down
9 changes: 0 additions & 9 deletions apps/frontend/convex/projections/orders/orderSummary.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/**
* @architect
* @architect-pattern OrderSummaryProjection
* @architect-status completed
* @architect-projection
* @architect-arch-role projection
* @architect-arch-context orders
* @architect-arch-layer application
* @architect-uses EventStore
*
* OrderSummary projection handlers (app-level).
*
* Updates the orderSummaries read model based on order events.
Expand Down
Loading