JJijibora Docs
docs.jijibora.online
On this page (10 sections)

Developer Workflow

Scope: The day-to-day loop, expressed as operator/developer use cases: bring the stack up, build the workspace pieces, deploy data in order, run the suites, and produce evidence that what you changed actually works. SurrealQL hard-constraint detail lives with the data-plane documents — this guide links there rather than repeating it. Audience: operator + developer. Status: As of 2026-11-09. Sources (cited inline): the operating guide (environment, cloud-VM notes, BFF sections, mandates); the root workspace scripts; the runtime and engine package scripts; the full deploy script; the smoke and verification scripts.

1. Use case: bring the stack up

Actor: a developer with a fresh checkout. Goal: a healthy local platform — data store, both BFFs, and the console — ready for verification.

Precondition: the working directory is the repository root on the current branch; the deprecated separate worktree is not used (source: operating-guide working-directory rule).

PlatformData storeRuntime BFF (:3030)Engine BFF (:3031)Console (:10300)
Windows (PowerShell)http://127.0.0.1:8000, root/root, namespace and database per the operating guide, persistent file store (source: operating guide environment)cd apps/agent-bff && DEV_SKIP_AUTH=1 SURREAL_URL=http://127.0.0.1:8000 node src/index.jscd apps/truth-bff && NODE_ENV=development DEV_SKIP_AUTH=1 TRUTH_GRAPH_SKIP_TRANSIT_TRAIL=1 TRUTH_GRAPH_SKIP_VAULT_GUARD=1 PORT=3031 SURREAL_URL=http://127.0.0.1:8000 SURREAL_NS=africa SURREAL_DB=community_os node dist/index.jscd apps/sovereign-console && npm run dev
Linux VM (Cursor Cloud)Binary preinstalled; start with the persistent-file invocation belowSame command; boots even with no schema/messaging; the health endpoint reports degraded when messaging is absent — the HTTP API is fully upSame; dev calls use the dev_<user> bearer + a dev vault scope; graph mutations need the transit-trail skip flagSame; binds the local name only, so use the local-name address, not a numeric loopback
# Linux VM — data store (persistent file store)
surreal start --user root --pass root --bind 127.0.0.1:8000 rocksdb:/workspace/scratch/surreal-data
  • Messaging, cache, and identity providers are optional locally. Both BFFs tolerate their absence and degrade with warnings; authentication is bypassed with the dev skip flag (source: operating-guide cloud notes). Live data rides the messaging key-value store.
  • One-command start: node start-dev.js from the repository root spawns the engine, the runtime tier (slightly delayed, wired to the engine's address with a dev vault scope and enqueue execution mode), and the mobile web app. If the engine's built output is missing it tells you to build first (see Section 2). The cloud-VM notes document the same bring-up as start commands (source: cloud notes).
  • Dev-start script family: Windows and Linux each have their own script variants — per-tier starters for the agent, engine, data store, integrations, and mesh proxies, plus an all-in-one desktop variant and deploy/seed/test wrappers. There is no single "start-all" entrypoint; pick the starter for the tier you are touching (source: script inventory).
  • The edge API (:3040) is not started locally. It is a stateless edge tier (authentication, tenants, vault health) that needs a public data endpoint when deployed; a local loopback store is not reachable from the edge (source: tier split).

Ports at a glance: data store :8000, runtime BFF :3030, engine :3031, edge :3040, console :10300, messaging :4222, mobile web :8081, compliance mTLS gateway :8181 (source: operating guide; start script).

2. Use case: build the workspace pieces

Actor: the same developer, before starting the TypeScript tiers. Goal: every local library the engine and console import exists as built output.

Why this step exists: the engine and the console depend on local TypeScript libraries that must be compiled to their distribution folders before either tier runs (source: cloud notes).

# Build every workspace package
npm run build --workspaces

# Type-check the engine tier without emitting (CI-equivalent lint)
cd apps/truth-bff && npx tsc --noEmit

# Build the engine tier itself
cd apps/truth-bff && npm run build

# Start / watch the engine tier
cd apps/truth-bff && npm run start
cd apps/truth-bff && npm run dev

What to expect:

  • One shared UI library carries pre-existing type errors but still emits usable output — its build is guarded so the failure does not block the workspace build (source: cloud notes).
  • The engine resolves one identity client through the hoisted root node modules rather than its own direct dependency; it works as long as the root install ran (source: cloud notes).
  • Three previously broken setup issues are fixed — do not re-introduce workarounds: a corrected library path in the engine's package description, a corrected require path for a health kit in the engine entry point, and the console blank-page fix (a stray token removed from a workflow-designer page). The console fix means the landing and login screens now mount (source: cloud notes).
  • Repo-root workspace scripts also provide dev (all workspaces), test (all workspaces that define one), lint (all workspaces that define one), and Playwright end-to-end tests (source: root package scripts).

3. Use case: deploy schema, then seed configuration, then boot

Actor: an operator preparing a real environment or a full local demo. Goal: data shapes first, configuration second, services last — in that order, every time.

Step 1 — schema first. The full deploy the Windows world uses:

# PowerShell (Windows)
database\deploy.ps1

On the Linux VM the full deploy is PowerShell-only, so replicate the truth-graph deploy by hand: for each of the 23 truth-graph strata in order, import the file, then re-apply the same SQL over HTTP — imports can silently drop function bodies, so the HTTP re-apply is not optional (source: cloud notes; truth-graph deploy script).

Step 2 — seed the key-value configuration. Runtime services never read configuration files from disk; only the offline seeder does. It publishes the datasets into the messaging key-value store:

node scripts/seed-nats-kv-declarative.mjs

Targeted seeders publish the same way for single buckets (source: declarative-first mandate — runtime must never read lookup/template files from the filesystem).

Step 3 — validate the dataset contracts where a validator exists:

node scripts/validate-dispatch-openapi.mjs

Step 4 — boot the BFFs per Section 1 (or the one-command start). Graph functions are then available under the truth tier with explicit traversal directions (outgoing, incoming, or both) (source: operating-guide key functions).

Step 5 — smoke last (Section 5).

4. Use case: run the tests (what each suite proves)

Actor: a developer proving a change. Goal: pick the cheapest suite that proves the thing you touched.

SuiteCommandWhat it proves
Runtime tier — fullnode --test "tests/*.test.js" (from the agent tier directory)The whole HTTP and route surface, including the API-description parity contracts.
Runtime tier — quicknode --test tests/pipeline-engine.test.jsThe workflow/pipeline engine (168 of 171 in a prior run; the remainder need extra schema functions).
Runtime tier — vertical clusternode --test src/tests/materra-app.test.js src/tests/materra-composable-template-routes.test.js (13 files total in the cluster)The agriculture vertical end to end.
Runtime tier — capability clustersnode --test tests/lease-gap-c09-consume.test.js tests/service-access-gap-c09.test.js tests/service-subscription-billing.test.js (gap cluster); node --test tests/bi-routes.test.js tests/bi-analytics-routes.test.js (analytics); node --test tests/kutuma-mesh-routes.test.js tests/kutuma-webhook.test.js (notifications); the two jobs-platform suites (jobs)That each capability vertical still behaves after refactors.
Claims description covernode --test tests/claims-processing-openapi.test.jsAll 23 required paths exist in the published description — the contract cannot drift.
Entities description covernode --test tests/entity-lifelong-openapi.test.js38 paths plus the source-mirror check (every live route is documented).
Engine unit testsnpm test (from the engine directory; runs the vitest suite)~169 unit tests pass; ~78 integration tests need the full schema deployed and a free engine port — stop the dev server first or the run fails to bind.
Type checknpx tsc --noEmit (from the engine directory)CI-equivalent lint; no eslint is installed anywhere, so the type check plus workspace lint is the gate.
Workspace lintnpm run lint --workspaces --if-presentNo-op for most packages; the type check is the real gate.

Each row's command is verbatim from its package's script definitions or the operating-guide test notes (source: agent-tier scripts; engine scripts; cloud notes). When a suite's expected count is quoted from an older inventory, re-run it — counts age; the command does not.

5. Use case: produce live evidence (smokes and verifiers)

Actor: an operator who needs to show, not tell. Goal: a running service, a scripted pass, and a clean console — on a port that does not disturb the live stack.

  • Commerce proof: scripts\run-commerce-dev-smokes.ps1 -BffUrl http://127.0.0.1:3030 -RequireBff (source: operating-guide commerce deploy notes).
  • Agent proof: scripts\run-agent-dev-smokes.ps1 -BffUrl http://127.0.0.1:3030 (source: operating guide).
  • Health proof: scripts\run-afiyalink-health-dev-smokes.ps1 (source: operating guide).
  • Contract proof: node scripts/run-uoe-api-contracts.mjs --require-bff (source: root workspace scripts).
  • Dispatch proof: scripts\run-dispatch-openapi-smoke.ps1 wrapping the offline validator (source: dispatch smoke test).
  • Live verifiers (where they exist): e.g. the headless jobs-platform verification script proves 9 of 9 gates, the solver gateway 5 of 5, and the declarative workflow/prompt templates 3 of 3 and 4 of 4 respectively (source: operating-guide vertical verification suites).

Evidence habits that keep proof honest:

  • Temp ports for smokes, so a smoke run never fights the live :3030; the dev-start flow itself recycles stale listeners (source: operating-guide dev-start notes).
  • Readiness, not presence. A process listening is not a platform: check the readiness probe reports the database connected; when messaging is absent the health endpoint reports degraded but the HTTP API is up — that is the normal shape (source: cloud notes; ready probe).
  • Fix the run, not the test. A smoke script that asserts invented numbers is a fake test — flag it and rewrite it against a real engine; never code to satisfy a smoke-screen test (source: ban-on-fake-tests mandate).

6. Conventions the loop depends on

  • Fail closed. Infrastructure failures return an error or refusal — never a synthetic success (source: fail-closed mandate).
  • Zero synthetic payloads. No invented coordinates, suppliers, organization ids, or generated lists to satisfy a downstream contract; contract mismatches return a client error (source: synthetic-payloads mandate).
  • Declarative first. Lookups, templates, scenarios, and thresholds live in the messaging key-value store or in workflow-engine / protocol-gateway YAML; runtime file reads of datasets are forbidden outside the seeder (source: declarative-first mandates).
  • No bespoke stores. Entities map into the canonical primitives; anything unmappable stops for review (source: zero-bespoke-tables mandate).
  • No hardcoded card values. Dashboards render live data or an honest empty state (source: no-hardcoded-metrics mandate).
  • TypeScript for new code; plain JavaScript only where declaration is genuinely impractical (source: operating-guide key decisions).
  • Events over polling. Background work flows through durable outbox records; sweep endpoints are dev recovery only (source: operating-guide key decisions).
  • No vendor names in public descriptions (see the spec index) (source: product map; cover tests).

7. Minimal bring-up checklist (respects the deploy order)

  1. Build the workspace pieces (Section 2) — before the engine or console.
  2. Start the data store for your platform (Section 1); confirm readiness.
  3. Deploy schema (Section 3, Step 1).
  4. Seed the key-value store (Section 3, Step 2).
  5. Boot the BFFs (Section 1) or the one-command start.
  6. Cheapest proof first: the description-cover tests (Section 4), then the temp-port smokes (Section 5), then the engine type check and unit tests.
  7. Confirm the health and readiness endpoints; accept "degraded" health when messaging is intentionally absent.

8. Common failure digests (pointers, not detail)

Full tables live with the data-plane and transport documents; the symptoms below are what to grep for in review.

  • Over-fetch then filter in JavaScript — push the predicate into the query instead (the messaging relay fixed exactly this class of bug by moving its subject filter into the query) (source: relay fix).
  • Bare literals for string arguments — identifier-like strings must be emitted quoted, never as bare record literals (source: route-side safe-emission helpers).
  • Temporal-function arithmetic — subtract durations, not integers; always cast timestamps to text explicitly (source: hard-constraint table).
  • Import silently dropped functions — re-apply the same SQL over HTTP after import (source: cloud notes).
  • Engine port clash — stop the dev server before running the integration tests; the run fails to bind otherwise (source: cloud notes).
  • Runtime file reads — no service may read dataset/template files from disk; only the offline seeder may (source: declarative-first mandate).

9. Working-directory and tooling rules

  • Repository root, current branch. All changes land in the root; the deprecated separate worktree receives nothing (source: working-directory rule).
  • Dedicated tools over shell; parallelize independent calls; file edits go through the edit tool (source: harness communication rules).