diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..34dc2415 --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/.grok/workflows/migrate-specs-to-sdp.rhai b/.grok/workflows/migrate-specs-to-sdp.rhai new file mode 100644 index 00000000..af196c9a --- /dev/null +++ b/.grok/workflows/migrate-specs-to-sdp.rhai @@ -0,0 +1,323 @@ +let meta = #{ + name: "migrate-specs-to-sdp", + description: "Upgrade the specs/ corpus from mechanical SDP carriers to lawful Libar Software Delivery Protocol authoring", + when_to_use: "When libar-platform Specs need verifies, example spaces, decision bodies, or honest readiness against SDP law", + phases: [ + #{ title: "Mechanical", detail: "add verifies, rewrite stub outcomes, fill decision bodies from lineage" }, + #{ title: "Discover", detail: "group remaining protocol gaps into non-overlapping shards" }, + #{ title: "Migrate", detail: "one writer per shard authors example spaces and remaining kind evidence" }, + #{ title: "Verify", detail: "rebuild the graph and re-measure findings" }, + #{ title: "Repair", detail: "fix shards that still fail extraction or honesty" }, + ], +}; + +let mechanical_schema = #{ + "type": "object", "required": ["ok", "summary"], + "properties": #{ + "ok": #{ "type": "boolean" }, + "summary": #{ "type": "string" }, + }, +}; + +let shards_schema = #{ + "type": "object", "required": ["shards"], + "properties": #{ + "shards": #{ "type": "array", "maxItems": 40, "items": #{ + "type": "object", "required": ["id", "root", "kind"], + "properties": #{ + "id": #{ "type": "string" }, + "root": #{ "type": "string" }, + "kind": #{ "type": "string" }, + "note": #{ "type": "string" }, + }, + }}, + }, +}; + +let migrate_schema = #{ + "type": "object", "required": ["root", "edited", "ok"], + "properties": #{ + "root": #{ "type": "string" }, + "edited": #{ "type": "number" }, + "ok": #{ "type": "boolean" }, + "errors": #{ "type": "array", "items": #{ "type": "string" }, "maxItems": 8 }, + }, +}; + +let verify_schema = #{ + "type": "object", "required": ["ok", "specCount", "errorCount", "missingExampleSpaces", "examplesWithoutVerifies", "notes"], + "properties": #{ + "ok": #{ "type": "boolean" }, + "specCount": #{ "type": "number" }, + "errorCount": #{ "type": "number" }, + "missingExampleSpaces": #{ "type": "number" }, + "examplesWithoutVerifies": #{ "type": "number" }, + "notes": #{ "type": "string" }, + "brokenRoots": #{ "type": "array", "items": #{ "type": "string" }, "maxItems": 16 }, + }, +}; + +fn in_specs(root) { + if type_of(root) != "string" { return false; } + if root == "" { return false; } + if root.contains("..") { return false; } + root == "specs" || root.starts_with("specs/") +} + +fn fallback_shards() { + [ + #{ id: "behavior-frontend", root: "specs/behavior/frontend", kind: "behavior" }, + #{ id: "behavior-order-management", root: "specs/behavior/order-management", kind: "behavior" }, + #{ id: "behavior-platform-bc", root: "specs/behavior/platform-bc", kind: "behavior" }, + #{ id: "behavior-platform-bus", root: "specs/behavior/platform-bus", kind: "behavior" }, + #{ id: "behavior-platform-core", root: "specs/behavior/platform-core", kind: "behavior" }, + #{ id: "behavior-platform-decider", root: "specs/behavior/platform-decider", kind: "behavior" }, + #{ id: "behavior-platform-fsm", root: "specs/behavior/platform-fsm", kind: "behavior" }, + #{ id: "behavior-platform-store", root: "specs/behavior/platform-store", kind: "behavior" }, + #{ id: "decisions", root: "specs/decisions", kind: "decision" }, + #{ id: "platform", root: "specs/platform", kind: "platform" }, + #{ id: "unimplemented", root: "specs/unimplemented", kind: "unimplemented" }, + #{ id: "releases", root: "specs/releases", kind: "other" }, + #{ id: "example-app", root: "specs/example-app", kind: "other" }, + ] +} + +fn roots_overlap(left, right) { + if left == right { return true; } + left.starts_with(right + "/") || right.starts_with(left + "/") +} + +fn exclusive_shards(raw) { + let accepted = []; + for s in raw { + if s == () || !in_specs(s.root) { continue; } + let clash = false; + for a in accepted { + if roots_overlap(s.root, a.root) { clash = true; } + } + if clash { + log("Dropped overlapping shard root: " + s.root); + } else { + accepted.push(s); + } + } + accepted +} + +fn migrate_prompt(root, kind) { + let p = ""; + p += "You are migrating already-extracted Libar SDP Markdown carriers under "; + p += root; + p += " (shard kind "; + p += kind; + p += ") up to the Libar Software Delivery Protocol authoring law.\n\n"; + p += "Workspace is /home/darkomijic/dev-libar/libar-platform. Use read_file, grep, and StrReplace/write. "; + p += "Read every file you will edit. Do not answer from memory.\n\n"; + p += "LAW (do not paraphrase into a second model):\n"; + p += "1. Keep every existing Spec id, kind, altitude, and file path. One kind per Spec. Never invent ids.\n"; + p += "2. Envelope YAML uses camelCase relation keys: refines, dependsOn, constrainedBy, decidedBy, verifies, supersedes.\n"; + p += "3. Lawful headings only: Intent, Behavior, Rule, Workflow, Contract, Example space, Constraints, Model, Design, Decision, UI, Verification — executable|manual|reviewed|contract.\n"; + p += "4. Example Specs: add `verifies: ` beside existing `refines` if missing. Intent outcome must be a real sentence, not 'Executable scenario:'.\n"; + p += "5. Example space is OPTIONAL and dangerous: a Markdown ```gwt-vocabulary fence MUST have Given+, exactly one When, and Then+. "; + p += "Add ## Example space on a behavior parent ONLY if every example child under that parent can be expressed against that single When "; + p += "(lift shared literals to {name:type} on the parent and {name: value} on children). "; + p += "If children have genuinely different actions, leave example space off and do not break vocabulary matching.\n"; + p += "6. Child ```gwt fences stay under Intent, immediately after the outcome block, with no trailing prose after the fence.\n"; + p += "7. Never state readiness: ready. You may set defined when the kind's evidence is complete; otherwise keep idea or scoped.\n"; + p += "8. Decision Specs: fill ## Decision with context / decision / rationale / consequence from docs/lineage/architect/decisions when the live body is a title echo. Update architect/ paths to specs/ only when the decision itself is about corpus location.\n"; + p += "9. Unimplemented Specs stay idea. Write an honest outcome; do not pretend they are implemented.\n"; + p += "10. Platform pattern Specs: replace 'Preserve the former architect pattern' stubs with the actual outcome/problem from the matching lineage feature or docs-living pattern. Add a Behavior rule only when the source already states it.\n"; + p += "11. Do not edit specs/generated, pack manifests unless a member id would break, or any file outside this shard root.\n"; + p += "12. Do not invent behavior, slots, or relations you cannot point to in the current file or its lineage source.\n\n"; + p += "Gold-standard shape to copy: /home/darkomijic/dev-libar/software-delivery-protocol/examples/checkout-v1/specs/orders/create-order.sdp.md and create-order-valid-cart.sdp.md.\n"; + p += "Return {root, edited, ok, errors}. ok=true only if you inspected the shard and left valid Markdown carriers.\n"; + p +} + +let scope = if args == () { "all" } else { args.scope }; +if scope == () { scope = "all"; } + +phase("Mechanical"); +let mech_prompt = ""; +mech_prompt += "Run the mechanical Libar SDP migrator in /home/darkomijic/dev-libar/libar-platform.\n"; +mech_prompt += "1. Read scripts/sdp-protocol-migrate.mjs so you know what it changes.\n"; +mech_prompt += "2. Execute: node scripts/sdp-protocol-migrate.mjs\n"; +mech_prompt += "3. Return ok=true and a one-line summary of the JSON the script printed.\n"; +mech_prompt += "If the script fails, return ok=false and put the error in summary. Do not revert files.\n"; +let mechanical = agent(mech_prompt, #{ + label: "mechanical-migrate", + capability_mode: "all", + output_schema: mechanical_schema, +}); +if mechanical == () || !mechanical.success { + pause("infra", "Mechanical migrator agent did not return."); +} +let mech_ok = mechanical.output != () && mechanical.output.ok == true; +if mech_ok && mechanical.output.summary != () && mechanical.output.summary != "" { + log(mechanical.output.summary); +} else { + log("Mechanical migrator reported failure or empty output; continuing to discovery so remaining work is still sharded."); +} + +phase("Discover"); +let discover_prompt = ""; +discover_prompt += "Inventory remaining Libar SDP protocol gaps in /home/darkomijic/dev-libar/libar-platform/specs.\n"; +discover_prompt += "Use grep/read_file (do not parse generated/). Group work into at most 40 non-overlapping shards.\n"; +discover_prompt += "A shard root must be a specs/ directory prefix. Never emit paths with .. or outside specs/.\n"; +discover_prompt += "Prefer grouping a behavior parent *.sdp.md with its sibling .examples/ directory. "; +discover_prompt += "Split platform-core/agent by parent file when a folder exceeds ~80 spec files.\n"; +discover_prompt += "Include: behavior parents still missing ## Example space; decisions with title-echo ## Decision; "; +discover_prompt += "platform/unimplemented stubs whose outcome still starts with Preserve the former / Unimplemented deliverable.\n"; +discover_prompt += "Skip specs/generated. Return {shards:[{id,root,kind,note}]}. An empty list is valid only after you searched.\n"; +let discovered = agent(discover_prompt, #{ + label: "discover-shards", + capability_mode: "read-only", + output_schema: shards_schema, +}); + +let raw_shards = []; +if discovered != () && discovered.success && discovered.output != () && discovered.output.shards != () { + for s in discovered.output.shards { + if s != () && in_specs(s.root) { + raw_shards.push(s); + } else if s != () && s.root != () { + log("Dropped out-of-scope shard root: " + s.root); + } + } +} +let shards = exclusive_shards(raw_shards); +if shards.len() == 0 { + log("Discovery returned no in-scope shards; using the built-in family fallback list."); + shards = fallback_shards(); +} +log("Migrating " + shards.len().to_string() + " shards"); + +phase("Migrate"); +const BATCH = 12; +let migrate_ok = 0; +let migrate_fail = 0; +let edited_total = 0; +let i = 0; +while i < shards.len() { + let jobs = []; + let j = 0; + while j < BATCH && i + j < shards.len() { + let s = shards[i + j]; + let kind = if s.kind == () { "behavior" } else { s.kind }; + jobs.push(#{ + prompt: migrate_prompt(s.root, kind), + label: "migrate:" + s.id, + capability_mode: "read-write", + output_schema: migrate_schema, + }); + j += 1; + } + let results = parallel(jobs); + for r in results { + if r != () && r.success && r.output != () && r.output.ok == true { + migrate_ok += 1; + if r.output.edited != () { edited_total += r.output.edited; } + } else { + migrate_fail += 1; + } + } + i += BATCH; +} +log(migrate_ok.to_string() + " shards ok, " + migrate_fail.to_string() + " failed, edited=" + edited_total.to_string()); + +phase("Verify"); +let verify_prompt = ""; +verify_prompt += "Re-measure the Libar SDP corpus at /home/darkomijic/dev-libar/libar-platform.\n"; +verify_prompt += "Run these commands and use their output, not memory:\n"; +verify_prompt += "1. pnpm sdp:validate\n"; +verify_prompt += "2. pnpm --silent sdp:q --json 'return { specs: g.specs().length, packs: g.packs().length, errors: report.findings.filter((f) => f.severity === \"error\").length, warns: report.findings.filter((f) => f.severity === \"warn\").length }'\n"; +verify_prompt += "3. Count behavior parents that have example children but no Example space heading (grep).\n"; +verify_prompt += "4. Count example Specs whose frontmatter lacks verifies: (grep).\n"; +verify_prompt += "Set ok=true only when errorCount is 0 and the graph still derives. "; +verify_prompt += "brokenRoots: up to 16 specs/ prefixes that still look broken. notes: one short paragraph.\n"; +let verified = agent(verify_prompt, #{ + label: "verify-sdp", + capability_mode: "all", + output_schema: verify_schema, +}); + +let verify_ok = verified != () && verified.success && verified.output != () && verified.output.ok == true; +let broken = []; +if verified != () && verified.success && verified.output != () && verified.output.brokenRoots != () { + for b in verified.output.brokenRoots { + if in_specs(b) { broken.push(b); } + } +} + +if !verify_ok && broken.len() > 0 { + phase("Repair"); + let fixes = []; + for b in broken { + let fp = ""; + fp += "sdp validate reported remaining problems under "; + fp += b; + fp += " in /home/darkomijic/dev-libar/libar-platform. "; + fp += "Read the carriers, run pnpm --silent sdp:q against the affected ids if useful, and fix only files under that root. "; + fp += "Keep ids stable. Never state ready. Prefer removing an illegal Example space over leaving a broken fence. "; + fp += "Return {root, edited, ok, errors}.\n"; + fixes.push(#{ + prompt: fp, + label: "repair:" + b, + capability_mode: "read-write", + output_schema: migrate_schema, + }); + } + let repaired = parallel(fixes); + let repair_ok = 0; + for r in repaired { + if r != () && r.success && r.output != () && r.output.ok == true { repair_ok += 1; } + } + log(repair_ok.to_string() + "/" + broken.len().to_string() + " repair shards succeeded"); + verified = agent(verify_prompt, #{ + label: "verify-sdp-after-repair", + capability_mode: "all", + output_schema: verify_schema, + }); + verify_ok = verified != () && verified.success && verified.output != () && verified.output.ok == true; +} else if !verify_ok { + phase("Repair"); + log("Verify failed without a bounded brokenRoots list; skipping unscoped repair."); +} + +let spec_count = 0; +let error_count = -1; +let missing_spaces = -1; +let missing_verifies = -1; +let notes = ""; +if verified != () && verified.success && verified.output != () { + if verified.output.specCount != () { spec_count = verified.output.specCount; } + if verified.output.errorCount != () { error_count = verified.output.errorCount; } + if verified.output.missingExampleSpaces != () { missing_spaces = verified.output.missingExampleSpaces; } + if verified.output.examplesWithoutVerifies != () { missing_verifies = verified.output.examplesWithoutVerifies; } + if verified.output.notes != () { notes = verified.output.notes; } +} + +let report = ""; +report += "# SDP protocol migration\n\n"; +report += "- shards: " + shards.len().to_string() + "\n"; +report += "- migrate ok/fail: " + migrate_ok.to_string() + "/" + migrate_fail.to_string() + "\n"; +report += "- files agents reported edited: " + edited_total.to_string() + "\n"; +report += "- graph specCount: " + spec_count.to_string() + "\n"; +report += "- validate errorCount: " + error_count.to_string() + "\n"; +report += "- behavior parents still missing example space: " + missing_spaces.to_string() + "\n"; +report += "- examples still missing verifies: " + missing_verifies.to_string() + "\n"; +report += "- verify_ok: "; +if verify_ok { report += "true\n\n"; } else { report += "false\n\n"; } +report += notes; +let report_path = write_scratch_file("sdp-migration-report.md", report); + +complete(#{ + path: report_path, + report: report, + verifyOk: verify_ok, + shards: shards.len(), + migrateOk: migrate_ok, + migrateFail: migrate_fail, + specCount: spec_count, + errorCount: error_count, +}); diff --git a/Justfile b/Justfile new file mode 100644 index 00000000..f6671a5f --- /dev/null +++ b/Justfile @@ -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 diff --git a/README.md b/README.md index 4d820f1d..8210188c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/apps/frontend/convex/admin/intents.ts b/apps/frontend/convex/admin/intents.ts index f0d2b197..f858c765 100644 --- a/apps/frontend/convex/admin/intents.ts +++ b/apps/frontend/convex/admin/intents.ts @@ -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, diff --git a/apps/frontend/convex/admin/poison.ts b/apps/frontend/convex/admin/poison.ts index 50e4fc41..b577f81d 100644 --- a/apps/frontend/convex/admin/poison.ts +++ b/apps/frontend/convex/admin/poison.ts @@ -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. diff --git a/apps/frontend/convex/admin/projections.ts b/apps/frontend/convex/admin/projections.ts index bd2c4383..8b46c52f 100644 --- a/apps/frontend/convex/admin/projections.ts +++ b/apps/frontend/convex/admin/projections.ts @@ -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. diff --git a/apps/frontend/convex/admin/rebuildDemo.ts b/apps/frontend/convex/admin/rebuildDemo.ts index 3617f39a..c97de78f 100644 --- a/apps/frontend/convex/admin/rebuildDemo.ts +++ b/apps/frontend/convex/admin/rebuildDemo.ts @@ -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 diff --git a/apps/frontend/convex/commands/durableOrchestrator.ts b/apps/frontend/convex/commands/durableOrchestrator.ts index 956f2101..0de62b37 100644 --- a/apps/frontend/convex/commands/durableOrchestrator.ts +++ b/apps/frontend/convex/commands/durableOrchestrator.ts @@ -1,8 +1,4 @@ /** - * @architect - * @architect-implements DurableEventsIntegration - * @architect-command - * * Durable Command Orchestrator - Intent/Completion Bracketing Wrapper * * Wraps the standard CommandOrchestrator with durability features: diff --git a/apps/frontend/convex/contexts/agent/index.ts b/apps/frontend/convex/contexts/agent/index.ts index 125954cd..cb4de5f9 100644 --- a/apps/frontend/convex/contexts/agent/index.ts +++ b/apps/frontend/convex/contexts/agent/index.ts @@ -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. diff --git a/apps/frontend/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts b/apps/frontend/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts index d981f2d1..b5bb93b6 100644 --- a/apps/frontend/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts +++ b/apps/frontend/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts @@ -7,10 +7,6 @@ * - Returns `DCBStateUpdates` (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) */ diff --git a/apps/frontend/convex/contexts/inventory/handlers/commands.ts b/apps/frontend/convex/contexts/inventory/handlers/commands.ts index ff9a3b5a..d2269352 100644 --- a/apps/frontend/convex/contexts/inventory/handlers/commands.ts +++ b/apps/frontend/convex/contexts/inventory/handlers/commands.ts @@ -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: diff --git a/apps/frontend/convex/contexts/orders/handlers/commands.ts b/apps/frontend/convex/contexts/orders/handlers/commands.ts index af529a54..9e2429bf 100644 --- a/apps/frontend/convex/contexts/orders/handlers/commands.ts +++ b/apps/frontend/convex/contexts/orders/handlers/commands.ts @@ -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: diff --git a/apps/frontend/convex/dcb/retryExecution.ts b/apps/frontend/convex/dcb/retryExecution.ts index 70104d56..7f681b36 100644 --- a/apps/frontend/convex/dcb/retryExecution.ts +++ b/apps/frontend/convex/dcb/retryExecution.ts @@ -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 * diff --git a/apps/frontend/convex/eventStore/durableAppend.ts b/apps/frontend/convex/eventStore/durableAppend.ts index 23e99ac0..9b7d5995 100644 --- a/apps/frontend/convex/eventStore/durableAppend.ts +++ b/apps/frontend/convex/eventStore/durableAppend.ts @@ -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. diff --git a/apps/frontend/convex/infrastructure.ts b/apps/frontend/convex/infrastructure.ts index 69bd2f84..d0c3cbab 100644 --- a/apps/frontend/convex/infrastructure.ts +++ b/apps/frontend/convex/infrastructure.ts @@ -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. diff --git a/apps/frontend/convex/projections/crossContext/orderWithInventory.ts b/apps/frontend/convex/projections/crossContext/orderWithInventory.ts index e23c5ca4..fd98d7bc 100644 --- a/apps/frontend/convex/projections/crossContext/orderWithInventory.ts +++ b/apps/frontend/convex/projections/crossContext/orderWithInventory.ts @@ -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. diff --git a/apps/frontend/convex/projections/evolve/index.ts b/apps/frontend/convex/projections/evolve/index.ts index c4cabb64..a4999aa9 100644 --- a/apps/frontend/convex/projections/evolve/index.ts +++ b/apps/frontend/convex/projections/evolve/index.ts @@ -14,9 +14,6 @@ * import { evolveOrderSummary } from "@convex/projections/evolve"; * ``` * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ // Order Summary evolve function diff --git a/apps/frontend/convex/projections/evolve/orderSummary.evolve.ts b/apps/frontend/convex/projections/evolve/orderSummary.evolve.ts index eb8083b2..a21130d8 100644 --- a/apps/frontend/convex/projections/evolve/orderSummary.evolve.ts +++ b/apps/frontend/convex/projections/evolve/orderSummary.evolve.ts @@ -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 diff --git a/apps/frontend/convex/projections/orders/orderSummary.ts b/apps/frontend/convex/projections/orders/orderSummary.ts index 285ced9b..f5da9214 100644 --- a/apps/frontend/convex/projections/orders/orderSummary.ts +++ b/apps/frontend/convex/projections/orders/orderSummary.ts @@ -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. diff --git a/apps/frontend/convex/queries/events.ts b/apps/frontend/convex/queries/events.ts index 08183536..b9fdd6e6 100644 --- a/apps/frontend/convex/queries/events.ts +++ b/apps/frontend/convex/queries/events.ts @@ -13,9 +13,6 @@ * Event payloads may contain sensitive data. These queries filter events * to only return those for the requesting entity (streamId match). * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ import { query } from "../_generated/server"; diff --git a/apps/frontend/convex/rateLimits.ts b/apps/frontend/convex/rateLimits.ts index 943fc7ae..33a4bbbd 100644 --- a/apps/frontend/convex/rateLimits.ts +++ b/apps/frontend/convex/rateLimits.ts @@ -4,10 +4,6 @@ * Centralized rate limit configuration for the order-management application. * Uses @convex-dev/rate-limiter for production-grade limiting with sharding. * - * @architect - * @architect-pattern DurableFunctionAdapters - * @architect-status active - * @architect-infra */ import { RateLimiter, MINUTE, HOUR } from "@convex-dev/rate-limiter"; import { components } from "./_generated/api"; diff --git a/apps/frontend/convex/sagas/orderFulfillment.ts b/apps/frontend/convex/sagas/orderFulfillment.ts index 021d6ae3..c305fd07 100644 --- a/apps/frontend/convex/sagas/orderFulfillment.ts +++ b/apps/frontend/convex/sagas/orderFulfillment.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern OrderFulfillmentSaga - * @architect-status completed - * @architect-saga - * @architect-arch-role saga - * @architect-arch-layer application - * @architect-uses OrderCommandHandlers, InventoryCommandHandlers - * * Order Fulfillment Saga. * * Coordinates the order fulfillment process across bounded contexts: diff --git a/apps/frontend/convex/sagas/payments/actions.ts b/apps/frontend/convex/sagas/payments/actions.ts index 64a03b64..fce0eeab 100644 --- a/apps/frontend/convex/sagas/payments/actions.ts +++ b/apps/frontend/convex/sagas/payments/actions.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern MockPaymentActions - * @architect-status completed - * @architect-implements DurableEventsIntegration - * @architect-saga - * * Mock Payment Actions - Simulated external payment service. * * Provides a mock Stripe charge action for integration testing. diff --git a/apps/frontend/convex/sagas/payments/outbox.ts b/apps/frontend/convex/sagas/payments/outbox.ts index 7ff8d153..22a42967 100644 --- a/apps/frontend/convex/sagas/payments/outbox.ts +++ b/apps/frontend/convex/sagas/payments/outbox.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern PaymentOutboxHandler - * @architect-status completed - * @architect-implements DurableEventsIntegration - * @architect-saga - * * Payment Outbox Handler - Captures payment action results as events. * * Uses the outbox pattern to ensure that payment results (success/failure) diff --git a/apps/frontend/convex/schema.ts b/apps/frontend/convex/schema.ts index 0a971417..096d96f1 100644 --- a/apps/frontend/convex/schema.ts +++ b/apps/frontend/convex/schema.ts @@ -482,8 +482,6 @@ export default defineSchema({ * Tracks progress of projection rebuild operations. * Enables checkpoint-based resumption for long-running replays. * - * @architect - * @architect-implements EventReplayInfrastructure */ replayCheckpoints: defineTable({ replayId: v.string(), // Unique identifier (for external reference) diff --git a/apps/frontend/hooks/use-reactive-order-detail.ts b/apps/frontend/hooks/use-reactive-order-detail.ts index f3bf3593..d1dbfea8 100644 --- a/apps/frontend/hooks/use-reactive-order-detail.ts +++ b/apps/frontend/hooks/use-reactive-order-detail.ts @@ -10,9 +10,6 @@ * - Recent events from event store (reactive push) * - Shared evolve logic (same on client and server) * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ import { useQuery } from "convex/react"; diff --git a/apps/frontend/hooks/use-reactive-projection.ts b/apps/frontend/hooks/use-reactive-projection.ts index 1fa20f28..63ec1701 100644 --- a/apps/frontend/hooks/use-reactive-projection.ts +++ b/apps/frontend/hooks/use-reactive-projection.ts @@ -21,9 +21,6 @@ * }); * ``` * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ import { useMemo } from "react"; diff --git a/architect/ARCHITECT-GUIDE.md b/architect/ARCHITECT-GUIDE.md deleted file mode 100644 index 0f8e90c3..00000000 --- a/architect/ARCHITECT-GUIDE.md +++ /dev/null @@ -1,161 +0,0 @@ -# Architect Guide - -> Repo-specific setup for `@libar-dev/architect`. -> For workflow details and package internals, use the upstream architect docs linked below. - ---- - -## Package Documentation - -The monorepo installs `@libar-dev/architect` from the npm registry and keeps -`deps-packages/architect/` as a read-only subtree for source exploration. - -| Topic | Upstream Doc | -| ----------------- | ------------------------------------------------------------------------------------------------ | -| Core methodology | [METHODOLOGY.md](https://github.com/libar-dev/architect/blob/main/docs/METHODOLOGY.md) | -| Session workflows | [SESSION-GUIDES.md](https://github.com/libar-dev/architect/blob/main/docs/SESSION-GUIDES.md) | -| Gherkin authoring | [GHERKIN-PATTERNS.md](https://github.com/libar-dev/architect/blob/main/docs/GHERKIN-PATTERNS.md) | -| Process guard | [PROCESS-GUARD.md](https://github.com/libar-dev/architect/blob/main/docs/PROCESS-GUARD.md) | -| Validation tools | [VALIDATION.md](https://github.com/libar-dev/architect/blob/main/docs/VALIDATION.md) | -| Configuration | [CONFIGURATION.md](https://github.com/libar-dev/architect/blob/main/docs/CONFIGURATION.md) | -| Process API | [PROCESS-API.md](https://github.com/libar-dev/architect/blob/main/docs/PROCESS-API.md) | -| Annotation guide | [ANNOTATION-GUIDE.md](https://github.com/libar-dev/architect/blob/main/docs/ANNOTATION-GUIDE.md) | -| Architecture | [ARCHITECTURE.md](https://github.com/libar-dev/architect/blob/main/docs/ARCHITECTURE.md) | -| MCP setup | [MCP-SETUP.md](https://github.com/libar-dev/architect/blob/main/docs/MCP-SETUP.md) | - -Local generated references: - -- `libar-platform/architect/docs/tag-taxonomy.md` -- `libar-platform/docs-living/reference/` -- `CLAUDE.md` via `pnpm claude:build` - ---- - -## Repo Configuration - -The repo root config is [`architect.config.js`](../../architect.config.js): - -```javascript -import { defineConfig } from "@libar-dev/architect/config"; - -export default defineConfig({ - preset: "ddd-es-cqrs", -}); -``` - -This repo uses the `ddd-es-cqrs` preset: - -- Tag prefix: `@architect-*` -- Opt-in marker: `@architect` -- Categories: 21 DDD/ES/CQRS tags -- Local docs output: `libar-platform/docs-living/` - -Reference-doc overrides in `architect.config.js` also define this repo's scoped -architecture outputs, including the component-topology reference doc. - ---- - -## Directory Map - -| Purpose | Location | -| ---------------------------- | ----------------------------------------------- | -| Roadmap specs | `libar-platform/architect/specs/` | -| Platform specs | `libar-platform/architect/specs/platform/` | -| Example-app specs | `libar-platform/architect/specs/example-app/` | -| Decision records | `libar-platform/architect/decisions/` | -| Release definitions | `libar-platform/architect/releases/` | -| Design stubs | `libar-platform/architect/stubs/` | -| Generated taxonomy reference | `libar-platform/architect/docs/tag-taxonomy.md` | -| Generated living docs | `libar-platform/docs-living/` | -| Source-exploration subtree | `deps-packages/architect/` | - -The subtree is read-only in this repo. Treat it as package source and documentation -reference, not as an editable dependency. - ---- - -## Common Commands - -### CLI - -| Command | Purpose | -| ---------------------------------------------------------------- | -------------------------------- | -| `pnpm exec architect -- overview` | Project health and active work | -| `pnpm architect -- overview` | Repo wrapper around the same API | -| `pnpm exec architect -- context --session ` | Curated session context | -| `pnpm exec architect -- scope-validate ` | FSM and prerequisite pre-flight | - -### Generation - -| Command | Purpose | -| ------------------------------------------------ | --------------------------------------- | -| `pnpm docs:all` | Regenerate the main living docs set | -| `pnpm docs:tag-taxonomy` | Regenerate the local taxonomy reference | -| `pnpm exec architect-generate -g reference-docs` | Regenerate reference docs from config | -| `pnpm exec architect-generate -g patterns` | Regenerate pattern registry outputs | - -### Validation - -| Command | Purpose | -| ------------------------------------ | ----------------------------- | -| `pnpm exec architect-guard --staged` | Pre-commit FSM guard | -| `pnpm exec architect-guard --all` | Full-repo FSM validation | -| `pnpm exec architect-lint-patterns` | Annotation and authoring lint | -| `pnpm exec architect-validate` | Full validation pipeline | - -### Claude Modules - -| Command | Purpose | -| ---------------------- | -------------------------------------- | -| `pnpm claude:build` | Rebuild `CLAUDE.md` from `_claude-md/` | -| `pnpm claude:validate` | Validate modular source files | -| `pnpm claude:preview` | Preview output without writing | - ---- - -## Session Output Paths - -| Session Type | Output Location | -| -------------- | ------------------------------------------------------------------------------------------ | -| Planning | `libar-platform/architect/specs/{product-area}/` | -| Design | `libar-platform/architect/decisions/` and `libar-platform/architect/stubs/{pattern-name}/` | -| Implementation | Runtime packages, tests, and docs under `libar-platform/` | - -For interactive sessions, prefer the architect CLI and `pnpm architect` over -manually reading generated markdown. - ---- - -## Taxonomy Source of Truth - -The repo's generated reference is: - -- `libar-platform/architect/docs/tag-taxonomy.md` - -The package source of truth is: - -- `deps-packages/architect/src/taxonomy/registry-builder.ts` -- `deps-packages/architect/src/taxonomy/status-values.ts` -- `deps-packages/architect/src/taxonomy/categories.ts` -- `deps-packages/architect/src/taxonomy/format-types.ts` - -Regenerate the local reference after config or upstream taxonomy changes: - -```bash -pnpm docs:tag-taxonomy -``` - ---- - -## Quick Links - -| Task | Reference | -| -------------------------- | ------------------------------------------------------------------------------------------------ | -| Understand the methodology | [METHODOLOGY.md](https://github.com/libar-dev/architect/blob/main/docs/METHODOLOGY.md) | -| Choose a session workflow | [SESSION-GUIDES.md](https://github.com/libar-dev/architect/blob/main/docs/SESSION-GUIDES.md) | -| Write feature files | [GHERKIN-PATTERNS.md](https://github.com/libar-dev/architect/blob/main/docs/GHERKIN-PATTERNS.md) | -| Review tags and formats | [ANNOTATION-GUIDE.md](https://github.com/libar-dev/architect/blob/main/docs/ANNOTATION-GUIDE.md) | -| Understand the guard | [PROCESS-GUARD.md](https://github.com/libar-dev/architect/blob/main/docs/PROCESS-GUARD.md) | -| Review local taxonomy | [docs/tag-taxonomy.md](docs/tag-taxonomy.md) | -| View current roadmap | [ROADMAP.md](../docs-living/ROADMAP.md) | -| View pattern registry | [PATTERNS.md](../docs-living/PATTERNS.md) | diff --git a/architect/README.md b/architect/README.md new file mode 100644 index 00000000..c510512a --- /dev/null +++ b/architect/README.md @@ -0,0 +1,16 @@ +# architect/ (moved) + +The former architect delivery corpus (`specs/`, `decisions/`, `releases/`, stubs, and guides) +was relocated to [`docs/lineage/architect/`](../docs/lineage/architect/). + +**Live delivery corpus:** [`specs/`](../specs/) — Libar Software Delivery Protocol Specs and Packs. + +```sh +pnpm sdp:build +pnpm sdp:validate +pnpm sdp:view +``` + +Cucumber `.feature` files under `packages/`, `examples/`, and `apps/` remain **runtime tests**. +Each Feature/Scenario has an SDP Spec under `specs/behavior/`. +Non-implemented backlog lives under `specs/unimplemented/`. diff --git a/docs/lineage/README.md b/docs/lineage/README.md new file mode 100644 index 00000000..2d0be93c --- /dev/null +++ b/docs/lineage/README.md @@ -0,0 +1,9 @@ +# Lineage + +Historical design evidence, not the live delivery corpus. + +| Path | What it is | +| --- | --- | +| `architect/` | Former `@libar-dev/architect` Gherkin specs, decisions, releases, stubs, and guides | + +Live intent is authored under [`specs/`](../../specs/). Query it with `pnpm sdp:q`. diff --git a/docs/lineage/architect/ARCHITECT-GUIDE.md b/docs/lineage/architect/ARCHITECT-GUIDE.md new file mode 100644 index 00000000..27984e81 --- /dev/null +++ b/docs/lineage/architect/ARCHITECT-GUIDE.md @@ -0,0 +1,20 @@ +# Architect Guide (historical) + +> **Retired delivery path.** libar-platform now uses **Libar Software Delivery Protocol (SDP)** — +> package `@libar-dev/software-delivery-protocol`, CLI `sdp`. Live intent lives under `specs/`. +> See the repo root `README.md` and `specs/README.md`. + +This file previously documented `@libar-dev/architect` setup for this repo. This tree is +`docs/lineage/architect/` — historical Gherkin only. Do not run `architect-generate`, +`architect-guard`, `architect-lint-patterns`, or `architect-validate` as the delivery workflow. + +## Current commands + +| Command | Purpose | +| --- | --- | +| `pnpm sdp:build` | Extract the SDP graph from `specs/` | +| `pnpm sdp:validate` | Conformance + honesty checks | +| `pnpm sdp:view` | Design Review projection | +| `pnpm sdp:q '…'` | Script the graph | + +Upstream architect package docs remain useful as historical design evidence only. diff --git a/architect/DESIGN-SESSION-GUIDE.md b/docs/lineage/architect/DESIGN-SESSION-GUIDE.md similarity index 100% rename from architect/DESIGN-SESSION-GUIDE.md rename to docs/lineage/architect/DESIGN-SESSION-GUIDE.md diff --git a/architect/SPEC-CLEANUP-REPORT.md b/docs/lineage/architect/SPEC-CLEANUP-REPORT.md similarity index 100% rename from architect/SPEC-CLEANUP-REPORT.md rename to docs/lineage/architect/SPEC-CLEANUP-REPORT.md diff --git a/architect/_shared/annotation-ownership.md b/docs/lineage/architect/_shared/annotation-ownership.md similarity index 100% rename from architect/_shared/annotation-ownership.md rename to docs/lineage/architect/_shared/annotation-ownership.md diff --git a/architect/_shared/four-tier-ladder.md b/docs/lineage/architect/_shared/four-tier-ladder.md similarity index 100% rename from architect/_shared/four-tier-ladder.md rename to docs/lineage/architect/_shared/four-tier-ladder.md diff --git a/architect/_shared/fsm-transitions.md b/docs/lineage/architect/_shared/fsm-transitions.md similarity index 100% rename from architect/_shared/fsm-transitions.md rename to docs/lineage/architect/_shared/fsm-transitions.md diff --git a/architect/_shared/spec-pattern-relationships.md b/docs/lineage/architect/_shared/spec-pattern-relationships.md similarity index 100% rename from architect/_shared/spec-pattern-relationships.md rename to docs/lineage/architect/_shared/spec-pattern-relationships.md diff --git a/architect/_shared/value-transfer.md b/docs/lineage/architect/_shared/value-transfer.md similarity index 100% rename from architect/_shared/value-transfer.md rename to docs/lineage/architect/_shared/value-transfer.md diff --git a/architect/decisions/pdr-001-process-decisions-folder.feature b/docs/lineage/architect/decisions/pdr-001-process-decisions-folder.feature similarity index 100% rename from architect/decisions/pdr-001-process-decisions-folder.feature rename to docs/lineage/architect/decisions/pdr-001-process-decisions-folder.feature diff --git a/architect/decisions/pdr-002-release-management-architecture.feature b/docs/lineage/architect/decisions/pdr-002-release-management-architecture.feature similarity index 100% rename from architect/decisions/pdr-002-release-management-architecture.feature rename to docs/lineage/architect/decisions/pdr-002-release-management-architecture.feature diff --git a/architect/decisions/pdr-003-behavior-feature-file-structure.feature b/docs/lineage/architect/decisions/pdr-003-behavior-feature-file-structure.feature similarity index 100% rename from architect/decisions/pdr-003-behavior-feature-file-structure.feature rename to docs/lineage/architect/decisions/pdr-003-behavior-feature-file-structure.feature diff --git a/architect/decisions/pdr-004-unified-tag-prefix-architecture.feature b/docs/lineage/architect/decisions/pdr-004-unified-tag-prefix-architecture.feature similarity index 100% rename from architect/decisions/pdr-004-unified-tag-prefix-architecture.feature rename to docs/lineage/architect/decisions/pdr-004-unified-tag-prefix-architecture.feature diff --git a/architect/decisions/pdr-005-mvp-workflow.feature b/docs/lineage/architect/decisions/pdr-005-mvp-workflow.feature similarity index 100% rename from architect/decisions/pdr-005-mvp-workflow.feature rename to docs/lineage/architect/decisions/pdr-005-mvp-workflow.feature diff --git a/architect/decisions/pdr-006-typescript-sourced-taxonomy.feature b/docs/lineage/architect/decisions/pdr-006-typescript-sourced-taxonomy.feature similarity index 100% rename from architect/decisions/pdr-006-typescript-sourced-taxonomy.feature rename to docs/lineage/architect/decisions/pdr-006-typescript-sourced-taxonomy.feature diff --git a/architect/decisions/pdr-007-two-tier-spec-architecture.feature b/docs/lineage/architect/decisions/pdr-007-two-tier-spec-architecture.feature similarity index 100% rename from architect/decisions/pdr-007-two-tier-spec-architecture.feature rename to docs/lineage/architect/decisions/pdr-007-two-tier-spec-architecture.feature diff --git a/architect/decisions/pdr-008-example-app-purpose.feature b/docs/lineage/architect/decisions/pdr-008-example-app-purpose.feature similarity index 100% rename from architect/decisions/pdr-008-example-app-purpose.feature rename to docs/lineage/architect/decisions/pdr-008-example-app-purpose.feature diff --git a/architect/decisions/pdr-009-design-session-methodology.feature b/docs/lineage/architect/decisions/pdr-009-design-session-methodology.feature similarity index 100% rename from architect/decisions/pdr-009-design-session-methodology.feature rename to docs/lineage/architect/decisions/pdr-009-design-session-methodology.feature diff --git a/architect/decisions/pdr-010-cross-component-argument-injection.feature b/docs/lineage/architect/decisions/pdr-010-cross-component-argument-injection.feature similarity index 100% rename from architect/decisions/pdr-010-cross-component-argument-injection.feature rename to docs/lineage/architect/decisions/pdr-010-cross-component-argument-injection.feature diff --git a/architect/decisions/pdr-011-agent-action-handler-architecture.feature b/docs/lineage/architect/decisions/pdr-011-agent-action-handler-architecture.feature similarity index 100% rename from architect/decisions/pdr-011-agent-action-handler-architecture.feature rename to docs/lineage/architect/decisions/pdr-011-agent-action-handler-architecture.feature diff --git a/architect/decisions/pdr-012-agent-command-routing.feature b/docs/lineage/architect/decisions/pdr-012-agent-command-routing.feature similarity index 100% rename from architect/decisions/pdr-012-agent-command-routing.feature rename to docs/lineage/architect/decisions/pdr-012-agent-command-routing.feature diff --git a/architect/decisions/pdr-013-agent-lifecycle-fsm.feature b/docs/lineage/architect/decisions/pdr-013-agent-lifecycle-fsm.feature similarity index 100% rename from architect/decisions/pdr-013-agent-lifecycle-fsm.feature rename to docs/lineage/architect/decisions/pdr-013-agent-lifecycle-fsm.feature diff --git a/architect/decisions/pdr-014-component-boundary-authentication-convention.feature b/docs/lineage/architect/decisions/pdr-014-component-boundary-authentication-convention.feature similarity index 100% rename from architect/decisions/pdr-014-component-boundary-authentication-convention.feature rename to docs/lineage/architect/decisions/pdr-014-component-boundary-authentication-convention.feature diff --git a/architect/decisions/pdr-015-global-position-numeric-representation.feature b/docs/lineage/architect/decisions/pdr-015-global-position-numeric-representation.feature similarity index 100% rename from architect/decisions/pdr-015-global-position-numeric-representation.feature rename to docs/lineage/architect/decisions/pdr-015-global-position-numeric-representation.feature diff --git a/architect/decisions/pdr-016-projection-pool-split-named-pools-per-concern.feature b/docs/lineage/architect/decisions/pdr-016-projection-pool-split-named-pools-per-concern.feature similarity index 100% rename from architect/decisions/pdr-016-projection-pool-split-named-pools-per-concern.feature rename to docs/lineage/architect/decisions/pdr-016-projection-pool-split-named-pools-per-concern.feature diff --git a/architect/decisions/pdr-017-tranche-3-platform-architecture-gate.feature b/docs/lineage/architect/decisions/pdr-017-tranche-3-platform-architecture-gate.feature similarity index 100% rename from architect/decisions/pdr-017-tranche-3-platform-architecture-gate.feature rename to docs/lineage/architect/decisions/pdr-017-tranche-3-platform-architecture-gate.feature diff --git a/architect/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.feature b/docs/lineage/architect/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.feature similarity index 100% rename from architect/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.feature rename to docs/lineage/architect/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.feature diff --git a/architect/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.feature b/docs/lineage/architect/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.feature similarity index 100% rename from architect/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.feature rename to docs/lineage/architect/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.feature diff --git a/architect/decisions/pdr-020-events-table-index-policy.feature b/docs/lineage/architect/decisions/pdr-020-events-table-index-policy.feature similarity index 100% rename from architect/decisions/pdr-020-events-table-index-policy.feature rename to docs/lineage/architect/decisions/pdr-020-events-table-index-policy.feature diff --git a/architect/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.feature b/docs/lineage/architect/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.feature similarity index 100% rename from architect/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.feature rename to docs/lineage/architect/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.feature diff --git a/architect/decisions/pdr-022-value-transfer-doctrine-adoption.feature b/docs/lineage/architect/decisions/pdr-022-value-transfer-doctrine-adoption.feature similarity index 100% rename from architect/decisions/pdr-022-value-transfer-doctrine-adoption.feature rename to docs/lineage/architect/decisions/pdr-022-value-transfer-doctrine-adoption.feature diff --git a/architect/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.feature b/docs/lineage/architect/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.feature similarity index 100% rename from architect/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.feature rename to docs/lineage/architect/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.feature diff --git a/architect/design-reviews/agent-as-bounded-context.md b/docs/lineage/architect/design-reviews/agent-as-bounded-context.md similarity index 100% rename from architect/design-reviews/agent-as-bounded-context.md rename to docs/lineage/architect/design-reviews/agent-as-bounded-context.md diff --git a/architect/design-reviews/command-bus-foundation.md b/docs/lineage/architect/design-reviews/command-bus-foundation.md similarity index 100% rename from architect/design-reviews/command-bus-foundation.md rename to docs/lineage/architect/design-reviews/command-bus-foundation.md diff --git a/architect/design-reviews/durable-function-adapters.md b/docs/lineage/architect/design-reviews/durable-function-adapters.md similarity index 100% rename from architect/design-reviews/durable-function-adapters.md rename to docs/lineage/architect/design-reviews/durable-function-adapters.md diff --git a/architect/design-reviews/event-store-foundation.md b/docs/lineage/architect/design-reviews/event-store-foundation.md similarity index 100% rename from architect/design-reviews/event-store-foundation.md rename to docs/lineage/architect/design-reviews/event-store-foundation.md diff --git a/architect/design-reviews/saga-orchestration.md b/docs/lineage/architect/design-reviews/saga-orchestration.md similarity index 100% rename from architect/design-reviews/saga-orchestration.md rename to docs/lineage/architect/design-reviews/saga-orchestration.md diff --git a/architect/design-reviews/workpool-partitioning-strategy.md b/docs/lineage/architect/design-reviews/workpool-partitioning-strategy.md similarity index 100% rename from architect/design-reviews/workpool-partitioning-strategy.md rename to docs/lineage/architect/design-reviews/workpool-partitioning-strategy.md diff --git a/architect/docs/process-api-configuration-audit-HISTORICAL.md b/docs/lineage/architect/docs/process-api-configuration-audit-HISTORICAL.md similarity index 100% rename from architect/docs/process-api-configuration-audit-HISTORICAL.md rename to docs/lineage/architect/docs/process-api-configuration-audit-HISTORICAL.md diff --git a/architect/docs/tag-taxonomy.md b/docs/lineage/architect/docs/tag-taxonomy.md similarity index 100% rename from architect/docs/tag-taxonomy.md rename to docs/lineage/architect/docs/tag-taxonomy.md diff --git a/architect/metadata-schema-v2.md b/docs/lineage/architect/metadata-schema-v2.md similarity index 100% rename from architect/metadata-schema-v2.md rename to docs/lineage/architect/metadata-schema-v2.md diff --git a/architect/releases/v0.1.0.feature b/docs/lineage/architect/releases/v0.1.0.feature similarity index 100% rename from architect/releases/v0.1.0.feature rename to docs/lineage/architect/releases/v0.1.0.feature diff --git a/architect/releases/v0.2.0.feature b/docs/lineage/architect/releases/v0.2.0.feature similarity index 100% rename from architect/releases/v0.2.0.feature rename to docs/lineage/architect/releases/v0.2.0.feature diff --git a/architect/releases/v0.3.0.feature b/docs/lineage/architect/releases/v0.3.0.feature similarity index 100% rename from architect/releases/v0.3.0.feature rename to docs/lineage/architect/releases/v0.3.0.feature diff --git a/architect/releases/vNEXT.feature b/docs/lineage/architect/releases/vNEXT.feature similarity index 100% rename from architect/releases/vNEXT.feature rename to docs/lineage/architect/releases/vNEXT.feature diff --git a/architect/remediation/REMEDIATION_PLAN.md b/docs/lineage/architect/remediation/REMEDIATION_PLAN.md similarity index 100% rename from architect/remediation/REMEDIATION_PLAN.md rename to docs/lineage/architect/remediation/REMEDIATION_PLAN.md diff --git a/architect/specs/codec-driven-reference-generation.feature b/docs/lineage/architect/specs/codec-driven-reference-generation.feature similarity index 100% rename from architect/specs/codec-driven-reference-generation.feature rename to docs/lineage/architect/specs/codec-driven-reference-generation.feature diff --git a/architect/specs/epic-process-enhancements.feature b/docs/lineage/architect/specs/epic-process-enhancements.feature similarity index 100% rename from architect/specs/epic-process-enhancements.feature rename to docs/lineage/architect/specs/epic-process-enhancements.feature diff --git a/architect/specs/example-app/agent-admin-frontend.feature b/docs/lineage/architect/specs/example-app/agent-admin-frontend.feature similarity index 100% rename from architect/specs/example-app/agent-admin-frontend.feature rename to docs/lineage/architect/specs/example-app/agent-admin-frontend.feature diff --git a/architect/specs/platform/admin-tooling-consolidation.feature b/docs/lineage/architect/specs/platform/admin-tooling-consolidation.feature similarity index 100% rename from architect/specs/platform/admin-tooling-consolidation.feature rename to docs/lineage/architect/specs/platform/admin-tooling-consolidation.feature diff --git a/architect/specs/platform/agent-bc-component-isolation.feature b/docs/lineage/architect/specs/platform/agent-bc-component-isolation.feature similarity index 100% rename from architect/specs/platform/agent-bc-component-isolation.feature rename to docs/lineage/architect/specs/platform/agent-bc-component-isolation.feature diff --git a/architect/specs/platform/agent-command-infrastructure.feature b/docs/lineage/architect/specs/platform/agent-command-infrastructure.feature similarity index 100% rename from architect/specs/platform/agent-command-infrastructure.feature rename to docs/lineage/architect/specs/platform/agent-command-infrastructure.feature diff --git a/architect/specs/platform/agent-llm-integration.feature b/docs/lineage/architect/specs/platform/agent-llm-integration.feature similarity index 100% rename from architect/specs/platform/agent-llm-integration.feature rename to docs/lineage/architect/specs/platform/agent-llm-integration.feature diff --git a/architect/specs/platform/circuit-breaker-pattern.feature b/docs/lineage/architect/specs/platform/circuit-breaker-pattern.feature similarity index 100% rename from architect/specs/platform/circuit-breaker-pattern.feature rename to docs/lineage/architect/specs/platform/circuit-breaker-pattern.feature diff --git a/architect/specs/platform/component-boundary-authentication-convention.feature b/docs/lineage/architect/specs/platform/component-boundary-authentication-convention.feature similarity index 100% rename from architect/specs/platform/component-boundary-authentication-convention.feature rename to docs/lineage/architect/specs/platform/component-boundary-authentication-convention.feature diff --git a/architect/specs/platform/confirmed-order-cancellation.feature b/docs/lineage/architect/specs/platform/confirmed-order-cancellation.feature similarity index 100% rename from architect/specs/platform/confirmed-order-cancellation.feature rename to docs/lineage/architect/specs/platform/confirmed-order-cancellation.feature diff --git a/architect/specs/platform/deterministic-id-hashing.feature b/docs/lineage/architect/specs/platform/deterministic-id-hashing.feature similarity index 100% rename from architect/specs/platform/deterministic-id-hashing.feature rename to docs/lineage/architect/specs/platform/deterministic-id-hashing.feature diff --git a/architect/specs/platform/event-correctness-migration.feature b/docs/lineage/architect/specs/platform/event-correctness-migration.feature similarity index 100% rename from architect/specs/platform/event-correctness-migration.feature rename to docs/lineage/architect/specs/platform/event-correctness-migration.feature diff --git a/architect/specs/platform/health-observability.feature b/docs/lineage/architect/specs/platform/health-observability.feature similarity index 100% rename from architect/specs/platform/health-observability.feature rename to docs/lineage/architect/specs/platform/health-observability.feature diff --git a/architect/specs/platform/integration-patterns-21a.feature b/docs/lineage/architect/specs/platform/integration-patterns-21a.feature similarity index 100% rename from architect/specs/platform/integration-patterns-21a.feature rename to docs/lineage/architect/specs/platform/integration-patterns-21a.feature diff --git a/architect/specs/platform/integration-patterns-21b.feature b/docs/lineage/architect/specs/platform/integration-patterns-21b.feature similarity index 100% rename from architect/specs/platform/integration-patterns-21b.feature rename to docs/lineage/architect/specs/platform/integration-patterns-21b.feature diff --git a/architect/specs/platform/package-architecture.feature b/docs/lineage/architect/specs/platform/package-architecture.feature similarity index 100% rename from architect/specs/platform/package-architecture.feature rename to docs/lineage/architect/specs/platform/package-architecture.feature diff --git a/architect/specs/platform/production-hardening.feature b/docs/lineage/architect/specs/platform/production-hardening.feature similarity index 100% rename from architect/specs/platform/production-hardening.feature rename to docs/lineage/architect/specs/platform/production-hardening.feature diff --git a/architect/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.feature b/docs/lineage/architect/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.feature similarity index 100% rename from architect/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.feature rename to docs/lineage/architect/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.feature diff --git a/architect/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.feature b/docs/lineage/architect/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.feature similarity index 100% rename from architect/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.feature rename to docs/lineage/architect/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.feature diff --git a/architect/specs/platform/tranche-1-supporting-security-and-contract-sweep.feature b/docs/lineage/architect/specs/platform/tranche-1-supporting-security-and-contract-sweep.feature similarity index 100% rename from architect/specs/platform/tranche-1-supporting-security-and-contract-sweep.feature rename to docs/lineage/architect/specs/platform/tranche-1-supporting-security-and-contract-sweep.feature diff --git a/architect/specs/test-content-blocks.feature b/docs/lineage/architect/specs/test-content-blocks.feature similarity index 100% rename from architect/specs/test-content-blocks.feature rename to docs/lineage/architect/specs/test-content-blocks.feature diff --git a/architect/specs/themed-decision-architecture.feature b/docs/lineage/architect/specs/themed-decision-architecture.feature similarity index 100% rename from architect/specs/themed-decision-architecture.feature rename to docs/lineage/architect/specs/themed-decision-architecture.feature diff --git a/architect/src/phases/_archive/README.md b/docs/lineage/architect/src/phases/_archive/README.md similarity index 100% rename from architect/src/phases/_archive/README.md rename to docs/lineage/architect/src/phases/_archive/README.md diff --git a/architect/src/phases/_archive/v0.1.0/phase-01-foundation.ts b/docs/lineage/architect/src/phases/_archive/v0.1.0/phase-01-foundation.ts similarity index 100% rename from architect/src/phases/_archive/v0.1.0/phase-01-foundation.ts rename to docs/lineage/architect/src/phases/_archive/v0.1.0/phase-01-foundation.ts diff --git a/architect/stubs/agent-action-handler/action-handler.ts b/docs/lineage/architect/stubs/agent-action-handler/action-handler.ts similarity index 100% rename from architect/stubs/agent-action-handler/action-handler.ts rename to docs/lineage/architect/stubs/agent-action-handler/action-handler.ts diff --git a/architect/stubs/agent-action-handler/agent-subscription.ts b/docs/lineage/architect/stubs/agent-action-handler/agent-subscription.ts similarity index 100% rename from architect/stubs/agent-action-handler/agent-subscription.ts rename to docs/lineage/architect/stubs/agent-action-handler/agent-subscription.ts diff --git a/architect/stubs/agent-action-handler/event-subscription-types.ts b/docs/lineage/architect/stubs/agent-action-handler/event-subscription-types.ts similarity index 100% rename from architect/stubs/agent-action-handler/event-subscription-types.ts rename to docs/lineage/architect/stubs/agent-action-handler/event-subscription-types.ts diff --git a/architect/stubs/agent-action-handler/eventbus-publish-update.ts b/docs/lineage/architect/stubs/agent-action-handler/eventbus-publish-update.ts similarity index 100% rename from architect/stubs/agent-action-handler/eventbus-publish-update.ts rename to docs/lineage/architect/stubs/agent-action-handler/eventbus-publish-update.ts diff --git a/architect/stubs/agent-action-handler/oncomplete-handler.ts b/docs/lineage/architect/stubs/agent-action-handler/oncomplete-handler.ts similarity index 100% rename from architect/stubs/agent-action-handler/oncomplete-handler.ts rename to docs/lineage/architect/stubs/agent-action-handler/oncomplete-handler.ts diff --git a/architect/stubs/agent-command-routing/agent-bc-config.ts b/docs/lineage/architect/stubs/agent-command-routing/agent-bc-config.ts similarity index 100% rename from architect/stubs/agent-command-routing/agent-bc-config.ts rename to docs/lineage/architect/stubs/agent-command-routing/agent-bc-config.ts diff --git a/architect/stubs/agent-command-routing/command-bridge.ts b/docs/lineage/architect/stubs/agent-command-routing/command-bridge.ts similarity index 100% rename from architect/stubs/agent-command-routing/command-bridge.ts rename to docs/lineage/architect/stubs/agent-command-routing/command-bridge.ts diff --git a/architect/stubs/agent-command-routing/command-router.ts b/docs/lineage/architect/stubs/agent-command-routing/command-router.ts similarity index 100% rename from architect/stubs/agent-command-routing/command-router.ts rename to docs/lineage/architect/stubs/agent-command-routing/command-router.ts diff --git a/architect/stubs/agent-command-routing/pattern-executor.ts b/docs/lineage/architect/stubs/agent-command-routing/pattern-executor.ts similarity index 100% rename from architect/stubs/agent-command-routing/pattern-executor.ts rename to docs/lineage/architect/stubs/agent-command-routing/pattern-executor.ts diff --git a/architect/stubs/agent-command-routing/pattern-registry.ts b/docs/lineage/architect/stubs/agent-command-routing/pattern-registry.ts similarity index 100% rename from architect/stubs/agent-command-routing/pattern-registry.ts rename to docs/lineage/architect/stubs/agent-command-routing/pattern-registry.ts diff --git a/architect/stubs/agent-component-isolation/component/approvals.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/approvals.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/approvals.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/approvals.ts diff --git a/architect/stubs/agent-component-isolation/component/audit.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/audit.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/audit.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/audit.ts diff --git a/architect/stubs/agent-component-isolation/component/checkpoints.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/checkpoints.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/checkpoints.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/checkpoints.ts diff --git a/architect/stubs/agent-component-isolation/component/commands.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/commands.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/commands.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/commands.ts diff --git a/architect/stubs/agent-component-isolation/component/convex.config.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/convex.config.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/convex.config.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/convex.config.ts diff --git a/architect/stubs/agent-component-isolation/component/deadLetters.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/deadLetters.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/deadLetters.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/deadLetters.ts diff --git a/architect/stubs/agent-component-isolation/component/schema.ts b/docs/lineage/architect/stubs/agent-component-isolation/component/schema.ts similarity index 100% rename from architect/stubs/agent-component-isolation/component/schema.ts rename to docs/lineage/architect/stubs/agent-component-isolation/component/schema.ts diff --git a/architect/stubs/agent-component-isolation/cross-bc-query.ts b/docs/lineage/architect/stubs/agent-component-isolation/cross-bc-query.ts similarity index 100% rename from architect/stubs/agent-component-isolation/cross-bc-query.ts rename to docs/lineage/architect/stubs/agent-component-isolation/cross-bc-query.ts diff --git a/architect/stubs/agent-lifecycle-fsm/checkpoint-status-extension.ts b/docs/lineage/architect/stubs/agent-lifecycle-fsm/checkpoint-status-extension.ts similarity index 100% rename from architect/stubs/agent-lifecycle-fsm/checkpoint-status-extension.ts rename to docs/lineage/architect/stubs/agent-lifecycle-fsm/checkpoint-status-extension.ts diff --git a/architect/stubs/agent-lifecycle-fsm/lifecycle-audit-events.ts b/docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-audit-events.ts similarity index 100% rename from architect/stubs/agent-lifecycle-fsm/lifecycle-audit-events.ts rename to docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-audit-events.ts diff --git a/architect/stubs/agent-lifecycle-fsm/lifecycle-command-handlers.ts b/docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-command-handlers.ts similarity index 100% rename from architect/stubs/agent-lifecycle-fsm/lifecycle-command-handlers.ts rename to docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-command-handlers.ts diff --git a/architect/stubs/agent-lifecycle-fsm/lifecycle-command-types.ts b/docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-command-types.ts similarity index 100% rename from architect/stubs/agent-lifecycle-fsm/lifecycle-command-types.ts rename to docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-command-types.ts diff --git a/architect/stubs/agent-lifecycle-fsm/lifecycle-fsm.ts b/docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-fsm.ts similarity index 100% rename from architect/stubs/agent-lifecycle-fsm/lifecycle-fsm.ts rename to docs/lineage/architect/stubs/agent-lifecycle-fsm/lifecycle-fsm.ts diff --git a/architect/stubs/integration-patterns/patterns.ts b/docs/lineage/architect/stubs/integration-patterns/patterns.ts similarity index 100% rename from architect/stubs/integration-patterns/patterns.ts rename to docs/lineage/architect/stubs/integration-patterns/patterns.ts diff --git a/architect/stubs/production-hardening/monitoring-stubs.ts b/docs/lineage/architect/stubs/production-hardening/monitoring-stubs.ts similarity index 100% rename from architect/stubs/production-hardening/monitoring-stubs.ts rename to docs/lineage/architect/stubs/production-hardening/monitoring-stubs.ts diff --git a/architect/tsconfig.json b/docs/lineage/architect/tsconfig.json similarity index 100% rename from architect/tsconfig.json rename to docs/lineage/architect/tsconfig.json diff --git a/examples/order-management/ARCHITECTURE.md b/examples/order-management/ARCHITECTURE.md index 62a917a3..5a11fecd 100644 --- a/examples/order-management/ARCHITECTURE.md +++ b/examples/order-management/ARCHITECTURE.md @@ -1,10 +1,4 @@ # Order Management Example App Architecture diff --git a/examples/order-management/convex/admin/intents.ts b/examples/order-management/convex/admin/intents.ts index f0d2b197..f858c765 100644 --- a/examples/order-management/convex/admin/intents.ts +++ b/examples/order-management/convex/admin/intents.ts @@ -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, diff --git a/examples/order-management/convex/admin/poison.ts b/examples/order-management/convex/admin/poison.ts index 50e4fc41..b577f81d 100644 --- a/examples/order-management/convex/admin/poison.ts +++ b/examples/order-management/convex/admin/poison.ts @@ -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. diff --git a/examples/order-management/convex/admin/projections.ts b/examples/order-management/convex/admin/projections.ts index a1d7fb74..4f826987 100644 --- a/examples/order-management/convex/admin/projections.ts +++ b/examples/order-management/convex/admin/projections.ts @@ -1,12 +1,6 @@ /** * Admin mutations for projection replay and rebuilding. * - * @architect - * @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. diff --git a/examples/order-management/convex/admin/rebuildDemo.ts b/examples/order-management/convex/admin/rebuildDemo.ts index 7ed6ec8a..0c2dda35 100644 --- a/examples/order-management/convex/admin/rebuildDemo.ts +++ b/examples/order-management/convex/admin/rebuildDemo.ts @@ -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 diff --git a/examples/order-management/convex/commands/durableOrchestrator.ts b/examples/order-management/convex/commands/durableOrchestrator.ts index 956f2101..0de62b37 100644 --- a/examples/order-management/convex/commands/durableOrchestrator.ts +++ b/examples/order-management/convex/commands/durableOrchestrator.ts @@ -1,8 +1,4 @@ /** - * @architect - * @architect-implements DurableEventsIntegration - * @architect-command - * * Durable Command Orchestrator - Intent/Completion Bracketing Wrapper * * Wraps the standard CommandOrchestrator with durability features: diff --git a/examples/order-management/convex/commands/inventory/configs.ts b/examples/order-management/convex/commands/inventory/configs.ts index 2fef768d..7b2cd7bb 100644 --- a/examples/order-management/convex/commands/inventory/configs.ts +++ b/examples/order-management/convex/commands/inventory/configs.ts @@ -1,15 +1,4 @@ /** - * @architect - * @architect-pattern InventoryCommandConfigs - * @architect-status completed - * @architect-command - * @architect-arch-role infrastructure - * @architect-arch-context inventory - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses ActiveReservationsProjection, ProductCatalogProjection, OrderWithInventoryProjection - * @architect-used-by OrderManagementInfrastructure - * * Command configs for 7 inventory commands. Wires each command to * primary/secondary projections including cross-context orderWithInventory. */ diff --git a/examples/order-management/convex/commands/orders/configs.ts b/examples/order-management/convex/commands/orders/configs.ts index ff2ce192..26176e9d 100644 --- a/examples/order-management/convex/commands/orders/configs.ts +++ b/examples/order-management/convex/commands/orders/configs.ts @@ -1,15 +1,4 @@ /** - * @architect - * @architect-pattern OrderCommandConfigs - * @architect-status completed - * @architect-command - * @architect-arch-role infrastructure - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses OrderSummaryProjection, OrderWithInventoryProjection, OrderItemsProjection, CustomerCancellationsProjection - * @architect-used-by OrderManagementInfrastructure - * * Command configs for 6 order commands. Wires each command to primary/secondary * projections, saga routes, and integration events. */ diff --git a/examples/order-management/convex/commands/registry.ts b/examples/order-management/convex/commands/registry.ts index a096f27e..7e18e143 100644 --- a/examples/order-management/convex/commands/registry.ts +++ b/examples/order-management/convex/commands/registry.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern CommandRegistry - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-uses OrderCommandHandlers, InventoryCommandHandlers - * @architect-used-by OrderManagementInfrastructure - * * Command registry with Zod validation schemas per command type. * Used by registry validation middleware for runtime args validation. */ diff --git a/examples/order-management/convex/contexts/agent/_config.ts b/examples/order-management/convex/contexts/agent/_config.ts index 664e8df1..1d09ff5b 100644 --- a/examples/order-management/convex/contexts/agent/_config.ts +++ b/examples/order-management/convex/contexts/agent/_config.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role infrastructure - * @architect-arch-context agent - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-extract-shapes CHURN_RISK_AGENT_ID, CHURN_RISK_SUBSCRIPTIONS, churnRiskAgentConfig - * * Churn Risk Agent Configuration * * Defines the configuration for the churn risk detection agent. diff --git a/examples/order-management/convex/contexts/agent/_llm/config.ts b/examples/order-management/convex/contexts/agent/_llm/config.ts index c9bbb5b7..354e4424 100644 --- a/examples/order-management/convex/contexts/agent/_llm/config.ts +++ b/examples/order-management/convex/contexts/agent/_llm/config.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role infrastructure - * @architect-arch-context agent - * @architect-arch-layer infrastructure - * * LLM Provider Configuration * * Configures the language model for agent pattern analysis. diff --git a/examples/order-management/convex/contexts/agent/_llm/index.ts b/examples/order-management/convex/contexts/agent/_llm/index.ts index 5a30bbe7..a82f80a8 100644 --- a/examples/order-management/convex/contexts/agent/_llm/index.ts +++ b/examples/order-management/convex/contexts/agent/_llm/index.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role infrastructure - * @architect-arch-context agent - * @architect-arch-layer infrastructure - * * LLM Configuration and Runtime Exports * * @module contexts/agent/_llm diff --git a/examples/order-management/convex/contexts/agent/_llm/runtime.ts b/examples/order-management/convex/contexts/agent/_llm/runtime.ts index 6eb3ec14..2002bd4e 100644 --- a/examples/order-management/convex/contexts/agent/_llm/runtime.ts +++ b/examples/order-management/convex/contexts/agent/_llm/runtime.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role infrastructure - * @architect-arch-context agent - * @architect-arch-layer infrastructure - * * OpenRouter Agent Runtime * * Implements AgentRuntimeConfig using the Vercel AI SDK with OpenRouter. diff --git a/examples/order-management/convex/contexts/agent/_patterns/churnRisk.ts b/examples/order-management/convex/contexts/agent/_patterns/churnRisk.ts index 7ce1f5f7..423e741b 100644 --- a/examples/order-management/convex/contexts/agent/_patterns/churnRisk.ts +++ b/examples/order-management/convex/contexts/agent/_patterns/churnRisk.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role decider - * @architect-arch-context agent - * @architect-arch-layer domain - * * Churn Risk Pattern Definition * * Defines the pattern detection rules for identifying customers at risk of churning. diff --git a/examples/order-management/convex/contexts/agent/_utils/confidence.ts b/examples/order-management/convex/contexts/agent/_utils/confidence.ts index cc8bd4e3..74fa7c05 100644 --- a/examples/order-management/convex/contexts/agent/_utils/confidence.ts +++ b/examples/order-management/convex/contexts/agent/_utils/confidence.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role service - * @architect-arch-context agent - * @architect-arch-layer domain - * * Confidence Calculation Utilities for Agent BC * * Shared utilities for calculating churn risk confidence scores. diff --git a/examples/order-management/convex/contexts/agent/_utils/customer.ts b/examples/order-management/convex/contexts/agent/_utils/customer.ts index 15c1d92d..64e679d5 100644 --- a/examples/order-management/convex/contexts/agent/_utils/customer.ts +++ b/examples/order-management/convex/contexts/agent/_utils/customer.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role service - * @architect-arch-context agent - * @architect-arch-layer domain - * * Customer Utility Functions for Agent BC * * Shared utilities for extracting customer information from events. diff --git a/examples/order-management/convex/contexts/agent/_utils/index.ts b/examples/order-management/convex/contexts/agent/_utils/index.ts index 6d0ff54d..5a103643 100644 --- a/examples/order-management/convex/contexts/agent/_utils/index.ts +++ b/examples/order-management/convex/contexts/agent/_utils/index.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role service - * @architect-arch-context agent - * @architect-arch-layer domain - * * Agent BC Utility Functions * * Shared utilities for agent bounded context operations. diff --git a/examples/order-management/convex/contexts/agent/handlers/analyzeEvent.ts b/examples/order-management/convex/contexts/agent/handlers/analyzeEvent.ts index e793434c..23092953 100644 --- a/examples/order-management/convex/contexts/agent/handlers/analyzeEvent.ts +++ b/examples/order-management/convex/contexts/agent/handlers/analyzeEvent.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern AgentActionHandler - * @architect-status completed - * @architect-infra - * @architect-arch-role command-handler - * @architect-arch-context agent - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses AgentLLMIntegration, AgentBCComponentIsolation - * * Agent action handler for churn risk detection. * This is the ACTION half of the action/mutation split pattern. * Runs in Workpool action context -- can call external APIs (LLM). diff --git a/examples/order-management/convex/contexts/agent/handlers/onComplete.ts b/examples/order-management/convex/contexts/agent/handlers/onComplete.ts index 580e88f5..fa65bf67 100644 --- a/examples/order-management/convex/contexts/agent/handlers/onComplete.ts +++ b/examples/order-management/convex/contexts/agent/handlers/onComplete.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern AgentOnCompleteHandler - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-context agent - * @architect-arch-layer infrastructure - * @architect-include overview-topology - * @architect-uses AgentAsBoundedContext, AgentLLMIntegration - * * Workpool job completion handler for agent BC. * This is the MUTATION half of the action/mutation split pattern. * diff --git a/examples/order-management/convex/contexts/agent/index.ts b/examples/order-management/convex/contexts/agent/index.ts index ed52bd6c..ac074673 100644 --- a/examples/order-management/convex/contexts/agent/index.ts +++ b/examples/order-management/convex/contexts/agent/index.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-ddd @architect-core - * @architect-implements AgentAsBoundedContext - * @architect-status active - * @architect-phase 22 - * @architect-depends-on ReactiveProjections - * @architect-brief docs/project-management/aggregate-less-pivot/pattern-briefs/08-agent-as-bc.md - * * ## Agent as Bounded Context - AI-Driven Event Reactors * * Demonstrates the Agent as Bounded Context pattern where AI agents subscribe to diff --git a/examples/order-management/convex/contexts/agent/tools/approval.ts b/examples/order-management/convex/contexts/agent/tools/approval.ts index b669d9f1..ea25b67b 100644 --- a/examples/order-management/convex/contexts/agent/tools/approval.ts +++ b/examples/order-management/convex/contexts/agent/tools/approval.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role service - * @architect-arch-context agent - * @architect-arch-layer application - * * Agent Approval Workflow Tools * * Provides utilities for managing human-in-loop approval workflow for diff --git a/examples/order-management/convex/contexts/agent/tools/emitCommand.ts b/examples/order-management/convex/contexts/agent/tools/emitCommand.ts index 2c744e8f..94d85287 100644 --- a/examples/order-management/convex/contexts/agent/tools/emitCommand.ts +++ b/examples/order-management/convex/contexts/agent/tools/emitCommand.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-uses AgentAsBoundedContext - * @architect-arch-role service - * @architect-arch-context agent - * @architect-arch-layer application - * * Agent Command Emission Tool * * Provides utilities for emitting commands from the agent. diff --git a/examples/order-management/convex/contexts/inventory/domain/deciders/index.ts b/examples/order-management/convex/contexts/inventory/domain/deciders/index.ts index 7f799fdb..67c3b994 100644 --- a/examples/order-management/convex/contexts/inventory/domain/deciders/index.ts +++ b/examples/order-management/convex/contexts/inventory/domain/deciders/index.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern InventoryDeciders - * @architect-status completed - * @architect-decider - * @architect-arch-role decider - * @architect-arch-context inventory - * @architect-arch-layer domain - * @architect-used-by InventoryCommandHandlers - * * Pure decision functions for Inventory aggregate (product + reservation). * SKU uniqueness, stock sufficiency, reservation lifecycle invariants. No I/O. */ diff --git a/examples/order-management/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts b/examples/order-management/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts index 241cb01f..b5bb93b6 100644 --- a/examples/order-management/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts +++ b/examples/order-management/convex/contexts/inventory/domain/deciders/reserveMultipleDCB.ts @@ -7,9 +7,6 @@ * - Returns `DCBStateUpdates` (updates per entity) * - Enables atomic cross-entity invariant validation via executeWithDCB * - * @architect - * @architect-implements ExampleAppModernization - * @architect-status roadmap * * @since Phase 23 (Example App Modernization - Rule 1) */ diff --git a/examples/order-management/convex/contexts/inventory/domain/events.ts b/examples/order-management/convex/contexts/inventory/domain/events.ts index 31e97858..571e59cc 100644 --- a/examples/order-management/convex/contexts/inventory/domain/events.ts +++ b/examples/order-management/convex/contexts/inventory/domain/events.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern InventoryDomainEvents - * @architect-status completed - * @architect-event-sourcing - * @architect-arch-role bounded-context - * @architect-arch-context inventory - * @architect-arch-layer domain - * @architect-used-by InventoryCommandHandlers, OrderWithInventoryProjection, ActiveReservationsProjection, ProductCatalogProjection - * * Inventory BC domain events (7 types). Product lifecycle (Created, StockAdded) * and reservation lifecycle (Reserved, Failed, Confirmed, Released, Expired). */ diff --git a/examples/order-management/convex/contexts/inventory/handlers/commands.ts b/examples/order-management/convex/contexts/inventory/handlers/commands.ts index 577abaa2..d2269352 100644 --- a/examples/order-management/convex/contexts/inventory/handlers/commands.ts +++ b/examples/order-management/convex/contexts/inventory/handlers/commands.ts @@ -1,14 +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-include overview-topology - * @architect-uses InventoryDeciders, InventoryRepository - * * Inventory command handlers implementing the dual-write pattern. * * CRITICAL: Every handler follows this pattern: diff --git a/examples/order-management/convex/contexts/orders/domain/deciders/index.ts b/examples/order-management/convex/contexts/orders/domain/deciders/index.ts index 5db34d0a..24b61c8b 100644 --- a/examples/order-management/convex/contexts/orders/domain/deciders/index.ts +++ b/examples/order-management/convex/contexts/orders/domain/deciders/index.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern OrderDeciders - * @architect-status completed - * @architect-decider - * @architect-arch-role decider - * @architect-arch-context orders - * @architect-arch-layer domain - * @architect-used-by OrderCommandHandlers - * * Pure decision functions for Order aggregate. * Each decider validates invariants and produces events. * No I/O, no ctx — pure functions only. diff --git a/examples/order-management/convex/contexts/orders/domain/events.ts b/examples/order-management/convex/contexts/orders/domain/events.ts index 7286d2b0..134fada7 100644 --- a/examples/order-management/convex/contexts/orders/domain/events.ts +++ b/examples/order-management/convex/contexts/orders/domain/events.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern OrderDomainEvents - * @architect-status completed - * @architect-event-sourcing - * @architect-arch-role bounded-context - * @architect-arch-context orders - * @architect-arch-layer domain - * @architect-used-by OrderCommandHandlers, OrderSummaryProjection, OrderFulfillmentSaga, OrderNotificationPM, ReservationReleasePM - * * Orders BC domain events (6 types, 2 schema versions). * V1: Original schemas. V2: OrderSubmitted with CustomerSnapshot (Fat Events). * Use upcasters to migrate V1 events to V2 at read time. diff --git a/examples/order-management/convex/contexts/orders/handlers/commands.ts b/examples/order-management/convex/contexts/orders/handlers/commands.ts index 659c2079..9e2429bf 100644 --- a/examples/order-management/convex/contexts/orders/handlers/commands.ts +++ b/examples/order-management/convex/contexts/orders/handlers/commands.ts @@ -1,14 +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-include overview-topology - * @architect-uses OrderDeciders, OrderRepository - * * Order command handlers implementing the dual-write pattern. * * CRITICAL: Every handler follows this pattern: diff --git a/examples/order-management/convex/convex.config.ts b/examples/order-management/convex/convex.config.ts index d72d5322..ec026689 100644 --- a/examples/order-management/convex/convex.config.ts +++ b/examples/order-management/convex/convex.config.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern AppCompositionRoot - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-include overview-topology - * * Application composition root. Mounts all Convex components (workpool, workflow, * event store, command bus, rate limiter, agent BC) and bounded contexts (orders, inventory). */ diff --git a/examples/order-management/convex/crossContextQueries.ts b/examples/order-management/convex/crossContextQueries.ts index 20ec8ff3..15951d58 100644 --- a/examples/order-management/convex/crossContextQueries.ts +++ b/examples/order-management/convex/crossContextQueries.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern CrossContextReadModel - * @architect-status completed - * @architect-cqrs - * @architect-arch-role read-model - * @architect-arch-layer application - * * Cross-context query APIs. Combines data from multiple bounded contexts * into unified read models for the frontend. Uses app-level projections. */ diff --git a/examples/order-management/convex/dcb/retryExecution.ts b/examples/order-management/convex/dcb/retryExecution.ts index 326278ae..543a6c11 100644 --- a/examples/order-management/convex/dcb/retryExecution.ts +++ b/examples/order-management/convex/dcb/retryExecution.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern DCBRetryExecution - * @architect-status active - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * DCB Retry Execution — reference implementation for integrating withDCBRetry * into command handlers. Self-referential retry pattern where the retry mutation * schedules itself for re-execution on OCC conflicts. diff --git a/examples/order-management/convex/eventStore/durableAppend.ts b/examples/order-management/convex/eventStore/durableAppend.ts index d77b153c..076cce7e 100644 --- a/examples/order-management/convex/eventStore/durableAppend.ts +++ b/examples/order-management/convex/eventStore/durableAppend.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern DurableAppendAction - * @architect-status completed - * @architect-implements DurableEventsIntegration - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Durable Append - Workpool-backed event append with retry. * * Provides the action handler for durableAppendEvent() from platform-core. diff --git a/examples/order-management/convex/eventSubscriptions.ts b/examples/order-management/convex/eventSubscriptions.ts index a2790dc1..dfc49aa6 100644 --- a/examples/order-management/convex/eventSubscriptions.ts +++ b/examples/order-management/convex/eventSubscriptions.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern EventSubscriptionRegistry - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-include overview-topology - * @architect-uses OrderNotificationPM, ReservationReleasePM, AgentAsBoundedContext, AgentLLMIntegration - * @architect-used-by OrderManagementInfrastructure - * * EventBus pub/sub subscription definitions. * PM subscriptions (priority 200) + Agent subscriptions (priority 250). * NOTE: Projections via CommandConfig are NOT duplicated here. diff --git a/examples/order-management/convex/infrastructure.ts b/examples/order-management/convex/infrastructure.ts index c388ce7f..25799751 100644 --- a/examples/order-management/convex/infrastructure.ts +++ b/examples/order-management/convex/infrastructure.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern OrderManagementInfrastructure - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-include overview-topology - * @architect-uses Workpool, Workflow, EventStore, CommandBus - * * Infrastructure setup for the order-management application. * * Initializes Workpool, Workflow, and other infrastructure components. diff --git a/examples/order-management/convex/integration/deadLetters.ts b/examples/order-management/convex/integration/deadLetters.ts index 5393dbcd..aef5d768 100644 --- a/examples/order-management/convex/integration/deadLetters.ts +++ b/examples/order-management/convex/integration/deadLetters.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern IntegrationDeadLetters - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Dead letter queue management for cross-context event publications. * Handles failed integration event processing with replay and ignore operations. */ diff --git a/examples/order-management/convex/integration/events.ts b/examples/order-management/convex/integration/events.ts index 68a4196c..40c9f64d 100644 --- a/examples/order-management/convex/integration/events.ts +++ b/examples/order-management/convex/integration/events.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern IntegrationEventSchemas - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Integration event schema definitions for cross-context communication. * Published Language pattern — defines the contract for external consumers. */ diff --git a/examples/order-management/convex/integration/handlers.ts b/examples/order-management/convex/integration/handlers.ts index 74dae9e8..9cce34b6 100644 --- a/examples/order-management/convex/integration/handlers.ts +++ b/examples/order-management/convex/integration/handlers.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern IntegrationEventHandlers - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Integration event handlers. Processes integration events from the Published Language * and dispatches to appropriate bounded context commands. */ diff --git a/examples/order-management/convex/integration/routes.ts b/examples/order-management/convex/integration/routes.ts index a33f5047..038ecc81 100644 --- a/examples/order-management/convex/integration/routes.ts +++ b/examples/order-management/convex/integration/routes.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern IntegrationRoutes - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-uses OrderCommandHandlers - * @architect-used-by OrderManagementInfrastructure - * * Integration event routes. Translates internal domain events to integration * events for external consumers. Currently: OrderSubmitted -> OrderPlacedIntegration. */ diff --git a/examples/order-management/convex/inventory.ts b/examples/order-management/convex/inventory.ts index 9f01ab6b..1e5ae441 100644 --- a/examples/order-management/convex/inventory.ts +++ b/examples/order-management/convex/inventory.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern InventoryPublicAPI - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-context inventory - * @architect-arch-layer infrastructure - * * App-level public API for Inventory bounded context. * Exposes CommandOrchestrator-backed mutations for external consumers. */ diff --git a/examples/order-management/convex/inventoryInternal.ts b/examples/order-management/convex/inventoryInternal.ts index d004f2da..d5d18093 100644 --- a/examples/order-management/convex/inventoryInternal.ts +++ b/examples/order-management/convex/inventoryInternal.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern InventoryInternalMutations - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-context inventory - * @architect-arch-layer infrastructure - * * Internal mutations for Inventory operations. * Used by sagas and process managers for programmatic inventory commands. */ diff --git a/examples/order-management/convex/orders.ts b/examples/order-management/convex/orders.ts index fc5b7538..7e2d688b 100644 --- a/examples/order-management/convex/orders.ts +++ b/examples/order-management/convex/orders.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern OrderPublicAPI - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-context orders - * @architect-arch-layer infrastructure - * * App-level public API for Orders bounded context. * Exposes CommandOrchestrator-backed mutations for external consumers. */ diff --git a/examples/order-management/convex/pools.ts b/examples/order-management/convex/pools.ts index d7f523f5..47f83b17 100644 --- a/examples/order-management/convex/pools.ts +++ b/examples/order-management/convex/pools.ts @@ -7,13 +7,6 @@ * Both infrastructure.ts and eventSubscriptions.ts can safely import * from this module without creating cycles. * - * @architect - * @architect-pattern OrderManagementInfrastructure - * @architect-status completed - * @architect-unlock-reason:'Extract-agentPool-break-circular-dep' - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure */ import { Workpool, type WorkpoolComponent, type WorkpoolOptions } from "@convex-dev/workpool"; diff --git a/examples/order-management/convex/processManagers/orderNotification.ts b/examples/order-management/convex/processManagers/orderNotification.ts index 517395b0..23a23e61 100644 --- a/examples/order-management/convex/processManagers/orderNotification.ts +++ b/examples/order-management/convex/processManagers/orderNotification.ts @@ -1,15 +1,4 @@ /** - * @architect - * @architect-pattern OrderNotificationPM - * @architect-status completed - * @architect-saga - * @architect-arch-role process-manager - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses OrderCommandHandlers - * @architect-used-by OrderManagementInfrastructure - * * Process manager: OrderConfirmed -> SendNotification command. * Fire-and-forget coordinator (no compensation, unlike Sagas). * Subscribed via EventBus at PM priority (200). diff --git a/examples/order-management/convex/processManagers/reservationRelease.ts b/examples/order-management/convex/processManagers/reservationRelease.ts index 50f52235..80a8af6f 100644 --- a/examples/order-management/convex/processManagers/reservationRelease.ts +++ b/examples/order-management/convex/processManagers/reservationRelease.ts @@ -1,15 +1,4 @@ /** - * @architect - * @architect-pattern ReservationReleasePM - * @architect-status completed - * @architect-saga - * @architect-arch-role process-manager - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses InventoryCommandHandlers, OrderWithInventoryProjection - * @architect-used-by OrderManagementInfrastructure - * * Process manager: OrderCancelled -> ReleaseReservation command. * Queries orderWithInventory projection to check active reservation exists before emitting release. * Subscribed via EventBus at PM priority (200). diff --git a/examples/order-management/convex/projections/crossContext/orderWithInventory.ts b/examples/order-management/convex/projections/crossContext/orderWithInventory.ts index 125d04fa..09ce90ba 100644 --- a/examples/order-management/convex/projections/crossContext/orderWithInventory.ts +++ b/examples/order-management/convex/projections/crossContext/orderWithInventory.ts @@ -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. diff --git a/examples/order-management/convex/projections/customers/customerCancellations.ts b/examples/order-management/convex/projections/customers/customerCancellations.ts index afa10391..8632884d 100644 --- a/examples/order-management/convex/projections/customers/customerCancellations.ts +++ b/examples/order-management/convex/projections/customers/customerCancellations.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern CustomerCancellationsProjection - * @architect-status completed - * @architect-projection - * @architect-arch-role projection - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-uses OrderCommandHandlers - * @architect-used-by AgentAsBoundedContext - * * Customer cancellation history with rolling 30-day window. * Provides getCustomerCancellations() for churn risk agent pattern detection. Added in Phase 22. */ diff --git a/examples/order-management/convex/projections/deadLetters.ts b/examples/order-management/convex/projections/deadLetters.ts index 4f2d0bab..132ea84f 100644 --- a/examples/order-management/convex/projections/deadLetters.ts +++ b/examples/order-management/convex/projections/deadLetters.ts @@ -2,14 +2,6 @@ // apps/frontend/convex/projections/deadLetters.ts /** - * @architect - * @architect-pattern ProjectionDeadLetters - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-used-by OrderManagementInfrastructure - * * Dead letter queue for failed projection and subscription handlers. * Shared onComplete handler for both direct projections and EventBus delivery. * Provides replay, ignore, and bulk retry operations. diff --git a/examples/order-management/convex/projections/definitions.ts b/examples/order-management/convex/projections/definitions.ts index 203c023c..cacea17f 100644 --- a/examples/order-management/convex/projections/definitions.ts +++ b/examples/order-management/convex/projections/definitions.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern ProjectionDefinitions - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Registry of all projection definitions and replay handler registry. * Central configuration for projection infrastructure. * diff --git a/examples/order-management/convex/projections/evolve/index.ts b/examples/order-management/convex/projections/evolve/index.ts index c4cabb64..a4999aa9 100644 --- a/examples/order-management/convex/projections/evolve/index.ts +++ b/examples/order-management/convex/projections/evolve/index.ts @@ -14,9 +14,6 @@ * import { evolveOrderSummary } from "@convex/projections/evolve"; * ``` * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ // Order Summary evolve function diff --git a/examples/order-management/convex/projections/evolve/orderSummary.evolve.ts b/examples/order-management/convex/projections/evolve/orderSummary.evolve.ts index 99d8e128..a90b1b10 100644 --- a/examples/order-management/convex/projections/evolve/orderSummary.evolve.ts +++ b/examples/order-management/convex/projections/evolve/orderSummary.evolve.ts @@ -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 diff --git a/examples/order-management/convex/projections/inventory/activeReservations.ts b/examples/order-management/convex/projections/inventory/activeReservations.ts index eebbdaf0..e494cb61 100644 --- a/examples/order-management/convex/projections/inventory/activeReservations.ts +++ b/examples/order-management/convex/projections/inventory/activeReservations.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern ActiveReservationsProjection - * @architect-status completed - * @architect-projection - * @architect-arch-role projection - * @architect-arch-context inventory - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses InventoryCommandHandlers - * * Tracks active stock reservations and updates stock levels. * Handles StockReserved, ReservationConfirmed, ReservationReleased, * ReservationExpired. Uses EVENT DATA ONLY — proper ES projection. diff --git a/examples/order-management/convex/projections/inventory/productCatalog.ts b/examples/order-management/convex/projections/inventory/productCatalog.ts index 368d6f35..45f376de 100644 --- a/examples/order-management/convex/projections/inventory/productCatalog.ts +++ b/examples/order-management/convex/projections/inventory/productCatalog.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern ProductCatalogProjection - * @architect-status completed - * @architect-projection - * @architect-arch-role projection - * @architect-arch-context inventory - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses InventoryCommandHandlers - * * Product catalog read model. Handles ProductCreated, StockAdded. * Also updates stockAvailability as secondary projection. */ diff --git a/examples/order-management/convex/projections/orders/orderItems.ts b/examples/order-management/convex/projections/orders/orderItems.ts index 50517d3e..992007a8 100644 --- a/examples/order-management/convex/projections/orders/orderItems.ts +++ b/examples/order-management/convex/projections/orders/orderItems.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern OrderItemsProjection - * @architect-status completed - * @architect-projection - * @architect-arch-role projection - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-uses OrderCommandHandlers - * * Order line items read model. Upsert behavior for individual items. * Handles OrderItemAdded, OrderItemRemoved. */ diff --git a/examples/order-management/convex/projections/orders/orderSummary.ts b/examples/order-management/convex/projections/orders/orderSummary.ts index 3a37d6f9..506120c6 100644 --- a/examples/order-management/convex/projections/orders/orderSummary.ts +++ b/examples/order-management/convex/projections/orders/orderSummary.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern OrderSummaryProjection - * @architect-status completed - * @architect-projection - * @architect-arch-role projection - * @architect-arch-context orders - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-uses EventStore - * * OrderSummary projection handlers (app-level). * * Updates the orderSummaries read model based on order events. diff --git a/examples/order-management/convex/queries/events.ts b/examples/order-management/convex/queries/events.ts index 37226018..865fc7ee 100644 --- a/examples/order-management/convex/queries/events.ts +++ b/examples/order-management/convex/queries/events.ts @@ -13,9 +13,6 @@ * Event payloads may contain sensitive data. These queries filter events * to only return those for the requesting entity (streamId match). * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ import { query } from "../_generated/server"; diff --git a/examples/order-management/convex/rateLimits.ts b/examples/order-management/convex/rateLimits.ts index 39c90749..66dca689 100644 --- a/examples/order-management/convex/rateLimits.ts +++ b/examples/order-management/convex/rateLimits.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern RateLimitDefinitions - * @architect-status completed - * @architect-infra - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Centralized rate limit configuration for the order-management application. * Uses @convex-dev/rate-limiter for production-grade limiting with sharding. */ diff --git a/examples/order-management/convex/sagas/completion.ts b/examples/order-management/convex/sagas/completion.ts index a0520f20..679a6331 100644 --- a/examples/order-management/convex/sagas/completion.ts +++ b/examples/order-management/convex/sagas/completion.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-pattern SagaCompletionHandler - * @architect-status completed - * @architect-saga - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-uses SagaRegistry - * @architect-used-by OrderManagementInfrastructure - * * Workflow onComplete callback handler. Updates saga status on completion * and cleans up workflow state. */ diff --git a/examples/order-management/convex/sagas/orderFulfillment.ts b/examples/order-management/convex/sagas/orderFulfillment.ts index b8666562..c305fd07 100644 --- a/examples/order-management/convex/sagas/orderFulfillment.ts +++ b/examples/order-management/convex/sagas/orderFulfillment.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-pattern OrderFulfillmentSaga - * @architect-status completed - * @architect-saga - * @architect-arch-role saga - * @architect-arch-layer application - * @architect-include overview-topology - * @architect-extract-shapes OrderFulfillmentArgs, OrderFulfillmentResult - * @architect-uses OrderCommandHandlers, InventoryCommandHandlers - * * Order Fulfillment Saga. * * Coordinates the order fulfillment process across bounded contexts: diff --git a/examples/order-management/convex/sagas/payments/actions.ts b/examples/order-management/convex/sagas/payments/actions.ts index bf408bfc..fce0eeab 100644 --- a/examples/order-management/convex/sagas/payments/actions.ts +++ b/examples/order-management/convex/sagas/payments/actions.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern MockPaymentActions - * @architect-status completed - * @architect-implements DurableEventsIntegration - * @architect-saga - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Mock Payment Actions - Simulated external payment service. * * Provides a mock Stripe charge action for integration testing. diff --git a/examples/order-management/convex/sagas/payments/outbox.ts b/examples/order-management/convex/sagas/payments/outbox.ts index 5a4c6e44..22a42967 100644 --- a/examples/order-management/convex/sagas/payments/outbox.ts +++ b/examples/order-management/convex/sagas/payments/outbox.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern PaymentOutboxHandler - * @architect-status completed - * @architect-implements DurableEventsIntegration - * @architect-saga - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * * Payment Outbox Handler - Captures payment action results as events. * * Uses the outbox pattern to ensure that payment results (success/failure) diff --git a/examples/order-management/convex/sagas/registry.ts b/examples/order-management/convex/sagas/registry.ts index 9dde8a7b..a1395b78 100644 --- a/examples/order-management/convex/sagas/registry.ts +++ b/examples/order-management/convex/sagas/registry.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern SagaRegistry - * @architect-status completed - * @architect-saga - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-used-by SagaRouter, OrderFulfillmentSaga - * * Saga registry providing idempotent saga start (startSagaIfNotExists), * status tracking, and Zod payload validation at runtime. */ diff --git a/examples/order-management/convex/sagas/router.ts b/examples/order-management/convex/sagas/router.ts index e02b32ac..90901530 100644 --- a/examples/order-management/convex/sagas/router.ts +++ b/examples/order-management/convex/sagas/router.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-pattern SagaRouter - * @architect-status completed - * @architect-saga - * @architect-arch-role infrastructure - * @architect-arch-layer infrastructure - * @architect-uses OrderFulfillmentSaga - * * Routes domain events to saga workflows. * Currently: OrderSubmitted -> OrderFulfillment saga (idempotent start). */ diff --git a/examples/order-management/convex/schema.ts b/examples/order-management/convex/schema.ts index d009b810..eae332dc 100644 --- a/examples/order-management/convex/schema.ts +++ b/examples/order-management/convex/schema.ts @@ -540,8 +540,6 @@ export default defineSchema({ * Tracks progress of projection rebuild operations. * Enables checkpoint-based resumption for long-running replays. * - * @architect - * @architect-implements EventReplayInfrastructure */ replayCheckpoints: defineTable({ replayId: v.string(), // Unique identifier (for external reference) diff --git a/examples/order-management/tests/features/behavior/agent/on-complete.feature b/examples/order-management/tests/features/behavior/agent/on-complete.feature index 363c1539..9edc14e8 100644 --- a/examples/order-management/tests/features/behavior/agent/on-complete.feature +++ b/examples/order-management/tests/features/behavior/agent/on-complete.feature @@ -1,9 +1,4 @@ -@architect @agent-on-complete -@architect-pattern:AgentChurnRiskCompletionExecutableTests -@architect-status:completed -@architect-unlock-reason:carrier-opt-in-for-shipped-pattern-continuity -@architect-implements:AgentChurnRiskCompletion Feature: Agent onComplete Handler As a system operator diff --git a/examples/order-management/tests/features/behavior/orders/cancel-order.feature b/examples/order-management/tests/features/behavior/orders/cancel-order.feature index c05387ed..7f249fb3 100644 --- a/examples/order-management/tests/features/behavior/orders/cancel-order.feature +++ b/examples/order-management/tests/features/behavior/orders/cancel-order.feature @@ -1,6 +1,4 @@ @orders @commands -@architect-pattern:ConfirmedOrderCancellationExecutableTests -@architect-implements:ConfirmedOrderCancellation Feature: Cancel Order As a customer I want to cancel my order diff --git a/examples/order-management/tests/features/behavior/testing-infrastructure/data-table-parsing.feature b/examples/order-management/tests/features/behavior/testing-infrastructure/data-table-parsing.feature index d7b2062f..6e3c5e8a 100644 --- a/examples/order-management/tests/features/behavior/testing-infrastructure/data-table-parsing.feature +++ b/examples/order-management/tests/features/behavior/testing-infrastructure/data-table-parsing.feature @@ -1,4 +1,3 @@ -@architect-pattern:DataTableParsing @testing-infrastructure Feature: Gherkin DataTable Parsing Utilities diff --git a/examples/order-management/tests/features/behavior/testing-infrastructure/decider-assertions.feature b/examples/order-management/tests/features/behavior/testing-infrastructure/decider-assertions.feature index 12b2a09f..0fe2db90 100644 --- a/examples/order-management/tests/features/behavior/testing-infrastructure/decider-assertions.feature +++ b/examples/order-management/tests/features/behavior/testing-infrastructure/decider-assertions.feature @@ -1,4 +1,3 @@ -@architect-pattern:DeciderAssertions @testing-infrastructure Feature: Decider Testing Assertions diff --git a/examples/order-management/tests/features/behavior/testing-infrastructure/fsm-assertions.feature b/examples/order-management/tests/features/behavior/testing-infrastructure/fsm-assertions.feature index 5624de8f..be9a4842 100644 --- a/examples/order-management/tests/features/behavior/testing-infrastructure/fsm-assertions.feature +++ b/examples/order-management/tests/features/behavior/testing-infrastructure/fsm-assertions.feature @@ -1,4 +1,3 @@ -@architect-pattern:FSMAssertions @testing-infrastructure Feature: FSM Testing Assertions diff --git a/examples/order-management/tests/features/behavior/testing-infrastructure/test-isolation.feature b/examples/order-management/tests/features/behavior/testing-infrastructure/test-isolation.feature index 784c0227..77061778 100644 --- a/examples/order-management/tests/features/behavior/testing-infrastructure/test-isolation.feature +++ b/examples/order-management/tests/features/behavior/testing-infrastructure/test-isolation.feature @@ -1,4 +1,3 @@ -@architect-pattern:TestIsolation @testing-infrastructure Feature: Test Isolation via Namespace Prefixing diff --git a/examples/order-management/tests/features/modernization/dcb-multi-product-reservation.feature b/examples/order-management/tests/features/modernization/dcb-multi-product-reservation.feature index 578b4e3a..aa44e8c9 100644 --- a/examples/order-management/tests/features/modernization/dcb-multi-product-reservation.feature +++ b/examples/order-management/tests/features/modernization/dcb-multi-product-reservation.feature @@ -1,8 +1,3 @@ -@architect-phase:23 -@architect-product-area:ExampleApp -@architect-pattern:DCBMultiProductReservation -@architect-implements:ExampleAppModernization -@architect-status:completed @acceptance-criteria Feature: DCB Multi-Product Reservation diff --git a/examples/order-management/tests/features/modernization/fat-events-order-submitted.feature b/examples/order-management/tests/features/modernization/fat-events-order-submitted.feature index c41999e9..163b622e 100644 --- a/examples/order-management/tests/features/modernization/fat-events-order-submitted.feature +++ b/examples/order-management/tests/features/modernization/fat-events-order-submitted.feature @@ -1,8 +1,3 @@ -@architect-phase:23 -@architect-product-area:ExampleApp -@architect-pattern:EcstFatEvents -@architect-implements:ExampleAppModernization -@architect-status:completed @acceptance-criteria Feature: Fat Events - Enriched OrderSubmitted diff --git a/examples/order-management/tests/features/modernization/reactive-order-detail.feature b/examples/order-management/tests/features/modernization/reactive-order-detail.feature index 1aeb051b..050b5b64 100644 --- a/examples/order-management/tests/features/modernization/reactive-order-detail.feature +++ b/examples/order-management/tests/features/modernization/reactive-order-detail.feature @@ -1,8 +1,3 @@ -@architect-phase:23 -@architect-product-area:ExampleApp -@architect-pattern:ReactiveProjections -@architect-implements:ExampleAppModernization -@architect-status:completed @acceptance-criteria Feature: Reactive Order Detail View diff --git a/examples/order-management/tests/features/modernization/reference-documentation.feature b/examples/order-management/tests/features/modernization/reference-documentation.feature index 15051ef8..3364512a 100644 --- a/examples/order-management/tests/features/modernization/reference-documentation.feature +++ b/examples/order-management/tests/features/modernization/reference-documentation.feature @@ -1,8 +1,3 @@ -@architect-phase:23 -@architect-product-area:ExampleApp -@architect-pattern:ExampleAppModernizationExecutableTests -@architect-implements:ExampleAppModernization -@architect-status:completed @acceptance-criteria Feature: Reference Implementation Documentation diff --git a/examples/order-management/tests/integration-features/durability/durable-commands.feature b/examples/order-management/tests/integration-features/durability/durable-commands.feature index b6f5a66f..824cf1c3 100644 --- a/examples/order-management/tests/integration-features/durability/durable-commands.feature +++ b/examples/order-management/tests/integration-features/durability/durable-commands.feature @@ -1,6 +1,4 @@ @integration @durability @durable-commands -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Durable Command Execution (App Integration) As a developer using event sourcing I want commands to be tracked with intent/completion bracketing diff --git a/examples/order-management/tests/integration-features/durability/durable-publication.feature b/examples/order-management/tests/integration-features/durability/durable-publication.feature index 4ed7bba5..7e2d8a61 100644 --- a/examples/order-management/tests/integration-features/durability/durable-publication.feature +++ b/examples/order-management/tests/integration-features/durability/durable-publication.feature @@ -1,6 +1,4 @@ @integration @durability @publication -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Durable Cross-Context Publication (App Integration) As a developer using event sourcing I want cross-context event publications to be tracked and retryable diff --git a/examples/order-management/tests/integration-features/durability/event-replay.feature b/examples/order-management/tests/integration-features/durability/event-replay.feature index 16487aeb..bbbb4dcf 100644 --- a/examples/order-management/tests/integration-features/durability/event-replay.feature +++ b/examples/order-management/tests/integration-features/durability/event-replay.feature @@ -1,6 +1,4 @@ @integration @durability @event-replay -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Event Replay Infrastructure (App Integration) As a developer maintaining projections I want to rebuild projections from event history diff --git a/examples/order-management/tests/integration-features/durability/idempotent-append.feature b/examples/order-management/tests/integration-features/durability/idempotent-append.feature index c2ff9913..5350d90f 100644 --- a/examples/order-management/tests/integration-features/durability/idempotent-append.feature +++ b/examples/order-management/tests/integration-features/durability/idempotent-append.feature @@ -1,6 +1,4 @@ @integration @durability @idempotent-append -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Idempotent Event Append (App Integration) As a developer using the order-management app I want event appends with idempotency keys to be deduplicated diff --git a/examples/order-management/tests/integration-features/durability/orphan-detection.feature b/examples/order-management/tests/integration-features/durability/orphan-detection.feature index e6e6200b..660b6f90 100644 --- a/examples/order-management/tests/integration-features/durability/orphan-detection.feature +++ b/examples/order-management/tests/integration-features/durability/orphan-detection.feature @@ -1,6 +1,4 @@ @integration @durability @orphan-detection -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Orphan Intent Detection (App Integration) As a developer using event sourcing I want orphaned intents to be detected and flagged diff --git a/examples/order-management/tests/integration-features/durability/poison-event.feature b/examples/order-management/tests/integration-features/durability/poison-event.feature index 93e38253..7092700e 100644 --- a/examples/order-management/tests/integration-features/durability/poison-event.feature +++ b/examples/order-management/tests/integration-features/durability/poison-event.feature @@ -1,6 +1,4 @@ @integration @durability @poison-event -@architect-pattern:DurableEventsIntegrationExecutableTests -@architect-implements:DurableEventsIntegration Feature: Poison Event Handling (App Integration) As a developer using event sourcing I want malformed events to be quarantined after repeated failures diff --git a/examples/order-management/tests/integration-features/orders/cancel-order.feature b/examples/order-management/tests/integration-features/orders/cancel-order.feature index 9c676af7..a8cd9b92 100644 --- a/examples/order-management/tests/integration-features/orders/cancel-order.feature +++ b/examples/order-management/tests/integration-features/orders/cancel-order.feature @@ -1,6 +1,4 @@ @orders @integration @commands -@architect-pattern:ConfirmedOrderCancellationExecutableTests -@architect-implements:ConfirmedOrderCancellation Feature: Cancel Order (Integration) As a customer I want to cancel my order diff --git a/examples/order-management/tests/planning-stubs/modernization/modernization.steps.ts b/examples/order-management/tests/planning-stubs/modernization/modernization.steps.ts index 0a6e70d0..5685e385 100644 --- a/examples/order-management/tests/planning-stubs/modernization/modernization.steps.ts +++ b/examples/order-management/tests/planning-stubs/modernization/modernization.steps.ts @@ -1,8 +1,6 @@ /** * Example App Modernization - Step Definitions Stub * - * @architect - * @architect-implements ExampleAppModernization * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/modernization/ during implementation and replace throw statements. diff --git a/examples/order-management/tests/steps/modernization/dcb-reservation.steps.ts b/examples/order-management/tests/steps/modernization/dcb-reservation.steps.ts index 70839de6..c58e7ef0 100644 --- a/examples/order-management/tests/steps/modernization/dcb-reservation.steps.ts +++ b/examples/order-management/tests/steps/modernization/dcb-reservation.steps.ts @@ -1,9 +1,6 @@ /** * DCB Multi-Product Reservation - Step Definitions * - * @architect - * @architect-implements ExampleAppModernization - * @architect-phase 23 * * These tests verify the DCB (Dynamic Consistency Boundaries) pattern for * multi-product reservation using executeWithDCB: diff --git a/examples/order-management/tests/steps/modernization/fat-events.steps.ts b/examples/order-management/tests/steps/modernization/fat-events.steps.ts index 33db9c54..707c8f85 100644 --- a/examples/order-management/tests/steps/modernization/fat-events.steps.ts +++ b/examples/order-management/tests/steps/modernization/fat-events.steps.ts @@ -1,8 +1,6 @@ /** * Fat Events - OrderSubmitted with Customer Snapshot * - * @architect - * @architect-implements ExampleAppModernization * * These tests verify the Fat Events pattern for OrderSubmitted: * - V2 events include customer snapshot (name, email) diff --git a/examples/order-management/tests/steps/modernization/reactive-projection.steps.ts b/examples/order-management/tests/steps/modernization/reactive-projection.steps.ts index a2cd7bce..a4c4d2ff 100644 --- a/examples/order-management/tests/steps/modernization/reactive-projection.steps.ts +++ b/examples/order-management/tests/steps/modernization/reactive-projection.steps.ts @@ -1,9 +1,6 @@ /** * Reactive Order Detail View - Step Definitions * - * @architect - * @architect-implements ExampleAppModernization - * @architect-phase 23 * * These tests verify the reactive projection pattern for OrderDetailView: * - Instant updates via synchronous event merging diff --git a/examples/order-management/tests/steps/modernization/reference-documentation.steps.ts b/examples/order-management/tests/steps/modernization/reference-documentation.steps.ts index 00d8a0d2..9fc6c34e 100644 --- a/examples/order-management/tests/steps/modernization/reference-documentation.steps.ts +++ b/examples/order-management/tests/steps/modernization/reference-documentation.steps.ts @@ -1,9 +1,6 @@ /** * Reference Implementation Documentation - Step Definitions * - * @architect - * @architect-implements ExampleAppModernization - * @architect-phase 23 * * These tests verify the README.md structure and link validity: * - Reference Implementation designation is present diff --git a/package.json b/package.json index 008a73d7..0527152b 100644 --- a/package.json +++ b/package.json @@ -20,28 +20,18 @@ "format:check": "prettier --check .", "dev": "pnpm --filter order-management dev", "ladle": "pnpm --filter frontend ladle", - "docs:all": "pnpm docs:prd:all && pnpm docs:pdrs && pnpm docs:changelog && pnpm docs:business-rules", - "docs:patterns": "architect-generate --input 'packages/*/src/**/*.ts' --input 'architect/src/**/*.ts' --generators patterns --output docs-living --features 'examples/order-management/tests/**/*.feature' --features 'architect/specs/**/*.feature' --overwrite && prettier --write 'docs-living/**/*.md'", - "docs:roadmap": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --features 'examples/order-management/tests/features/timeline/*.feature' --generators roadmap --output docs-living --overwrite && prettier --write 'docs-living/ROADMAP.md' 'docs-living/phases/*.md'", - "docs:prd": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators requirements --output docs-living --overwrite && prettier --write 'docs-living/PRODUCT-REQUIREMENTS.md' 'docs-living/requirements/*.md'", - "docs:prd:roadmap": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators roadmap --output docs-living --overwrite && prettier --write 'docs-living/ROADMAP.md' 'docs-living/phases/*.md'", - "docs:prd:remaining": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators remaining --output docs-living --overwrite && prettier --write 'docs-living/REMAINING-WORK.md' 'docs-living/remaining/*.md'", - "docs:prd:current": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators current --output docs-living --overwrite && prettier --write 'docs-living/CURRENT-WORK.md' && (ls docs-living/current/*.md >/dev/null 2>&1 && prettier --write 'docs-living/current/*.md' || true)", - "docs:prd:milestones": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators milestones --output docs-living/timeline --overwrite && prettier --write 'docs-living/timeline/COMPLETED-MILESTONES.md' 'docs-living/timeline/milestones/*.md'", - "docs:prd:all": "pnpm docs:prd && pnpm docs:prd:roadmap && pnpm docs:prd:remaining && pnpm docs:prd:current && pnpm docs:prd:milestones", - "docs:pdrs": "architect-generate --input 'architect/src/**/*.ts' --features 'architect/decisions/*.feature' --generators adrs --output docs-living --overwrite && prettier --write 'docs-living/DECISIONS.md' 'docs-living/decisions/**/*.md'", - "docs:business-rules": "architect-generate --input 'architect/src/**/*.ts' --input 'packages/*/src/**/*.ts' --features 'architect/specs/**/*.feature' --features 'architect/specs/**/*.feature.md' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators business-rules --output docs-living --overwrite && prettier --write 'docs-living/BUSINESS-RULES.md'", - "docs:changelog": "architect-generate --input 'packages/*/src/**/*.ts' --input 'architect/src/**/*.ts' --features 'architect/decisions/*.feature' --features 'architect/releases/*.feature' --features 'architect/specs/**/*.feature' --features 'packages/platform-core/tests/features/behavior/**/*.feature' --generators changelog --output docs-living --overwrite && prettier --write 'docs-living/CHANGELOG-GENERATED.md'", - "lint:patterns": "architect-lint-patterns -i 'packages/*/src/**/*.ts'", - "lint:layers": "node ../scripts/lint-layers.mjs", - "architect-guard": "architect-guard", - "release:plan": "node ../scripts/build-release-plan.mjs", - "release:check": "pnpm release:plan -- --check-all" + "sdp": "sdp", + "sdp:build": "sdp build specs", + "sdp:validate": "sdp validate specs", + "sdp:view": "sdp view specs", + "sdp:q": "sdp q --root specs", + "docs:all": "echo \"docs-living architect generators are retired; use pnpm sdp:build / pnpm sdp:validate / pnpm sdp:view\" && exit 1", + "check:sdp-migration": "vitest run --config vitest.migration.config.ts" }, "devDependencies": { "@convex-dev/eslint-plugin": "catalog:", - "@libar-dev/architect": "1.0.0-pre.3", "@edge-runtime/vm": "catalog:", + "@libar-dev/software-delivery-protocol": "file:../software-delivery-protocol", "concurrently": "^9.2.1", "convex-helpers": "catalog:", "eslint": "catalog:", @@ -62,7 +52,12 @@ "@typescript-eslint/types": "8.59.0", "@typescript-eslint/typescript-estree": "8.59.0", "@typescript-eslint/visitor-keys": "8.59.0" - } + }, + "onlyBuiltDependencies": [ + "@swc/core", + "esbuild", + "msw" + ] }, "packageManager": "pnpm@10.26.1" } diff --git a/packages/platform-bc/src/contracts/dual-write-contract.ts b/packages/platform-bc/src/contracts/dual-write-contract.ts index 0302c816..86cf5222 100644 --- a/packages/platform-bc/src/contracts/dual-write-contract.ts +++ b/packages/platform-bc/src/contracts/dual-write-contract.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern DualWriteContract - * @architect-status completed - * @architect-core - * @architect-deliverable BoundedContextFoundation:dual-write-contract - * @architect-uses BoundedContextIdentity - * * ## Dual-Write Contract - BC Type Declaration * * Type-safe contract for bounded contexts using the dual-write pattern, diff --git a/packages/platform-bc/src/contracts/identity.ts b/packages/platform-bc/src/contracts/identity.ts index 9319a04f..e03cda53 100644 --- a/packages/platform-bc/src/contracts/identity.ts +++ b/packages/platform-bc/src/contracts/identity.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern BoundedContextIdentity - * @architect-status completed - * @architect-ddd - * @architect-deliverable BoundedContextFoundation:bounded-context-identity - * * ## Bounded Context Identity - Domain Metadata * * Core identification contract for bounded contexts, providing metadata diff --git a/packages/platform-bc/tests/features/behavior/bc-contracts.feature b/packages/platform-bc/tests/features/behavior/bc-contracts.feature index 5736d893..74b64b74 100644 --- a/packages/platform-bc/tests/features/behavior/bc-contracts.feature +++ b/packages/platform-bc/tests/features/behavior/bc-contracts.feature @@ -1,6 +1,3 @@ -@architect -@architect-phase:19 -@architect-product-area:PlatformBC @testing-infrastructure Feature: Bounded Context Contract Helper Functions diff --git a/packages/platform-bc/tests/features/behavior/bounded-context-foundation-executable-tests.feature b/packages/platform-bc/tests/features/behavior/bounded-context-foundation-executable-tests.feature index 42d26cd3..3739ab75 100644 --- a/packages/platform-bc/tests/features/behavior/bounded-context-foundation-executable-tests.feature +++ b/packages/platform-bc/tests/features/behavior/bounded-context-foundation-executable-tests.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:BoundedContextFoundationExecutableTests -@architect-implements:BoundedContextFoundation -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-product-area:PlatformBC Feature: BoundedContextFoundation Executable Tests **Provenance:** This file was authored under the refactoring carve-out diff --git a/packages/platform-bc/tests/steps/bc-contracts.steps.ts b/packages/platform-bc/tests/steps/bc-contracts.steps.ts index 3cfbf62e..f2403875 100644 --- a/packages/platform-bc/tests/steps/bc-contracts.steps.ts +++ b/packages/platform-bc/tests/steps/bc-contracts.steps.ts @@ -5,8 +5,6 @@ * This is a Layer 0 package (pure TypeScript, no Convex dependencies), * so tests run without any backend - just pure function testing. * - * @architect - * @architect-pattern BddTestingInfrastructure */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-bc/tsconfig.json b/packages/platform-bc/tsconfig.json index b33a80bb..1245c38f 100644 --- a/packages/platform-bc/tsconfig.json +++ b/packages/platform-bc/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-bus/src/client/index.ts b/packages/platform-bus/src/client/index.ts index ead5df6c..3a2068da 100644 --- a/packages/platform-bus/src/client/index.ts +++ b/packages/platform-bus/src/client/index.ts @@ -163,14 +163,6 @@ export interface CommandBusApi { } /** - * @architect - * @architect-pattern CommandBus - * @architect-command @architect-overview @architect-core - * @architect-status completed - * @architect-usecase "Ensuring command idempotency" - * @architect-usecase "Tracking command execution status" - * @architect-used-by CommandOrchestrator - * * ## CommandBus - Command Idempotency Infrastructure * * Type-safe client for the Convex Command Bus component providing infrastructure-level idempotency. Provides command diff --git a/packages/platform-bus/tests/features/behavior/command-bus-foundation-executable-tests.feature b/packages/platform-bus/tests/features/behavior/command-bus-foundation-executable-tests.feature index ad26aca4..3466c35d 100644 --- a/packages/platform-bus/tests/features/behavior/command-bus-foundation-executable-tests.feature +++ b/packages/platform-bus/tests/features/behavior/command-bus-foundation-executable-tests.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:CommandBusFoundationExecutableTests -@architect-implements:CommandBusFoundation -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-product-area:PlatformBus Feature: CommandBusFoundation Executable Tests **Provenance:** This file was authored under the refactoring carve-out diff --git a/packages/platform-bus/tests/features/behavior/idempotency.feature b/packages/platform-bus/tests/features/behavior/idempotency.feature index d4074e7b..4e59a6bf 100644 --- a/packages/platform-bus/tests/features/behavior/idempotency.feature +++ b/packages/platform-bus/tests/features/behavior/idempotency.feature @@ -1,15 +1,4 @@ -@architect-pattern:CommandBusIdempotency @acceptance-criteria -@architect-pattern:CommandBusIdempotency -@architect-status:completed -@architect-phase:59 -@architect-quarter:Q1-2026 -@architect-effort:4h -@architect-effort-actual:4h -@architect-completed:2026-01-08 -@architect-product-area:PlatformBus -@architect-business-value:prevent-duplicate-command-processing -@architect-priority:critical Feature: Command Bus Idempotency Command idempotency ensures that duplicate command submissions (same commandId) diff --git a/packages/platform-bus/tests/steps/idempotency.integration.steps.ts b/packages/platform-bus/tests/steps/idempotency.integration.steps.ts index 0770d0f7..145bed46 100644 --- a/packages/platform-bus/tests/steps/idempotency.integration.steps.ts +++ b/packages/platform-bus/tests/steps/idempotency.integration.steps.ts @@ -9,8 +9,6 @@ * just test-infrastructure # Full cycle on port 3210 * just test-infrastructure-isolated # Full cycle on port 3215 (parallel safe) * - * @architect-command - * @architect-pattern CommandBusIdempotency */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; diff --git a/packages/platform-bus/tests/support/helpers.ts b/packages/platform-bus/tests/support/helpers.ts index 657c435e..8d94f204 100644 --- a/packages/platform-bus/tests/support/helpers.ts +++ b/packages/platform-bus/tests/support/helpers.ts @@ -4,7 +4,6 @@ * Provides test isolation through unique command ID prefixes per test run. * This eliminates the need for database cleanup between tests. * - * @architect-pattern CommandBusIdempotency */ import { ConvexTestingHelper } from "convex-helpers/testing"; diff --git a/packages/platform-bus/tsconfig.json b/packages/platform-bus/tsconfig.json index 341bf76a..483e56d2 100644 --- a/packages/platform-bus/tsconfig.json +++ b/packages/platform-bus/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-contracts-shared/tsconfig.json b/packages/platform-contracts-shared/tsconfig.json index c4359b7e..2163857b 100644 --- a/packages/platform-contracts-shared/tsconfig.json +++ b/packages/platform-contracts-shared/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-core/src/cms/types.ts b/packages/platform-core/src/cms/types.ts index 585165ca..aa417cc3 100644 --- a/packages/platform-core/src/cms/types.ts +++ b/packages/platform-core/src/cms/types.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern CMSDualWrite - * @architect-status completed - * @architect-phase 01 - * @architect-core - * @architect-used-by CommandOrchestrator, CMSRepository - * * ## CMS Dual-Write Pattern - O(1) State + Full Audit * * Core types for Command Model State - the continuously updated aggregate snapshot diff --git a/packages/platform-core/src/correlation/types.ts b/packages/platform-core/src/correlation/types.ts index 61f45da5..b642ddb8 100644 --- a/packages/platform-core/src/correlation/types.ts +++ b/packages/platform-core/src/correlation/types.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern CorrelationChainSystem - * @architect-status completed - * @architect-phase 09 - * @architect-used-by CommandOrchestrator, SagaOrchestration - * * ## Correlation Chain - Request Tracing * * Correlation types for tracking causal relationships in command-event flows. diff --git a/packages/platform-core/src/dcb/backoff.ts b/packages/platform-core/src/dcb/backoff.ts index 91c97a65..a1d51e39 100644 --- a/packages/platform-core/src/dcb/backoff.ts +++ b/packages/platform-core/src/dcb/backoff.ts @@ -3,10 +3,6 @@ * * Exponential backoff with jitter for DCB conflict retry scheduling. * - * @architect - * @architect-implements DurableFunctionAdapters - * @architect-status completed - * @architect-infra * * ### Formula * diff --git a/packages/platform-core/src/dcb/scopeKey.ts b/packages/platform-core/src/dcb/scopeKey.ts index 3649aa8a..29001608 100644 --- a/packages/platform-core/src/dcb/scopeKey.ts +++ b/packages/platform-core/src/dcb/scopeKey.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern DCBScopeKeyUtilities - * @architect-status completed - * @architect-phase 16 - * @architect-ddd - * @architect-extract-shapes SCOPE_KEY_PREFIX, createScopeKey, tryCreateScopeKey, parseScopeKey, validateScopeKey, isValidScopeKey, assertValidScopeKey, isScopeTenant, extractTenantId, extractScopeType, extractScopeId - * * ## DCB Scope Key Utilities * * Re-export the canonical shared scope-key contract used across platform packages. diff --git a/packages/platform-core/src/dcb/types.ts b/packages/platform-core/src/dcb/types.ts index d1c62ad6..2ddcbcc0 100644 --- a/packages/platform-core/src/dcb/types.ts +++ b/packages/platform-core/src/dcb/types.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern DCBTypes - * @architect-status completed - * @architect-phase 16 - * @architect-ddd - * @architect-extract-shapes DCBScopeKey, ParsedScopeKey, ScopeKeyValidationError, DCBScope, ScopeVersionCheckResult, ScopeCommitResult, ScopeOperations, DCBEntityState, DCBAggregatedState, DCBStateUpdates, DCBDecider, DCBEntityConfig, ExecuteWithDCBConfig, DCBExecutionResult, DCBSuccessResult, DCBRejectedResult, DCBFailedResult, DCBConflictResult, DCBDeferredResult, DCBRetryResult - * * ## Dynamic Consistency Boundaries (DCB) - Type Definitions * * Types for scope-based multi-entity coordination within bounded contexts. diff --git a/packages/platform-core/src/dcb/withRetry.ts b/packages/platform-core/src/dcb/withRetry.ts index 69ce594f..f27ed066 100644 --- a/packages/platform-core/src/dcb/withRetry.ts +++ b/packages/platform-core/src/dcb/withRetry.ts @@ -1,11 +1,6 @@ /** * ## DCB Retry Helper - Automatic OCC Conflict Retry via Workpool * - * @architect - * @architect-implements DurableFunctionAdapters - * @architect-status completed - * @architect-infra - * @architect-uses DCB, Workpool * * Wraps DCB operations to automatically retry on OCC (Optimistic Concurrency * Control) conflicts using Workpool for durable, delayed execution. diff --git a/packages/platform-core/src/durability/durableAppend.ts b/packages/platform-core/src/durability/durableAppend.ts index 4a479666..11a5f593 100644 --- a/packages/platform-core/src/durability/durableAppend.ts +++ b/packages/platform-core/src/durability/durableAppend.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-uses WorkpoolPartitioningStrategy - * @architect-used-by SagaEngine, ScheduledJobs, outbox - * @architect-usecase "When event append must survive failures in async contexts" - * * ## Durable Append via Workpool Actions * * Failed event appends from async contexts are retried via Workpool actions diff --git a/packages/platform-core/src/durability/idempotentAppend.ts b/packages/platform-core/src/durability/idempotentAppend.ts index eef269c1..acbfc1b7 100644 --- a/packages/platform-core/src/durability/idempotentAppend.ts +++ b/packages/platform-core/src/durability/idempotentAppend.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-used-by outbox, durableAppend, publication, SagaEngine - * @architect-usecase "When appending events that may be retried or deduplicated" - * * ## Idempotent Event Append * * Ensures each logical event is stored exactly once in the event store, diff --git a/packages/platform-core/src/durability/index.ts b/packages/platform-core/src/durability/index.ts index b9da0b1e..790c512b 100644 --- a/packages/platform-core/src/durability/index.ts +++ b/packages/platform-core/src/durability/index.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * @architect-core - * - * @architect-uses WorkpoolPartitioningStrategy - * @architect-used-by CommandOrchestrator, SagaEngine, ProjectionProcessor - * * ## Event Store Durability * * Guaranteed event persistence patterns for Convex-native event sourcing. diff --git a/packages/platform-core/src/durability/intentCompletion.ts b/packages/platform-core/src/durability/intentCompletion.ts index f82f4b82..acba874f 100644 --- a/packages/platform-core/src/durability/intentCompletion.ts +++ b/packages/platform-core/src/durability/intentCompletion.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-used-by SagaEngine, LongRunningOperations, ReconciliationService - * @architect-usecase "When operations span multiple steps and need visibility" - * * ## Intent/Completion Event Pattern * * Long-running operations bracket with intent and completion events diff --git a/packages/platform-core/src/durability/outbox.ts b/packages/platform-core/src/durability/outbox.ts index e67c1844..437baef3 100644 --- a/packages/platform-core/src/durability/outbox.ts +++ b/packages/platform-core/src/durability/outbox.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-used-by CommandOrchestrator, SagaEngine, PaymentHandler - * @architect-usecase "When capturing external API results as domain events" - * * ## Outbox Pattern for Action Results * * Captures external API results (success or failure) as domain events using diff --git a/packages/platform-core/src/durability/poisonEvent.ts b/packages/platform-core/src/durability/poisonEvent.ts index c084e093..d3aaf8ad 100644 --- a/packages/platform-core/src/durability/poisonEvent.ts +++ b/packages/platform-core/src/durability/poisonEvent.ts @@ -1,12 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-used-by ProjectionProcessor, EventReplayInfrastructure, ProjectionRebuilder - * @architect-usecase "When projection processing must not be blocked by malformed events" - * * ## Poison Event Handling * * Events that cause projection processing failures are tracked; after N diff --git a/packages/platform-core/src/durability/publication.ts b/packages/platform-core/src/durability/publication.ts index 5a53bab0..1faff4d8 100644 --- a/packages/platform-core/src/durability/publication.ts +++ b/packages/platform-core/src/durability/publication.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * - * @architect-uses WorkpoolPartitioningStrategy, EventBusAbstraction - * @architect-used-by IntegrationRoutes, CrossContextIntegration, SagaEngine - * @architect-usecase "When publishing events across bounded contexts durably" - * * ## Durable Cross-Context Event Publication * * Cross-context events use Workpool-backed publication with tracking, diff --git a/packages/platform-core/src/durability/types.ts b/packages/platform-core/src/durability/types.ts index d434ed04..30537220 100644 --- a/packages/platform-core/src/durability/types.ts +++ b/packages/platform-core/src/durability/types.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status completed - * @architect-event-sourcing - * @architect-core - * * ## Event Store Durability Types * * Core types for durable event persistence patterns: @@ -20,7 +14,6 @@ * - Sharing a common type vocabulary for event append, publication, and recovery flows * - Typing retry-safe interfaces passed between platform-core and mounted components * - * @architect-used-by idempotentAppend, outbox, durableAppend, publication, intentCompletion, poisonEvent */ import type { SafeMutationRef, SafeQueryRef } from "../function-refs/types.js"; diff --git a/packages/platform-core/src/ecst/builder.ts b/packages/platform-core/src/ecst/builder.ts index d347a5e5..0d2d7cab 100644 --- a/packages/platform-core/src/ecst/builder.ts +++ b/packages/platform-core/src/ecst/builder.ts @@ -1,10 +1,6 @@ /** * Fat Event Builder - Creates ECST (Event-Carried State Transfer) events * - * @architect - * @architect-implements EcstFatEvents - * @architect-status completed - * @architect-event-sourcing * * Builder utilities for creating fat events with embedded context. * Fat events carry full context for downstream consumers, eliminating diff --git a/packages/platform-core/src/ecst/embed.ts b/packages/platform-core/src/ecst/embed.ts index 598d1da0..ebff019c 100644 --- a/packages/platform-core/src/ecst/embed.ts +++ b/packages/platform-core/src/ecst/embed.ts @@ -1,10 +1,6 @@ /** * Entity Embedding Helpers - Snapshot entity data into fat events * - * @architect - * @architect-implements EcstFatEvents - * @architect-status completed - * @architect-event-sourcing * * Helper functions for embedding entity data into fat events. * Enables selective field inclusion and crypto-shredding markers. diff --git a/packages/platform-core/src/ecst/index.ts b/packages/platform-core/src/ecst/index.ts index 0125420d..abc326fd 100644 --- a/packages/platform-core/src/ecst/index.ts +++ b/packages/platform-core/src/ecst/index.ts @@ -55,8 +55,6 @@ * } * ``` * - * @architect - * @architect-implements EcstFatEvents */ // Type exports diff --git a/packages/platform-core/src/ecst/privacy.ts b/packages/platform-core/src/ecst/privacy.ts index 09c33557..3bc384e3 100644 --- a/packages/platform-core/src/ecst/privacy.ts +++ b/packages/platform-core/src/ecst/privacy.ts @@ -1,10 +1,6 @@ /** * Crypto-Shredding Markers - GDPR compliance for fat events * - * @architect - * @architect-implements EcstFatEvents - * @architect-status completed - * @architect-event-sourcing * * Provides tools for marking PII (Personally Identifiable Information) in * fat events for GDPR-compliant deletion. Marked fields can be identified diff --git a/packages/platform-core/src/ecst/types.ts b/packages/platform-core/src/ecst/types.ts index 5adfa13d..e459aa0b 100644 --- a/packages/platform-core/src/ecst/types.ts +++ b/packages/platform-core/src/ecst/types.ts @@ -1,10 +1,6 @@ /** * ECST Type Definitions * - * @architect - * @architect-implements EcstFatEvents - * @architect-status completed - * @architect-event-sourcing * * Core type definitions for Event-Carried State Transfer (ECST) fat events. */ diff --git a/packages/platform-core/src/ecst/versioning.ts b/packages/platform-core/src/ecst/versioning.ts index 63e04a67..bb0db1ae 100644 --- a/packages/platform-core/src/ecst/versioning.ts +++ b/packages/platform-core/src/ecst/versioning.ts @@ -1,10 +1,6 @@ /** * Schema Versioning - Fat event schema evolution support * - * @architect - * @architect-implements EcstFatEvents - * @architect-status completed - * @architect-event-sourcing * * Provides schema versioning and migration capabilities for fat events. * Enables backward-compatible evolution of event structures over time. diff --git a/packages/platform-core/src/eventbus/ConvexEventBus.ts b/packages/platform-core/src/eventbus/ConvexEventBus.ts index 6bbcd6e4..6ba90610 100644 --- a/packages/platform-core/src/eventbus/ConvexEventBus.ts +++ b/packages/platform-core/src/eventbus/ConvexEventBus.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern EventBusAbstraction - * @architect-status completed - * @architect-phase 09 - * @architect-event-sourcing - * @architect-used-by ProcessManagerLifecycle, SagaOrchestration - * * ## EventBus - Pub/Sub for Domain Events * * Durable event pub/sub using Workpool for parallelism, retries, and dead letter handling. diff --git a/packages/platform-core/src/events/upcaster.ts b/packages/platform-core/src/events/upcaster.ts index 35d7c6f0..e767b517 100644 --- a/packages/platform-core/src/events/upcaster.ts +++ b/packages/platform-core/src/events/upcaster.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern EventUpcasting - * @architect-status completed - * @architect-phase 09 - * @architect-event-sourcing - * * ## Event Upcasting Pipeline - Schema Evolution * * Transforms events from older schema versions to current version at read time. diff --git a/packages/platform-core/src/invariants/createInvariant.ts b/packages/platform-core/src/invariants/createInvariant.ts index 32731ba8..028502f2 100644 --- a/packages/platform-core/src/invariants/createInvariant.ts +++ b/packages/platform-core/src/invariants/createInvariant.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern InvariantFramework - * @architect-status completed - * @architect-phase 11 - * @architect-ddd - * * ## Invariant Framework - Declarative Business Rules * * Factory for declarative business rule validation with typed error codes. diff --git a/packages/platform-core/src/logging/scoped.ts b/packages/platform-core/src/logging/scoped.ts index 0ca5c104..7905afb4 100644 --- a/packages/platform-core/src/logging/scoped.ts +++ b/packages/platform-core/src/logging/scoped.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern LoggingInfrastructure - * @architect-status completed - * @architect-phase 13 - * @architect-infra - * * ## Logging Infrastructure - Scoped Loggers * * Factory for domain-specific loggers with scope prefixes and level filtering. diff --git a/packages/platform-core/src/middleware/MiddlewarePipeline.ts b/packages/platform-core/src/middleware/MiddlewarePipeline.ts index 55205737..f691d8e9 100644 --- a/packages/platform-core/src/middleware/MiddlewarePipeline.ts +++ b/packages/platform-core/src/middleware/MiddlewarePipeline.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern MiddlewarePipeline - * @architect-status completed - * @architect-phase 10 - * @architect-command - * @architect-used-by CommandOrchestrator - * * ## Middleware Pipeline - Command Execution Hooks * * Orchestrates middleware execution in the correct order. diff --git a/packages/platform-core/src/middleware/rateLimitAdapter.ts b/packages/platform-core/src/middleware/rateLimitAdapter.ts index 10b0466a..08d8e1a8 100644 --- a/packages/platform-core/src/middleware/rateLimitAdapter.ts +++ b/packages/platform-core/src/middleware/rateLimitAdapter.ts @@ -5,11 +5,6 @@ * Enables production-grade rate limiting with persistence and sharding without * requiring changes to the middleware pipeline. * - * @architect - * @architect-implements DurableFunctionAdapters - * @architect-status active - * @architect-infra - * @architect-uses RateLimitChecker */ import type { RateLimitChecker, RateLimitResult } from "./types.js"; diff --git a/packages/platform-core/src/orchestration/CommandOrchestrator.ts b/packages/platform-core/src/orchestration/CommandOrchestrator.ts index 2329745b..0da93a48 100644 --- a/packages/platform-core/src/orchestration/CommandOrchestrator.ts +++ b/packages/platform-core/src/orchestration/CommandOrchestrator.ts @@ -36,16 +36,6 @@ type EventAppendResult = Awaited< >; /** - * @architect - * @architect-command @architect-core @architect-overview - * @architect-pattern CommandOrchestrator - * @architect-status completed - * @architect-usecase "Executing commands with dual-write pattern" - * @architect-usecase "Coordinating CMS update, event append, and projection trigger" - * @architect-usecase "Ensuring command idempotency across retries" - * @architect-uses EventStore, CommandBus, MiddlewarePipeline - * @architect-used-by BoundedContextHandlers - * * ## CommandOrchestrator - Dual-Write Pattern Implementation * * The CommandOrchestrator encapsulates the 7-step dual-write + projection execution diff --git a/packages/platform-core/src/orchestration/validation.ts b/packages/platform-core/src/orchestration/validation.ts index a24d7007..6a174f52 100644 --- a/packages/platform-core/src/orchestration/validation.ts +++ b/packages/platform-core/src/orchestration/validation.ts @@ -1,13 +1,6 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status active - * @architect-command * @contract-status: Planned * - * @architect-uses WorkpoolPartitioningStrategy - * @architect-used-by CommandOrchestrator - * @architect-usecase "When validating command configs have explicit partition keys" * * ## Command Config Partition Key Validation * diff --git a/packages/platform-core/src/processManager/index.ts b/packages/platform-core/src/processManager/index.ts index 6c033b92..522d390b 100644 --- a/packages/platform-core/src/processManager/index.ts +++ b/packages/platform-core/src/processManager/index.ts @@ -1,14 +1,4 @@ /** - * @architect - * @architect-saga @architect-ddd @architect-core - * @architect-pattern ProcessManager - * @architect-status completed - * @architect-usecase "Event-reactive coordination without orchestration" - * @architect-usecase "Fire-and-forget command emission from events" - * @architect-usecase "Time-triggered or hybrid event/time patterns" - * @architect-uses EventBusAbstraction - * @architect-used-by BoundedContextHandlers - * * ## ProcessManager - Event-Reactive Coordination * * Process Manager module for event-reactive coordination. diff --git a/packages/platform-core/src/processManager/lifecycle.ts b/packages/platform-core/src/processManager/lifecycle.ts index 90e16283..95ac738f 100644 --- a/packages/platform-core/src/processManager/lifecycle.ts +++ b/packages/platform-core/src/processManager/lifecycle.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern ProcessManagerLifecycle - * @architect-status completed - * @architect-phase 13 - * @architect-uses EventBusAbstraction - * * ## Process Manager Lifecycle FSM * * FSM for managing PM state transitions (idle/processing/completed/failed) with validation. diff --git a/packages/platform-core/src/projections/conflict.ts b/packages/platform-core/src/projections/conflict.ts index ca499796..200cd0a8 100644 --- a/packages/platform-core/src/projections/conflict.ts +++ b/packages/platform-core/src/projections/conflict.ts @@ -20,9 +20,6 @@ * - Timestamps can drift, be out of sync, or have precision issues * - Position comparison is deterministic and reliable * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ // ============================================================================ diff --git a/packages/platform-core/src/projections/reactive.ts b/packages/platform-core/src/projections/reactive.ts index 6b75c4cc..f1017e86 100644 --- a/packages/platform-core/src/projections/reactive.ts +++ b/packages/platform-core/src/projections/reactive.ts @@ -49,9 +49,6 @@ * }); * ``` * - * @architect - * @architect-implements ReactiveProjections - * @architect-status completed */ import { isViewProjection, type ProjectionCategory } from "@libar-dev/platform-bc"; diff --git a/packages/platform-core/src/projections/replay/index.ts b/packages/platform-core/src/projections/replay/index.ts index 5c10fd44..abb90f92 100644 --- a/packages/platform-core/src/projections/replay/index.ts +++ b/packages/platform-core/src/projections/replay/index.ts @@ -3,8 +3,6 @@ * * Provides checkpoint-based replay for projection recovery and schema migration. * - * @architect - * @architect-implements EventReplayInfrastructure */ // Types diff --git a/packages/platform-core/src/projections/replay/progress.ts b/packages/platform-core/src/projections/replay/progress.ts index ed8e3ed1..4cd4d21a 100644 --- a/packages/platform-core/src/projections/replay/progress.ts +++ b/packages/platform-core/src/projections/replay/progress.ts @@ -1,8 +1,4 @@ /** - * @architect - * @architect-implements EventReplayInfrastructure - * @architect-status completed - * * ## Replay Progress Utilities * * Progress calculation utilities for replay operations. diff --git a/packages/platform-core/src/projections/replay/types.ts b/packages/platform-core/src/projections/replay/types.ts index fe7f72ed..2317e8d6 100644 --- a/packages/platform-core/src/projections/replay/types.ts +++ b/packages/platform-core/src/projections/replay/types.ts @@ -1,8 +1,4 @@ /** - * @architect - * @architect-implements EventReplayInfrastructure - * @architect-status completed - * * ## Event Replay Infrastructure Types * * Types for event replay and projection rebuilding. diff --git a/packages/platform-core/src/projections/withCheckpoint.ts b/packages/platform-core/src/projections/withCheckpoint.ts index 077b5e3a..29a7e4c6 100644 --- a/packages/platform-core/src/projections/withCheckpoint.ts +++ b/packages/platform-core/src/projections/withCheckpoint.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern ProjectionCheckpointing - * @architect-status completed - * @architect-phase 04 - * @architect-projection - * * ## Projection Checkpointing - Idempotent Processing * * Projection checkpoint helper for idempotent event processing. diff --git a/packages/platform-core/src/queries/factory.ts b/packages/platform-core/src/queries/factory.ts index 0b7310e5..269adb39 100644 --- a/packages/platform-core/src/queries/factory.ts +++ b/packages/platform-core/src/queries/factory.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern QueryAbstraction - * @architect-status completed - * @architect-phase 12 - * @architect-cqrs - * * ## Query Abstraction - Read Model Factories * * Query factory functions for creating type-safe read model queries. diff --git a/packages/platform-core/src/repository/CMSRepository.ts b/packages/platform-core/src/repository/CMSRepository.ts index e89a904a..62ff3d2e 100644 --- a/packages/platform-core/src/repository/CMSRepository.ts +++ b/packages/platform-core/src/repository/CMSRepository.ts @@ -1,11 +1,4 @@ /** - * @architect - * @architect-pattern CMSRepository - * @architect-status completed - * @architect-phase 11 - * @architect-uses CMSDualWrite - * @architect-used-by BoundedContextHandlers - * * ## CMS Repository - Entity Access with Auto-Upcast * * Factory for typed data access with automatic schema upcasting in dual-write handlers. diff --git a/packages/platform-core/src/workpool/partitioning/complexity.ts b/packages/platform-core/src/workpool/partitioning/complexity.ts index 0824791a..16d6abf2 100644 --- a/packages/platform-core/src/workpool/partitioning/complexity.ts +++ b/packages/platform-core/src/workpool/partitioning/complexity.ts @@ -1,9 +1,4 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status completed - * @architect-projection - * * ## Projection Complexity Classifier * * Analyzes projection characteristics and recommends appropriate diff --git a/packages/platform-core/src/workpool/partitioning/config.ts b/packages/platform-core/src/workpool/partitioning/config.ts index 55298259..9ce86e95 100644 --- a/packages/platform-core/src/workpool/partitioning/config.ts +++ b/packages/platform-core/src/workpool/partitioning/config.ts @@ -1,9 +1,4 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status completed - * @architect-projection - * * ## Per-Projection Partition Configuration * * Defines configuration types and constants for projection partitioning diff --git a/packages/platform-core/src/workpool/partitioning/helpers.ts b/packages/platform-core/src/workpool/partitioning/helpers.ts index 52b3cf25..0bb5772f 100644 --- a/packages/platform-core/src/workpool/partitioning/helpers.ts +++ b/packages/platform-core/src/workpool/partitioning/helpers.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status completed - * @architect-projection - * - * @architect-uses EventBusAbstraction - * @architect-used-by CommandOrchestrator, Projections, DCBRetry - * @architect-usecase "When creating partition keys for Workpool-based event processing" - * * ## Partition Key Helper Functions * * Standardized partition key generation for per-entity event ordering diff --git a/packages/platform-core/src/workpool/partitioning/index.ts b/packages/platform-core/src/workpool/partitioning/index.ts index 8a7aed99..da3413fe 100644 --- a/packages/platform-core/src/workpool/partitioning/index.ts +++ b/packages/platform-core/src/workpool/partitioning/index.ts @@ -1,9 +1,4 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status completed - * @architect-projection - * * ## Workpool Partitioning Strategy * * Standardized partition key patterns for event ordering and OCC prevention diff --git a/packages/platform-core/src/workpool/partitioning/types.ts b/packages/platform-core/src/workpool/partitioning/types.ts index 7a518caa..f4647f30 100644 --- a/packages/platform-core/src/workpool/partitioning/types.ts +++ b/packages/platform-core/src/workpool/partitioning/types.ts @@ -1,13 +1,4 @@ /** - * @architect - * @architect-implements WorkpoolPartitioningStrategy - * @architect-status completed - * @architect-projection - * - * @architect-uses EventBusAbstraction - * @architect-used-by CommandOrchestrator, Projections, DCBRetry - * @architect-usecase "When configuring partition keys for Workpool-based event processing" - * * ## Workpool Partition Key Types * * Provides type definitions for partition key strategies that ensure diff --git a/packages/platform-core/tests/features/behavior/agent/audit-trail.feature b/packages/platform-core/tests/features/behavior/agent/audit-trail.feature index d0eb3ef0..a5b73f04 100644 --- a/packages/platform-core/tests/features/behavior/agent/audit-trail.feature +++ b/packages/platform-core/tests/features/behavior/agent/audit-trail.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:AgentAsBoundedContext -@architect-phase:22 -@architect-product-area:Platform @agent Feature: Agent Audit Trail diff --git a/packages/platform-core/tests/features/behavior/agent/command-emission.feature b/packages/platform-core/tests/features/behavior/agent/command-emission.feature index 3eb2d91a..014b3a71 100644 --- a/packages/platform-core/tests/features/behavior/agent/command-emission.feature +++ b/packages/platform-core/tests/features/behavior/agent/command-emission.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:AgentAsBoundedContext -@architect-phase:22 -@architect-product-area:Platform @agent Feature: Agent Command Emission diff --git a/packages/platform-core/tests/features/behavior/agent/event-subscription.feature b/packages/platform-core/tests/features/behavior/agent/event-subscription.feature index b24bdafc..780111cf 100644 --- a/packages/platform-core/tests/features/behavior/agent/event-subscription.feature +++ b/packages/platform-core/tests/features/behavior/agent/event-subscription.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:AgentAsBoundedContext -@architect-phase:22 -@architect-product-area:Platform @agent Feature: Agent Event Subscription diff --git a/packages/platform-core/tests/features/behavior/agent/human-in-loop.feature b/packages/platform-core/tests/features/behavior/agent/human-in-loop.feature index ac7b4bf1..40af2394 100644 --- a/packages/platform-core/tests/features/behavior/agent/human-in-loop.feature +++ b/packages/platform-core/tests/features/behavior/agent/human-in-loop.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:AgentAsBoundedContext -@architect-phase:22 -@architect-product-area:Platform @agent Feature: Human-in-Loop Configuration diff --git a/packages/platform-core/tests/features/behavior/agent/pattern-detection.feature b/packages/platform-core/tests/features/behavior/agent/pattern-detection.feature index c3fbd832..5a202af9 100644 --- a/packages/platform-core/tests/features/behavior/agent/pattern-detection.feature +++ b/packages/platform-core/tests/features/behavior/agent/pattern-detection.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:AgentAsBoundedContext -@architect-phase:22 -@architect-product-area:Platform @agent Feature: Agent Pattern Detection diff --git a/packages/platform-core/tests/features/behavior/dcb/execute.feature b/packages/platform-core/tests/features/behavior/dcb/execute.feature index 51dcb344..6fbad715 100644 --- a/packages/platform-core/tests/features/behavior/dcb/execute.feature +++ b/packages/platform-core/tests/features/behavior/dcb/execute.feature @@ -1,7 +1,3 @@ -@architect-implements:DynamicConsistencyBoundaries -@architect-status:active -@architect-phase:16 -@architect-product-area:PlatformCore Feature: DCB Execution with OCC As a platform developer diff --git a/packages/platform-core/tests/features/behavior/dcb/scope-key.feature b/packages/platform-core/tests/features/behavior/dcb/scope-key.feature index a0989a5c..014a9488 100644 --- a/packages/platform-core/tests/features/behavior/dcb/scope-key.feature +++ b/packages/platform-core/tests/features/behavior/dcb/scope-key.feature @@ -1,7 +1,3 @@ -@architect-implements:DynamicConsistencyBoundaries -@architect-status:active -@architect-phase:16 -@architect-product-area:PlatformCore Feature: DCB Scope Key Utilities As a platform developer diff --git a/packages/platform-core/tests/features/behavior/durable-function-adapters/dcb-conflict-retry.feature b/packages/platform-core/tests/features/behavior/durable-function-adapters/dcb-conflict-retry.feature index 2a405fba..d00c6863 100644 --- a/packages/platform-core/tests/features/behavior/durable-function-adapters/dcb-conflict-retry.feature +++ b/packages/platform-core/tests/features/behavior/durable-function-adapters/dcb-conflict-retry.feature @@ -1,7 +1,3 @@ -@architect-implements:DurableFunctionAdapters -@architect-status:active -@architect-phase:18a -@architect-product-area:Platform @acceptance-criteria Feature: DCB Conflict Retry diff --git a/packages/platform-core/tests/features/behavior/durable-function-adapters/integration-patterns.feature b/packages/platform-core/tests/features/behavior/durable-function-adapters/integration-patterns.feature index 32edcac9..faaf5927 100644 --- a/packages/platform-core/tests/features/behavior/durable-function-adapters/integration-patterns.feature +++ b/packages/platform-core/tests/features/behavior/durable-function-adapters/integration-patterns.feature @@ -1,7 +1,3 @@ -@architect-implements:DurableFunctionAdapters -@architect-status:active -@architect-phase:18a -@architect-product-area:Platform @acceptance-criteria Feature: Adapter Integration Patterns diff --git a/packages/platform-core/tests/features/behavior/durable-function-adapters/rate-limit-adapter.feature b/packages/platform-core/tests/features/behavior/durable-function-adapters/rate-limit-adapter.feature index 8ee2de28..ec2ffe06 100644 --- a/packages/platform-core/tests/features/behavior/durable-function-adapters/rate-limit-adapter.feature +++ b/packages/platform-core/tests/features/behavior/durable-function-adapters/rate-limit-adapter.feature @@ -1,7 +1,3 @@ -@architect-implements:DurableFunctionAdapters -@architect-status:active -@architect-phase:18a -@architect-product-area:Platform @acceptance-criteria Feature: Rate Limit Adapter diff --git a/packages/platform-core/tests/features/behavior/ecst/fat-event-builder.feature b/packages/platform-core/tests/features/behavior/ecst/fat-event-builder.feature index 19391a8f..40da52ac 100644 --- a/packages/platform-core/tests/features/behavior/ecst/fat-event-builder.feature +++ b/packages/platform-core/tests/features/behavior/ecst/fat-event-builder.feature @@ -1,9 +1,3 @@ -@architect -@architect-status:completed -@architect-unlock-reason:Initial-implementation-complete -@architect-implements:EcstFatEvents -@architect-phase:20 -@architect-product-area:PlatformCore @ecst Feature: Fat Event Builder diff --git a/packages/platform-core/tests/features/behavior/ecst/fat-vs-thin-selection.feature b/packages/platform-core/tests/features/behavior/ecst/fat-vs-thin-selection.feature index 5867ab6c..f1a48942 100644 --- a/packages/platform-core/tests/features/behavior/ecst/fat-vs-thin-selection.feature +++ b/packages/platform-core/tests/features/behavior/ecst/fat-vs-thin-selection.feature @@ -1,9 +1,3 @@ -@architect -@architect-status:completed -@architect-unlock-reason:Initial-implementation-complete -@architect-implements:EcstFatEvents -@architect-phase:20 -@architect-product-area:PlatformCore @ecst Feature: Fat vs Thin Event Selection diff --git a/packages/platform-core/tests/features/behavior/ecst/privacy-markers.feature b/packages/platform-core/tests/features/behavior/ecst/privacy-markers.feature index 095d187b..0f3c9b97 100644 --- a/packages/platform-core/tests/features/behavior/ecst/privacy-markers.feature +++ b/packages/platform-core/tests/features/behavior/ecst/privacy-markers.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:completed -@architect-implements:EcstFatEvents -@architect-phase:20 -@architect-product-area:PlatformCore @ecst @gdpr Feature: Privacy Markers (Crypto-Shredding) diff --git a/packages/platform-core/tests/features/behavior/ecst/schema-versioning.feature b/packages/platform-core/tests/features/behavior/ecst/schema-versioning.feature index 87228ea1..583e3454 100644 --- a/packages/platform-core/tests/features/behavior/ecst/schema-versioning.feature +++ b/packages/platform-core/tests/features/behavior/ecst/schema-versioning.feature @@ -1,9 +1,3 @@ -@architect -@architect-status:completed -@architect-unlock-reason:Initial-implementation-complete -@architect-implements:EcstFatEvents -@architect-phase:20 -@architect-product-area:PlatformCore @ecst Feature: Schema Versioning diff --git a/packages/platform-core/tests/features/behavior/event-replay/replay-progress.feature b/packages/platform-core/tests/features/behavior/event-replay/replay-progress.feature index e81d85b9..292604e7 100644 --- a/packages/platform-core/tests/features/behavior/event-replay/replay-progress.feature +++ b/packages/platform-core/tests/features/behavior/event-replay/replay-progress.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventReplayInfrastructure @acceptance-criteria Feature: Replay Progress Calculator diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/durable-append.feature b/packages/platform-core/tests/features/behavior/event-store-durability/durable-append.feature index c8c62a61..adb63224 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/durable-append.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/durable-append.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Durable Event Append diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/durable-publication.feature b/packages/platform-core/tests/features/behavior/event-store-durability/durable-publication.feature index 1c000954..7f4d66e6 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/durable-publication.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/durable-publication.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Durable Cross-Context Event Publication diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/idempotent-append.feature b/packages/platform-core/tests/features/behavior/event-store-durability/idempotent-append.feature index 4914ae89..ca338915 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/idempotent-append.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/idempotent-append.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Idempotent Event Append diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/intent-completion.feature b/packages/platform-core/tests/features/behavior/event-store-durability/intent-completion.feature index 96ada51d..f6240a76 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/intent-completion.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/intent-completion.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Intent and Completion Bracketing diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/outbox-handler.feature b/packages/platform-core/tests/features/behavior/event-store-durability/outbox-handler.feature index 633879d6..1905fdc8 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/outbox-handler.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/outbox-handler.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Outbox Handler Pattern diff --git a/packages/platform-core/tests/features/behavior/event-store-durability/poison-event.feature b/packages/platform-core/tests/features/behavior/event-store-durability/poison-event.feature index 88b1e525..8367338e 100644 --- a/packages/platform-core/tests/features/behavior/event-store-durability/poison-event.feature +++ b/packages/platform-core/tests/features/behavior/event-store-durability/poison-event.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:EventStoreDurability @acceptance-criteria Feature: Poison Event Handling diff --git a/packages/platform-core/tests/features/behavior/fsm/fsm.feature b/packages/platform-core/tests/features/behavior/fsm/fsm.feature index 68fe72ce..e14589ff 100644 --- a/packages/platform-core/tests/features/behavior/fsm/fsm.feature +++ b/packages/platform-core/tests/features/behavior/fsm/fsm.feature @@ -1,4 +1,3 @@ -@architect Feature: FSM Core As a platform developer diff --git a/packages/platform-core/tests/features/behavior/integration/anti-corruption-layer.feature b/packages/platform-core/tests/features/behavior/integration/anti-corruption-layer.feature index ce3a25dd..c65549f5 100644 --- a/packages/platform-core/tests/features/behavior/integration/anti-corruption-layer.feature +++ b/packages/platform-core/tests/features/behavior/integration/anti-corruption-layer.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:roadmap -@architect-implements:IntegrationPatterns21a -@architect-phase:21 -@architect-product-area:PlatformCore @integration Feature: Anti-Corruption Layer (ACL) diff --git a/packages/platform-core/tests/features/behavior/integration/context-map.feature b/packages/platform-core/tests/features/behavior/integration/context-map.feature index 8a143411..c2cf7866 100644 --- a/packages/platform-core/tests/features/behavior/integration/context-map.feature +++ b/packages/platform-core/tests/features/behavior/integration/context-map.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:roadmap -@architect-implements:IntegrationPatterns21a -@architect-phase:21 -@architect-product-area:PlatformCore @integration Feature: Context Map Documentation diff --git a/packages/platform-core/tests/features/behavior/integration/contract-testing.feature b/packages/platform-core/tests/features/behavior/integration/contract-testing.feature index 5517f0c4..cf4a1112 100644 --- a/packages/platform-core/tests/features/behavior/integration/contract-testing.feature +++ b/packages/platform-core/tests/features/behavior/integration/contract-testing.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:roadmap -@architect-implements:IntegrationPatterns21b -@architect-phase:21 -@architect-product-area:PlatformCore @integration Feature: Contract Testing Utilities diff --git a/packages/platform-core/tests/features/behavior/integration/event-versioning.feature b/packages/platform-core/tests/features/behavior/integration/event-versioning.feature index ebdf2ba1..4c45c0a2 100644 --- a/packages/platform-core/tests/features/behavior/integration/event-versioning.feature +++ b/packages/platform-core/tests/features/behavior/integration/event-versioning.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:roadmap -@architect-implements:IntegrationPatterns21b -@architect-phase:21 -@architect-product-area:PlatformCore @integration Feature: Integration Event Versioning diff --git a/packages/platform-core/tests/features/behavior/integration/published-language.feature b/packages/platform-core/tests/features/behavior/integration/published-language.feature index e0084e40..a10ffbb2 100644 --- a/packages/platform-core/tests/features/behavior/integration/published-language.feature +++ b/packages/platform-core/tests/features/behavior/integration/published-language.feature @@ -1,8 +1,3 @@ -@architect -@architect-status:roadmap -@architect-implements:IntegrationPatterns21a -@architect-phase:21 -@architect-product-area:PlatformCore @integration Feature: Published Language Registry diff --git a/packages/platform-core/tests/features/behavior/invariants/create-invariant-set.feature b/packages/platform-core/tests/features/behavior/invariants/create-invariant-set.feature index f14d8df7..198be5c9 100644 --- a/packages/platform-core/tests/features/behavior/invariants/create-invariant-set.feature +++ b/packages/platform-core/tests/features/behavior/invariants/create-invariant-set.feature @@ -1,4 +1,3 @@ -@architect @invariants Feature: createInvariantSet diff --git a/packages/platform-core/tests/features/behavior/invariants/create-invariant.feature b/packages/platform-core/tests/features/behavior/invariants/create-invariant.feature index 58fa1797..c74fed9b 100644 --- a/packages/platform-core/tests/features/behavior/invariants/create-invariant.feature +++ b/packages/platform-core/tests/features/behavior/invariants/create-invariant.feature @@ -1,4 +1,3 @@ -@architect @invariants Feature: createInvariant diff --git a/packages/platform-core/tests/features/behavior/invariants/invariant-error.feature b/packages/platform-core/tests/features/behavior/invariants/invariant-error.feature index 2eeaf24c..34617042 100644 --- a/packages/platform-core/tests/features/behavior/invariants/invariant-error.feature +++ b/packages/platform-core/tests/features/behavior/invariants/invariant-error.feature @@ -1,4 +1,3 @@ -@architect @invariants Feature: InvariantError diff --git a/packages/platform-core/tests/features/behavior/logging/commands.feature b/packages/platform-core/tests/features/behavior/logging/commands.feature index ab745261..035d016f 100644 --- a/packages/platform-core/tests/features/behavior/logging/commands.feature +++ b/packages/platform-core/tests/features/behavior/logging/commands.feature @@ -1,4 +1,3 @@ -@architect Feature: Command Logging Helpers As a platform developer diff --git a/packages/platform-core/tests/features/behavior/logging/scoped.feature b/packages/platform-core/tests/features/behavior/logging/scoped.feature index 891bdf9d..ca33137f 100644 --- a/packages/platform-core/tests/features/behavior/logging/scoped.feature +++ b/packages/platform-core/tests/features/behavior/logging/scoped.feature @@ -1,4 +1,3 @@ -@architect Feature: Scoped Logger As a platform developer diff --git a/packages/platform-core/tests/features/behavior/logging/testing.feature b/packages/platform-core/tests/features/behavior/logging/testing.feature index a2c6778b..ccdcc8f5 100644 --- a/packages/platform-core/tests/features/behavior/logging/testing.feature +++ b/packages/platform-core/tests/features/behavior/logging/testing.feature @@ -1,4 +1,3 @@ -@architect Feature: Logging Testing Utilities As a platform developer diff --git a/packages/platform-core/tests/features/behavior/logging/types.feature b/packages/platform-core/tests/features/behavior/logging/types.feature index 7a144107..a67a924e 100644 --- a/packages/platform-core/tests/features/behavior/logging/types.feature +++ b/packages/platform-core/tests/features/behavior/logging/types.feature @@ -1,4 +1,3 @@ -@architect Feature: Logging Types As a platform developer diff --git a/packages/platform-core/tests/features/behavior/monitoring/circuit-breaker.feature b/packages/platform-core/tests/features/behavior/monitoring/circuit-breaker.feature index c4e024c4..32fef85f 100644 --- a/packages/platform-core/tests/features/behavior/monitoring/circuit-breaker.feature +++ b/packages/platform-core/tests/features/behavior/monitoring/circuit-breaker.feature @@ -1,4 +1,3 @@ -@architect Feature: Circuit Breaker As a platform developer diff --git a/packages/platform-core/tests/features/behavior/orchestration/saga-orchestration-executable-tests.feature b/packages/platform-core/tests/features/behavior/orchestration/saga-orchestration-executable-tests.feature index ea9b1cf4..78d30fab 100644 --- a/packages/platform-core/tests/features/behavior/orchestration/saga-orchestration-executable-tests.feature +++ b/packages/platform-core/tests/features/behavior/orchestration/saga-orchestration-executable-tests.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:SagaOrchestrationExecutableTests -@architect-implements:SagaOrchestration -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-product-area:Platform Feature: SagaOrchestration Executable Tests **Provenance:** This file was authored under the refactoring carve-out diff --git a/packages/platform-core/tests/features/behavior/processManager/executor.feature b/packages/platform-core/tests/features/behavior/processManager/executor.feature index 0711f750..5b1e4277 100644 --- a/packages/platform-core/tests/features/behavior/processManager/executor.feature +++ b/packages/platform-core/tests/features/behavior/processManager/executor.feature @@ -1,4 +1,3 @@ -@architect Feature: Process Manager Executor As a platform developer diff --git a/packages/platform-core/tests/features/behavior/processManager/lifecycle.feature b/packages/platform-core/tests/features/behavior/processManager/lifecycle.feature index 1109a8a9..6ad74c3d 100644 --- a/packages/platform-core/tests/features/behavior/processManager/lifecycle.feature +++ b/packages/platform-core/tests/features/behavior/processManager/lifecycle.feature @@ -1,4 +1,3 @@ -@architect Feature: Process Manager Lifecycle State Machine As a platform developer diff --git a/packages/platform-core/tests/features/behavior/processManager/registry.feature b/packages/platform-core/tests/features/behavior/processManager/registry.feature index 50e0974b..56903294 100644 --- a/packages/platform-core/tests/features/behavior/processManager/registry.feature +++ b/packages/platform-core/tests/features/behavior/processManager/registry.feature @@ -1,4 +1,3 @@ -@architect Feature: Process Manager Registry As a platform developer diff --git a/packages/platform-core/tests/features/behavior/processManager/subscription.feature b/packages/platform-core/tests/features/behavior/processManager/subscription.feature index 17accf22..4cda162e 100644 --- a/packages/platform-core/tests/features/behavior/processManager/subscription.feature +++ b/packages/platform-core/tests/features/behavior/processManager/subscription.feature @@ -1,4 +1,3 @@ -@architect Feature: Process Manager EventBus Subscription As a platform developer diff --git a/packages/platform-core/tests/features/behavior/processManager/types.feature b/packages/platform-core/tests/features/behavior/processManager/types.feature index e4638484..7003235f 100644 --- a/packages/platform-core/tests/features/behavior/processManager/types.feature +++ b/packages/platform-core/tests/features/behavior/processManager/types.feature @@ -1,4 +1,3 @@ -@architect Feature: Process Manager Types As a platform developer diff --git a/packages/platform-core/tests/features/behavior/production-hardening/admin-tooling.feature b/packages/platform-core/tests/features/behavior/production-hardening/admin-tooling.feature index e85c1012..4b177cd3 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/admin-tooling.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/admin-tooling.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Admin Tooling - Operational Tasks As a platform operator diff --git a/packages/platform-core/tests/features/behavior/production-hardening/circuit-breakers.feature b/packages/platform-core/tests/features/behavior/production-hardening/circuit-breakers.feature index 78811fcb..c0f269dc 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/circuit-breakers.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/circuit-breakers.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Circuit Breakers - Fault Isolation As a platform developer diff --git a/packages/platform-core/tests/features/behavior/production-hardening/distributed-tracing.feature b/packages/platform-core/tests/features/behavior/production-hardening/distributed-tracing.feature index 14cedd3d..c852b616 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/distributed-tracing.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/distributed-tracing.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Distributed Tracing - Event Flow Visualization As a platform operator diff --git a/packages/platform-core/tests/features/behavior/production-hardening/durable-function-integration.feature b/packages/platform-core/tests/features/behavior/production-hardening/durable-function-integration.feature index 967b7242..a0581ff2 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/durable-function-integration.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/durable-function-integration.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Durable Function Integration - Reliable Execution Patterns As a platform developer diff --git a/packages/platform-core/tests/features/behavior/production-hardening/health-endpoints.feature b/packages/platform-core/tests/features/behavior/production-hardening/health-endpoints.feature index ec394816..0800d114 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/health-endpoints.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/health-endpoints.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Health Endpoints - Kubernetes Probes As a Kubernetes operator diff --git a/packages/platform-core/tests/features/behavior/production-hardening/metrics-collection.feature b/packages/platform-core/tests/features/behavior/production-hardening/metrics-collection.feature index 13207587..012d2e1f 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/metrics-collection.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/metrics-collection.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Metrics Collection - System Health Tracking As a platform operator diff --git a/packages/platform-core/tests/features/behavior/production-hardening/rate-limiting.feature b/packages/platform-core/tests/features/behavior/production-hardening/rate-limiting.feature index d85d05aa..e84db46f 100644 --- a/packages/platform-core/tests/features/behavior/production-hardening/rate-limiting.feature +++ b/packages/platform-core/tests/features/behavior/production-hardening/rate-limiting.feature @@ -1,9 +1,4 @@ -@architect -@architect-implements:ProductionHardening @acceptance-criteria -@architect-status:roadmap -@architect-phase:18 -@architect-product-area:Platform Feature: Rate Limiting - API Protection As a platform developer diff --git a/packages/platform-core/tests/features/behavior/projection-categories/category-definitions.feature b/packages/platform-core/tests/features/behavior/projection-categories/category-definitions.feature index 3b1f6054..02f8d841 100644 --- a/packages/platform-core/tests/features/behavior/projection-categories/category-definitions.feature +++ b/packages/platform-core/tests/features/behavior/projection-categories/category-definitions.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:ProjectionCategoriesExecutableTests -@architect-implements:ProjectionCategories -@architect-status:active -@architect-phase:15 -@architect-product-area:PlatformCore Feature: Projection Category Definitions As a platform developer diff --git a/packages/platform-core/tests/features/behavior/projection-categories/explicit-declaration.feature b/packages/platform-core/tests/features/behavior/projection-categories/explicit-declaration.feature index cd4127ba..1026cd1a 100644 --- a/packages/platform-core/tests/features/behavior/projection-categories/explicit-declaration.feature +++ b/packages/platform-core/tests/features/behavior/projection-categories/explicit-declaration.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:ProjectionCategoriesExecutableTests -@architect-implements:ProjectionCategories -@architect-status:active -@architect-phase:15 -@architect-product-area:PlatformCore Feature: Explicit Category Declaration As a platform developer diff --git a/packages/platform-core/tests/features/behavior/projection-categories/registry-lookup.feature b/packages/platform-core/tests/features/behavior/projection-categories/registry-lookup.feature index 749fcfda..6ef25c8c 100644 --- a/packages/platform-core/tests/features/behavior/projection-categories/registry-lookup.feature +++ b/packages/platform-core/tests/features/behavior/projection-categories/registry-lookup.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:ProjectionCategoriesExecutableTests -@architect-implements:ProjectionCategories -@architect-status:active -@architect-phase:15 -@architect-product-area:PlatformCore Feature: Registry Category Lookup As a platform developer diff --git a/packages/platform-core/tests/features/behavior/projections/lifecycle.feature b/packages/platform-core/tests/features/behavior/projections/lifecycle.feature index 84708977..49bedae3 100644 --- a/packages/platform-core/tests/features/behavior/projections/lifecycle.feature +++ b/packages/platform-core/tests/features/behavior/projections/lifecycle.feature @@ -1,4 +1,3 @@ -@architect Feature: Projection Lifecycle State Machine As a platform developer diff --git a/packages/platform-core/tests/features/behavior/reactive-projections/conflict-detection.feature b/packages/platform-core/tests/features/behavior/reactive-projections/conflict-detection.feature index a2f8f436..7cc577cb 100644 --- a/packages/platform-core/tests/features/behavior/reactive-projections/conflict-detection.feature +++ b/packages/platform-core/tests/features/behavior/reactive-projections/conflict-detection.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:ReactiveProjectionConflictDetection -@architect-implements:ReactiveProjections -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:17 -@architect-product-area:Platform @acceptance-criteria Feature: Conflict Detection and Rollback diff --git a/packages/platform-core/tests/features/behavior/reactive-projections/hybrid-model.feature b/packages/platform-core/tests/features/behavior/reactive-projections/hybrid-model.feature index b299b489..9c31724c 100644 --- a/packages/platform-core/tests/features/behavior/reactive-projections/hybrid-model.feature +++ b/packages/platform-core/tests/features/behavior/reactive-projections/hybrid-model.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:ReactiveProjectionHybridModel -@architect-implements:ReactiveProjections -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:17 -@architect-product-area:Platform @acceptance-criteria Feature: Hybrid Model - Durable + Reactive Projections diff --git a/packages/platform-core/tests/features/behavior/reactive-projections/reactive-eligibility.feature b/packages/platform-core/tests/features/behavior/reactive-projections/reactive-eligibility.feature index 67a72d10..d5231391 100644 --- a/packages/platform-core/tests/features/behavior/reactive-projections/reactive-eligibility.feature +++ b/packages/platform-core/tests/features/behavior/reactive-projections/reactive-eligibility.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:ReactiveProjectionEligibility -@architect-implements:ReactiveProjections -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:17 -@architect-product-area:Platform @acceptance-criteria Feature: Reactive Eligibility by Category diff --git a/packages/platform-core/tests/features/behavior/reactive-projections/shared-evolve.feature b/packages/platform-core/tests/features/behavior/reactive-projections/shared-evolve.feature index 080f80b0..cce262d5 100644 --- a/packages/platform-core/tests/features/behavior/reactive-projections/shared-evolve.feature +++ b/packages/platform-core/tests/features/behavior/reactive-projections/shared-evolve.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:ReactiveProjectionSharedEvolve -@architect-implements:ReactiveProjections -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:17 -@architect-product-area:Platform @acceptance-criteria Feature: Shared Evolve Logic - Client/Server Consistency diff --git a/packages/platform-core/tests/features/behavior/reservation/confirm-operation.feature b/packages/platform-core/tests/features/behavior/reservation/confirm-operation.feature index 55286b8b..05507457 100644 --- a/packages/platform-core/tests/features/behavior/reservation/confirm-operation.feature +++ b/packages/platform-core/tests/features/behavior/reservation/confirm-operation.feature @@ -1,8 +1,3 @@ -@architect -@architect-implements:ReservationPattern -@architect-status:active -@architect-phase:20 -@architect-product-area:PlatformCore @reservation Feature: Confirm Operation diff --git a/packages/platform-core/tests/features/behavior/reservation/release-operation.feature b/packages/platform-core/tests/features/behavior/reservation/release-operation.feature index 5ad25c44..70ebf564 100644 --- a/packages/platform-core/tests/features/behavior/reservation/release-operation.feature +++ b/packages/platform-core/tests/features/behavior/reservation/release-operation.feature @@ -1,8 +1,3 @@ -@architect -@architect-implements:ReservationPattern -@architect-status:active -@architect-phase:20 -@architect-product-area:PlatformCore @reservation Feature: Release Operation diff --git a/packages/platform-core/tests/features/behavior/reservation/reservation-key.feature b/packages/platform-core/tests/features/behavior/reservation/reservation-key.feature index 9a278887..10e78f8d 100644 --- a/packages/platform-core/tests/features/behavior/reservation/reservation-key.feature +++ b/packages/platform-core/tests/features/behavior/reservation/reservation-key.feature @@ -1,8 +1,3 @@ -@architect -@architect-implements:ReservationPattern -@architect-status:active -@architect-phase:20 -@architect-product-area:PlatformCore @reservation Feature: Reservation Key Format diff --git a/packages/platform-core/tests/features/behavior/reservation/reserve-operation.feature b/packages/platform-core/tests/features/behavior/reservation/reserve-operation.feature index a1deebc3..3a1c69d0 100644 --- a/packages/platform-core/tests/features/behavior/reservation/reserve-operation.feature +++ b/packages/platform-core/tests/features/behavior/reservation/reserve-operation.feature @@ -1,8 +1,3 @@ -@architect -@architect-implements:ReservationPattern -@architect-status:active -@architect-phase:20 -@architect-product-area:PlatformCore @reservation Feature: Reserve Operation diff --git a/packages/platform-core/tests/features/behavior/testing/guards.feature b/packages/platform-core/tests/features/behavior/testing/guards.feature index b149bd69..fe688296 100644 --- a/packages/platform-core/tests/features/behavior/testing/guards.feature +++ b/packages/platform-core/tests/features/behavior/testing/guards.feature @@ -1,17 +1,4 @@ -@architect -@architect-pattern:TestEnvironmentGuards -@architect-implements:BddTestingInfrastructure @testing-infrastructure -@architect-status:completed -@architect-unlock-reason:Task-3-branch-wide-remediation-guard-unblock -@architect-phase:58 -@architect-quarter:Q1-2026 -@architect-effort:1h -@architect-effort-actual:1h -@architect-completed:2026-01-08 -@architect-product-area:PlatformCore -@architect-business-value:prevent-test-utilities-in-production -@architect-priority:high Feature: Test Environment Guards As a platform developer diff --git a/packages/platform-core/tests/features/behavior/testing/integration-isolation.feature b/packages/platform-core/tests/features/behavior/testing/integration-isolation.feature index 07149e93..b35a0c71 100644 --- a/packages/platform-core/tests/features/behavior/testing/integration-isolation.feature +++ b/packages/platform-core/tests/features/behavior/testing/integration-isolation.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:BddTestingInfrastructureExecutableTests -@architect-implements:BddTestingInfrastructure -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-phase:19 -@architect-product-area:PlatformCore @testing-infrastructure Feature: Integration Test Isolation diff --git a/packages/platform-core/tests/features/behavior/testing/platform-coverage.feature b/packages/platform-core/tests/features/behavior/testing/platform-coverage.feature index 8b276153..4f05eeb6 100644 --- a/packages/platform-core/tests/features/behavior/testing/platform-coverage.feature +++ b/packages/platform-core/tests/features/behavior/testing/platform-coverage.feature @@ -1,10 +1,3 @@ -@architect -@architect-pattern:BddTestingInfrastructureExecutableTests -@architect-implements:BddTestingInfrastructure -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-phase:19 -@architect-product-area:PlatformCore @testing-infrastructure Feature: Platform Package BDD Coverage diff --git a/packages/platform-core/tests/features/behavior/testing/polling.feature b/packages/platform-core/tests/features/behavior/testing/polling.feature index 73c93c36..57d05c24 100644 --- a/packages/platform-core/tests/features/behavior/testing/polling.feature +++ b/packages/platform-core/tests/features/behavior/testing/polling.feature @@ -1,17 +1,4 @@ -@architect -@architect-pattern:PollingUtilities -@architect-implements:BddTestingInfrastructure @testing-infrastructure -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:56 -@architect-quarter:Q1-2026 -@architect-effort:2h -@architect-effort-actual:2h -@architect-completed:2026-01-08 -@architect-product-area:PlatformCore -@architect-business-value:enable-async-condition-waiting-in-tests -@architect-priority:high Feature: Polling Utilities for Integration Tests As a developer writing integration tests diff --git a/packages/platform-core/tests/features/behavior/testing/world.feature b/packages/platform-core/tests/features/behavior/testing/world.feature index 640163fb..80aee7be 100644 --- a/packages/platform-core/tests/features/behavior/testing/world.feature +++ b/packages/platform-core/tests/features/behavior/testing/world.feature @@ -1,17 +1,4 @@ -@architect -@architect-pattern:BDDWorld -@architect-implements:BddTestingInfrastructure @testing-infrastructure -@architect-status:completed -@architect-unlock-reason:value-transfer-add-reverse-tags-and-enrich-rule-blocks-per-new-architect-doctrine -@architect-phase:57 -@architect-quarter:Q1-2026 -@architect-effort:2h -@architect-effort-actual:2h -@architect-completed:2026-01-08 -@architect-product-area:PlatformCore -@architect-business-value:manage-scenario-context-across-steps -@architect-priority:high Feature: BDD Test World State Management As a BDD test author diff --git a/packages/platform-core/tests/features/behavior/workpool-partitioning/complexity-classifier.feature b/packages/platform-core/tests/features/behavior/workpool-partitioning/complexity-classifier.feature index e1804540..bb9d4ff3 100644 --- a/packages/platform-core/tests/features/behavior/workpool-partitioning/complexity-classifier.feature +++ b/packages/platform-core/tests/features/behavior/workpool-partitioning/complexity-classifier.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:WorkpoolPartitioningStrategy Feature: Projection Complexity Classifier As a platform developer diff --git a/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-key-helpers.feature b/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-key-helpers.feature index f0055370..608c573b 100644 --- a/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-key-helpers.feature +++ b/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-key-helpers.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:WorkpoolPartitioningStrategy Feature: Workpool Partition Key Helpers As a platform developer diff --git a/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-validation.feature b/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-validation.feature index 7fe67e36..bf545538 100644 --- a/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-validation.feature +++ b/packages/platform-core/tests/features/behavior/workpool-partitioning/partition-validation.feature @@ -1,5 +1,3 @@ -@architect -@architect-implements:WorkpoolPartitioningStrategy Feature: Command Config Partition Key Validation As a platform developer diff --git a/packages/platform-core/tests/integration/durability/idempotent-append.integration.steps.ts b/packages/platform-core/tests/integration/durability/idempotent-append.integration.steps.ts index c3afdca7..77ba2cc2 100644 --- a/packages/platform-core/tests/integration/durability/idempotent-append.integration.steps.ts +++ b/packages/platform-core/tests/integration/durability/idempotent-append.integration.steps.ts @@ -4,10 +4,6 @@ * Integration test steps for validating idempotent event append * against a real Convex backend with the Event Store component. * - * @architect - * @architect-implements EventStoreDurability - * @architect-status active - * @architect-event-sourcing * * @since Phase 18b */ diff --git a/packages/platform-core/tests/integration/durability/poison-event.integration.steps.ts b/packages/platform-core/tests/integration/durability/poison-event.integration.steps.ts index b58d285a..8a2b54f8 100644 --- a/packages/platform-core/tests/integration/durability/poison-event.integration.steps.ts +++ b/packages/platform-core/tests/integration/durability/poison-event.integration.steps.ts @@ -4,10 +4,6 @@ * Integration test steps for validating poison event handling * against a real Convex backend with the poisonEvents table. * - * @architect - * @architect-implements EventStoreDurability - * @architect-status active - * @architect-event-sourcing * * @since Phase 18b */ diff --git a/packages/platform-core/tests/integration/durable-adapters/dcb-retry.integration.steps.ts b/packages/platform-core/tests/integration/durable-adapters/dcb-retry.integration.steps.ts index 388f381e..77615075 100644 --- a/packages/platform-core/tests/integration/durable-adapters/dcb-retry.integration.steps.ts +++ b/packages/platform-core/tests/integration/durable-adapters/dcb-retry.integration.steps.ts @@ -4,10 +4,6 @@ * Integration test steps for validating the withDCBRetry adapter * that handles OCC conflicts with automatic retry scheduling via Workpool. * - * @architect - * @architect-pattern DurableFunctionAdapters - * @architect-status active - * @architect-infra * * @since Phase 18a */ diff --git a/packages/platform-core/tests/integration/durable-adapters/integration-patterns.integration.steps.ts b/packages/platform-core/tests/integration/durable-adapters/integration-patterns.integration.steps.ts index 79cab9b3..fa8bc67e 100644 --- a/packages/platform-core/tests/integration/durable-adapters/integration-patterns.integration.steps.ts +++ b/packages/platform-core/tests/integration/durable-adapters/integration-patterns.integration.steps.ts @@ -4,10 +4,6 @@ * Integration tests for validating adapter integration with * middleware pipeline, Workpool infrastructure, and component mounting. * - * @architect - * @architect-pattern DurableFunctionAdapters - * @architect-status active - * @architect-infra * * @since Phase 18a */ diff --git a/packages/platform-core/tests/integration/durable-adapters/rate-limit.integration.steps.ts b/packages/platform-core/tests/integration/durable-adapters/rate-limit.integration.steps.ts index 54f514e4..ecb23a89 100644 --- a/packages/platform-core/tests/integration/durable-adapters/rate-limit.integration.steps.ts +++ b/packages/platform-core/tests/integration/durable-adapters/rate-limit.integration.steps.ts @@ -4,10 +4,6 @@ * Integration test steps for validating the ConvexRateLimitAdapter * that bridges the RateLimitChecker interface to @convex-dev/rate-limiter. * - * @architect - * @architect-pattern DurableFunctionAdapters - * @architect-status active - * @architect-infra */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-core/tests/planning-stubs/agent/agent.steps.ts b/packages/platform-core/tests/planning-stubs/agent/agent.steps.ts index 236b3742..147b73d3 100644 --- a/packages/platform-core/tests/planning-stubs/agent/agent.steps.ts +++ b/packages/platform-core/tests/planning-stubs/agent/agent.steps.ts @@ -1,8 +1,6 @@ /** * Agent as Bounded Context - Step Definitions (Stub) * - * @architect - * @architect-roadmap-spec AgentAsBoundedContext * * PLANNING ARTIFACT: Stub step definitions for Phase 22 Agent features. * Covers: event-subscription, pattern-detection, command-emission, human-in-loop, audit-trail diff --git a/packages/platform-core/tests/planning-stubs/integration/patterns.steps.ts b/packages/platform-core/tests/planning-stubs/integration/patterns.steps.ts index 4d47b3fc..8797092d 100644 --- a/packages/platform-core/tests/planning-stubs/integration/patterns.steps.ts +++ b/packages/platform-core/tests/planning-stubs/integration/patterns.steps.ts @@ -1,9 +1,6 @@ /** * Integration Patterns - Step Definitions (Stub) * - * @architect - * @architect-roadmap-spec IntegrationPatterns21a (context-map, published-language, anti-corruption-layer) - * @architect-roadmap-spec IntegrationPatterns21b (event-versioning, contract-testing) * * PLANNING ARTIFACT: Stub step definitions for Phase 21 Integration Patterns. * Split into two phases: diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/admin-tooling.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/admin-tooling.steps.ts index 8be1e68a..56d4ff79 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/admin-tooling.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/admin-tooling.steps.ts @@ -1,8 +1,6 @@ /** * Admin Tooling - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/circuit-breakers.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/circuit-breakers.steps.ts index 929a6228..e07c53b5 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/circuit-breakers.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/circuit-breakers.steps.ts @@ -1,8 +1,6 @@ /** * Circuit Breakers - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/distributed-tracing.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/distributed-tracing.steps.ts index 7c5f3aed..5925f885 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/distributed-tracing.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/distributed-tracing.steps.ts @@ -1,8 +1,6 @@ /** * Distributed Tracing - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/durable-function-integration.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/durable-function-integration.steps.ts index c408e441..e26a58e2 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/durable-function-integration.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/durable-function-integration.steps.ts @@ -1,8 +1,6 @@ /** * Durable Function Integration - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/health-endpoints.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/health-endpoints.steps.ts index 82a0a2a6..4eb4f5ba 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/health-endpoints.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/health-endpoints.steps.ts @@ -1,8 +1,6 @@ /** * Health Endpoints - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/metrics-collection.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/metrics-collection.steps.ts index 586c0078..a9c643fc 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/metrics-collection.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/metrics-collection.steps.ts @@ -1,8 +1,6 @@ /** * Metrics Collection - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/planning-stubs/production-hardening/rate-limiting.steps.ts b/packages/platform-core/tests/planning-stubs/production-hardening/rate-limiting.steps.ts index 5cd0315c..f3e67229 100644 --- a/packages/platform-core/tests/planning-stubs/production-hardening/rate-limiting.steps.ts +++ b/packages/platform-core/tests/planning-stubs/production-hardening/rate-limiting.steps.ts @@ -1,8 +1,6 @@ /** * Rate Limiting - Step Definitions Stub * - * @architect - * @architect-roadmap-spec ProductionHardening * * NOTE: This file is in tests/planning-stubs/ and excluded from vitest. * Move to tests/steps/monitoring/ during implementation. diff --git a/packages/platform-core/tests/steps/agent/agent.steps.ts b/packages/platform-core/tests/steps/agent/agent.steps.ts index 0c765297..c6c2b695 100644 --- a/packages/platform-core/tests/steps/agent/agent.steps.ts +++ b/packages/platform-core/tests/steps/agent/agent.steps.ts @@ -1,8 +1,6 @@ /** * Agent as Bounded Context - Step Definitions * - * @architect - * @architect-pattern AgentAsBoundedContext * * BDD step definitions for Phase 22 Agent features. * Tests the PURE FUNCTIONS from the agent module: diff --git a/packages/platform-core/tests/steps/durability/durable-append.steps.ts b/packages/platform-core/tests/steps/durability/durable-append.steps.ts index 79e99a77..334cd5ba 100644 --- a/packages/platform-core/tests/steps/durability/durable-append.steps.ts +++ b/packages/platform-core/tests/steps/durability/durable-append.steps.ts @@ -6,8 +6,6 @@ * - Workpool enqueue behavior * - Action handler factory * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/durability/durable-publication.steps.ts b/packages/platform-core/tests/steps/durability/durable-publication.steps.ts index 53b715e8..1dde18ed 100644 --- a/packages/platform-core/tests/steps/durability/durable-publication.steps.ts +++ b/packages/platform-core/tests/steps/durability/durable-publication.steps.ts @@ -9,8 +9,6 @@ * - retryPublication mutation * - onComplete callback behavior * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/durability/idempotent-append.steps.ts b/packages/platform-core/tests/steps/durability/idempotent-append.steps.ts index 4f8463cf..7a2cf83f 100644 --- a/packages/platform-core/tests/steps/durability/idempotent-append.steps.ts +++ b/packages/platform-core/tests/steps/durability/idempotent-append.steps.ts @@ -6,8 +6,6 @@ * - Idempotent append function behavior * - OCC conflict handling * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/durability/intent-completion.steps.ts b/packages/platform-core/tests/steps/durability/intent-completion.steps.ts index 923f62a5..130fe914 100644 --- a/packages/platform-core/tests/steps/durability/intent-completion.steps.ts +++ b/packages/platform-core/tests/steps/durability/intent-completion.steps.ts @@ -8,8 +8,6 @@ * - checkIntentTimeout function * - queryOrphanedIntents function * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/durability/outbox-handler.steps.ts b/packages/platform-core/tests/steps/durability/outbox-handler.steps.ts index 72e2ebf9..5b39ebe6 100644 --- a/packages/platform-core/tests/steps/durability/outbox-handler.steps.ts +++ b/packages/platform-core/tests/steps/durability/outbox-handler.steps.ts @@ -5,8 +5,6 @@ * - createOutboxHandler factory * - Event building from action results * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/durability/poison-event.steps.ts b/packages/platform-core/tests/steps/durability/poison-event.steps.ts index 5991393f..eb625451 100644 --- a/packages/platform-core/tests/steps/durability/poison-event.steps.ts +++ b/packages/platform-core/tests/steps/durability/poison-event.steps.ts @@ -9,8 +9,6 @@ * - listQuarantinedEvents query * - getPoisonEventStats query * - * @architect - * @architect-implements EventStoreDurability */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect, vi } from "vitest"; diff --git a/packages/platform-core/tests/steps/ecst/builder.steps.ts b/packages/platform-core/tests/steps/ecst/builder.steps.ts index 01417183..b791c070 100644 --- a/packages/platform-core/tests/steps/ecst/builder.steps.ts +++ b/packages/platform-core/tests/steps/ecst/builder.steps.ts @@ -1,8 +1,6 @@ /** * Fat Event Builder - Step Definitions * - * @architect - * @architect-pattern EcstFatEvents * * BDD step definitions for fat event builder behavior: * - createFatEvent() creation diff --git a/packages/platform-core/tests/steps/ecst/privacy.steps.ts b/packages/platform-core/tests/steps/ecst/privacy.steps.ts index 2f4467a9..17aea244 100644 --- a/packages/platform-core/tests/steps/ecst/privacy.steps.ts +++ b/packages/platform-core/tests/steps/ecst/privacy.steps.ts @@ -1,8 +1,6 @@ /** * Privacy Markers (Crypto-Shredding) - Step Definitions * - * @architect - * @architect-pattern EcstFatEvents * * BDD step definitions for crypto-shredding behavior: * - PII field marking diff --git a/packages/platform-core/tests/steps/ecst/selection.steps.ts b/packages/platform-core/tests/steps/ecst/selection.steps.ts index 3dbc1665..b15d81b4 100644 --- a/packages/platform-core/tests/steps/ecst/selection.steps.ts +++ b/packages/platform-core/tests/steps/ecst/selection.steps.ts @@ -1,8 +1,6 @@ /** * Fat vs Thin Event Selection - Step Definitions * - * @architect - * @architect-pattern EcstFatEvents * * BDD step definitions for fat vs thin event selection guidelines: * - Cross-context integration scenarios diff --git a/packages/platform-core/tests/steps/ecst/versioning.steps.ts b/packages/platform-core/tests/steps/ecst/versioning.steps.ts index 1df30dd0..360e52d3 100644 --- a/packages/platform-core/tests/steps/ecst/versioning.steps.ts +++ b/packages/platform-core/tests/steps/ecst/versioning.steps.ts @@ -1,8 +1,6 @@ /** * Schema Versioning - Step Definitions * - * @architect - * @architect-pattern EcstFatEvents * * BDD step definitions for fat event schema versioning: * - Schema version tracking diff --git a/packages/platform-core/tests/steps/event-replay/replay-progress.steps.ts b/packages/platform-core/tests/steps/event-replay/replay-progress.steps.ts index 2e476efa..fe3732c6 100644 --- a/packages/platform-core/tests/steps/event-replay/replay-progress.steps.ts +++ b/packages/platform-core/tests/steps/event-replay/replay-progress.steps.ts @@ -8,8 +8,6 @@ * - isActiveReplay * - isTerminalReplayStatus * - * @architect - * @architect-implements EventReplayInfrastructure */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-core/tests/steps/projections/reactive.steps.ts b/packages/platform-core/tests/steps/projections/reactive.steps.ts index 657db813..84671b3a 100644 --- a/packages/platform-core/tests/steps/projections/reactive.steps.ts +++ b/packages/platform-core/tests/steps/projections/reactive.steps.ts @@ -7,8 +7,6 @@ * - conflict-detection.feature: Conflict detection and rollback * - reactive-eligibility.feature: Category-based eligibility * - * @architect - * @architect-roadmap-spec ReactiveProjections */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-core/tests/steps/testing/integration-isolation.steps.ts b/packages/platform-core/tests/steps/testing/integration-isolation.steps.ts index 0d97a0ef..9c6a582e 100644 --- a/packages/platform-core/tests/steps/testing/integration-isolation.steps.ts +++ b/packages/platform-core/tests/steps/testing/integration-isolation.steps.ts @@ -1,8 +1,6 @@ /** * Integration Test Isolation - Step Definitions * - * @architect - * @architect-pattern BddTestingInfrastructure * * BDD step definitions validating the Docker restart pattern for state cleanup, * test namespacing for entity isolation, and Workpool/scheduler isolation. diff --git a/packages/platform-core/tests/steps/testing/platform-coverage.steps.ts b/packages/platform-core/tests/steps/testing/platform-coverage.steps.ts index 1b3f9833..b34d08a5 100644 --- a/packages/platform-core/tests/steps/testing/platform-coverage.steps.ts +++ b/packages/platform-core/tests/steps/testing/platform-coverage.steps.ts @@ -1,8 +1,6 @@ /** * Platform Package BDD Coverage - Step Definitions * - * @architect - * @architect-pattern BddTestingInfrastructure * * BDD step definitions validating that each @libar-dev/platform-* package * has appropriate BDD test coverage for its public APIs. diff --git a/packages/platform-core/tsconfig.json b/packages/platform-core/tsconfig.json index 5396a0bd..52294739 100644 --- a/packages/platform-core/tsconfig.json +++ b/packages/platform-core/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-decider/src/types.ts b/packages/platform-decider/src/types.ts index b912d0aa..c6411320 100644 --- a/packages/platform-decider/src/types.ts +++ b/packages/platform-decider/src/types.ts @@ -1,10 +1,4 @@ /** - * @architect - * @architect-pattern HandlerFactories - * @architect-status completed - * @architect-phase 14 - * @architect-decider - * * ## Handler Factories - Decider-to-Handler Wrappers * * ## Decider Pattern - Pure Domain Decision Logic diff --git a/packages/platform-decider/tests/features/behavior/decider-outputs.feature b/packages/platform-decider/tests/features/behavior/decider-outputs.feature index cd4258b9..d610265d 100644 --- a/packages/platform-decider/tests/features/behavior/decider-outputs.feature +++ b/packages/platform-decider/tests/features/behavior/decider-outputs.feature @@ -1,15 +1,4 @@ -@architect-pattern:DeciderOutputs @acceptance-criteria -@architect-status:completed -@architect-phase:60 -@architect-quarter:Q1-2026 -@architect-effort:3h -@architect-effort-actual:3h -@architect-completed:2026-01-08 -@architect-product-area:PlatformDecider -@architect-business-value:type-safe-command-outcome-handling -@architect-priority:high -@architect-implements:DeciderPattern Feature: Decider Output Helpers and Type Guards The Decider pattern uses discriminated unions to represent command outcomes: diff --git a/packages/platform-decider/tests/steps/decider-outputs.steps.ts b/packages/platform-decider/tests/steps/decider-outputs.steps.ts index b4ee71ce..0b986426 100644 --- a/packages/platform-decider/tests/steps/decider-outputs.steps.ts +++ b/packages/platform-decider/tests/steps/decider-outputs.steps.ts @@ -6,8 +6,6 @@ * This is a Layer 0 package (pure TypeScript, no Convex dependencies), * so tests run without any backend - just pure function testing. * - * @architect-decider - * @architect-pattern DeciderOutputs */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-decider/tsconfig.json b/packages/platform-decider/tsconfig.json index c4359b7e..2163857b 100644 --- a/packages/platform-decider/tsconfig.json +++ b/packages/platform-decider/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-fsm/tests/features/behavior/fsm-transitions.feature b/packages/platform-fsm/tests/features/behavior/fsm-transitions.feature index 14360a76..0da5c7a9 100644 --- a/packages/platform-fsm/tests/features/behavior/fsm-transitions.feature +++ b/packages/platform-fsm/tests/features/behavior/fsm-transitions.feature @@ -1,9 +1,4 @@ -@architect -@architect-pattern:FSMTransitions -@architect-status:completed @acceptance-criteria -@architect-implements:DeciderPattern -@architect-unlock-reason:metadata-alignment Feature: FSM State Transitions The FSM (Finite State Machine) module provides type-safe state management diff --git a/packages/platform-fsm/tests/steps/fsm-transitions.steps.ts b/packages/platform-fsm/tests/steps/fsm-transitions.steps.ts index 1a60d541..aedd43c1 100644 --- a/packages/platform-fsm/tests/steps/fsm-transitions.steps.ts +++ b/packages/platform-fsm/tests/steps/fsm-transitions.steps.ts @@ -6,8 +6,6 @@ * This is a Layer 0 package (pure TypeScript, no Convex dependencies), * so tests run without any backend - just pure function testing. * - * @architect-fsm - * @architect-pattern FSMTransitions */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-fsm/tsconfig.json b/packages/platform-fsm/tsconfig.json index c4359b7e..2163857b 100644 --- a/packages/platform-fsm/tsconfig.json +++ b/packages/platform-fsm/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/platform-store/src/client/index.ts b/packages/platform-store/src/client/index.ts index b4e6309c..dd7aa299 100644 --- a/packages/platform-store/src/client/index.ts +++ b/packages/platform-store/src/client/index.ts @@ -260,14 +260,6 @@ export interface EventStoreApi { } /** - * @architect - * @architect-pattern EventStore - * @architect-event-sourcing @architect-overview @architect-core - * @architect-status completed - * @architect-usecase "Appending events after CMS updates" - * @architect-usecase "Reading events for projection processing" - * @architect-used-by CommandOrchestrator - * * ## EventStore - Central Event Storage * * Central event storage component for Event Sourcing. diff --git a/packages/platform-store/tests/features/behavior/event-store-foundation-executable-tests.feature b/packages/platform-store/tests/features/behavior/event-store-foundation-executable-tests.feature index 4d35220c..db0b6c18 100644 --- a/packages/platform-store/tests/features/behavior/event-store-foundation-executable-tests.feature +++ b/packages/platform-store/tests/features/behavior/event-store-foundation-executable-tests.feature @@ -1,9 +1,3 @@ -@architect -@architect-pattern:EventStoreFoundationExecutableTests -@architect-implements:EventStoreFoundation -@architect-status:completed -@architect-unlock-reason:refactoring-carve-out-executable-tests-for-shipped-pattern-predates-implements-convention -@architect-product-area:PlatformStore Feature: EventStoreFoundation Executable Tests **Provenance:** This file was authored under the refactoring carve-out diff --git a/packages/platform-store/tests/features/behavior/event-store-types.feature b/packages/platform-store/tests/features/behavior/event-store-types.feature index eb102421..f2fbf00e 100644 --- a/packages/platform-store/tests/features/behavior/event-store-types.feature +++ b/packages/platform-store/tests/features/behavior/event-store-types.feature @@ -1,6 +1,3 @@ -@architect -@architect-phase:19 -@architect-product-area:PlatformStore @testing-infrastructure Feature: Event Store Type Contracts diff --git a/packages/platform-store/tests/steps/event-store-types.steps.ts b/packages/platform-store/tests/steps/event-store-types.steps.ts index 1e1d7b62..da28d94f 100644 --- a/packages/platform-store/tests/steps/event-store-types.steps.ts +++ b/packages/platform-store/tests/steps/event-store-types.steps.ts @@ -6,8 +6,6 @@ * This is a Layer 1 package (Convex component), but these tests focus on * type contracts which are pure TypeScript - no Convex runtime required. * - * @architect-event-sourcing - * @architect-pattern BddTestingInfrastructure */ import { loadFeature, describeFeature } from "@amiceli/vitest-cucumber"; import { expect } from "vitest"; diff --git a/packages/platform-store/tsconfig.json b/packages/platform-store/tsconfig.json index 341bf76a..483e56d2 100644 --- a/packages/platform-store/tsconfig.json +++ b/packages/platform-store/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8de2b08a..c186e874 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -156,9 +156,9 @@ importers: '@edge-runtime/vm': specifier: 'catalog:' version: 5.0.0 - '@libar-dev/architect': - specifier: 1.0.0-pre.3 - version: 1.0.0-pre.3(typescript@6.0.3) + '@libar-dev/software-delivery-protocol': + specifier: file:../software-delivery-protocol + version: file:../software-delivery-protocol(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) concurrently: specifier: ^9.2.1 version: 9.2.1 @@ -182,7 +182,7 @@ importers: version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) zod: specifier: 'catalog:' version: 4.3.6 @@ -236,7 +236,7 @@ importers: version: 1.166.11(@tanstack/query-core@5.99.2)(@tanstack/react-query@5.99.2(react@19.2.5))(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(@tanstack/router-core@1.168.15)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/react-start': specifier: 'catalog:' - version: 1.167.42(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 1.167.42(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -279,13 +279,13 @@ importers: version: 5.2.5 '@ladle/react': specifier: ^5.1.1 - version: 5.1.1(@types/node@25.6.0)(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3) + version: 5.1.1(@types/node@25.6.0)(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.9.0) '@playwright/test': specifier: 'catalog:' version: 1.59.1 '@tailwindcss/vite': specifier: 'catalog:' - version: 4.2.4(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.2.4(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@types/node': specifier: 'catalog:' version: 25.6.0 @@ -297,7 +297,7 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: 'catalog:' - version: 6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) playwright-bdd: specifier: 'catalog:' version: 8.5.0(@playwright/test@1.59.1) @@ -312,7 +312,7 @@ importers: version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) vite: specifier: 'catalog:' - version: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + version: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) examples/order-management: dependencies: @@ -361,7 +361,7 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) '@edge-runtime/vm': specifier: 'catalog:' version: 5.0.0 @@ -376,7 +376,7 @@ importers: version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) packages/platform-bc: dependencies: @@ -386,13 +386,13 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) typescript: specifier: 'catalog:' version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) zod: specifier: 'catalog:' version: 4.3.6 @@ -408,7 +408,7 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) convex: specifier: 'catalog:' version: 1.36.0(react@19.2.5) @@ -417,7 +417,7 @@ importers: version: 0.1.115(@standard-schema/spec@1.1.0)(convex@1.36.0(react@19.2.5))(hono@4.11.7)(react@19.2.5)(typescript@6.0.3)(zod@4.3.6) vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) zod: specifier: 'catalog:' version: 4.3.6 @@ -429,7 +429,7 @@ importers: version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) packages/platform-core: dependencies: @@ -463,7 +463,7 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) convex: specifier: 'catalog:' version: 1.36.0(react@19.2.5) @@ -472,7 +472,7 @@ importers: version: 0.1.115(@standard-schema/spec@1.1.0)(convex@1.36.0(react@19.2.5))(hono@4.11.7)(react@19.2.5)(typescript@6.0.3)(zod@4.3.6) vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) zod: specifier: 'catalog:' version: 4.3.6 @@ -481,25 +481,25 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) typescript: specifier: 'catalog:' version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) packages/platform-fsm: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) typescript: specifier: 'catalog:' version: 6.0.3 vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) packages/platform-store: dependencies: @@ -515,7 +515,7 @@ importers: devDependencies: '@amiceli/vitest-cucumber': specifier: 'catalog:' - version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))) + version: 6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))) convex: specifier: 'catalog:' version: 1.36.0(react@19.2.5) @@ -524,7 +524,7 @@ importers: version: 0.1.115(@standard-schema/spec@1.1.0)(convex@1.36.0(react@19.2.5))(hono@4.11.7)(react@19.2.5)(typescript@6.0.3)(zod@4.3.6) vitest: specifier: 'catalog:' - version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + version: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) zod: specifier: 'catalog:' version: 4.3.6 @@ -794,15 +794,15 @@ packages: resolution: {integrity: sha512-3nmRbG1bUAZP3fAaUBNmqWO0z0OSkykZZotfLjyhc8KWwDSOrOmMJlBTd474lpA8EWh4JFLAX3iXgynBqBvKzw==} hasBin: true - '@cucumber/gherkin@29.0.0': - resolution: {integrity: sha512-6t3V7fFsLlyhLSj4FS+fPz22pPVcFhFZ3QOP7otFYmkhZ4g1ierj5pf7fxJWvEsI555hGatg+Iql6cqK93RFUg==} - '@cucumber/gherkin@31.0.0': resolution: {integrity: sha512-wlZfdPif7JpBWJdqvHk1Mkr21L5vl4EfxVUOS4JinWGf3FLRV6IKUekBv5bb5VX79fkDcfDvESzcQ8WQc07Wgw==} '@cucumber/gherkin@32.2.0': resolution: {integrity: sha512-X8xuVhSIqlUjxSRifRJ7t0TycVWyX58fygJH3wDNmHINLg9sYEkvQT0SO2G5YlRZnYc11TIFr4YPenscvdlBIw==} + '@cucumber/gherkin@42.0.1': + resolution: {integrity: sha512-Kqg0ULhWqbXp/a1c04ND4sS4KTlIL831tQ0NhZLXWdEhT6LiNsZ5LFRzy/lBy7QQpcKhroKp/i3C2WdEnRBKNg==} + '@cucumber/html-formatter@21.15.1': resolution: {integrity: sha512-tjxEpP161sQ7xc3VREc94v1ymwIckR3ySViy7lTvfi1jUpyqy2Hd/p4oE3YT1kQ9fFDvUflPwu5ugK5mA7BQLA==} peerDependencies: @@ -813,15 +813,15 @@ packages: peerDependencies: '@cucumber/messages': '*' - '@cucumber/messages@25.0.1': - resolution: {integrity: sha512-RjjhmzcauX5eYfcKns5pgenefDJQcfXE3ZDrVWdUDGcoaoyFVDmj+ZzQZWRWqFrfMjP3lKHJss6LtvIP/z+h8g==} - '@cucumber/messages@26.0.1': resolution: {integrity: sha512-DIxSg+ZGariumO+Lq6bn4kOUIUET83A4umrnWmidjGFl8XxkBieUZtsmNbLYgH/gnsmP07EfxxdTr0hOchV1Sg==} '@cucumber/messages@27.2.0': resolution: {integrity: sha512-f2o/HqKHgsqzFLdq6fAhfG1FNOQPdBdyMGpKwhb7hZqg0yZtx9BVqkTyuoNk83Fcvk3wjMVfouFXXHNEk4nddA==} + '@cucumber/messages@34.2.1': + resolution: {integrity: sha512-aj2iCAG9ZOpMVcMxcgShifv5fbR96b7SMgdWcPXXh2QbFp7OEcAnQ5MC5YfWUDSDasmw7FU5NJEsOrXdTQOU1A==} + '@cucumber/query@13.6.0': resolution: {integrity: sha512-tiDneuD5MoWsJ9VKPBmQok31mSX9Ybl+U4wqDoXeZgsXHDURqzM3rnpWVV3bC34y9W6vuFxrlwF/m7HdOxwqRw==} peerDependencies: @@ -1453,10 +1453,6 @@ packages: '@types/node': optional: true - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1487,10 +1483,15 @@ packages: react: '>=18.0.0' react-dom: '>=18.0.0' - '@libar-dev/architect@1.0.0-pre.3': - resolution: {integrity: sha512-TP/gq6dqrQrqr/0mE9D0x8SmKyZ1TZ5EyOk3jNpoFFKWxHY35BYEIgUM/NMYTjZJyNQb3G3k5HisTmQ/3c95sg==} - engines: {node: '>=18.0.0'} + '@libar-dev/software-delivery-protocol@file:../software-delivery-protocol': + resolution: {directory: ../software-delivery-protocol, type: directory} + engines: {node: '>=20'} hasBin: true + peerDependencies: + vitest: '>=2' + peerDependenciesMeta: + vitest: + optional: true '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} @@ -1584,10 +1585,6 @@ packages: '@oxc-project/types@0.126.0': resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - '@playwright/test@1.59.1': resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==} engines: {node: '>=18'} @@ -2155,6 +2152,9 @@ packages: '@ts-morph/common@0.28.1': resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==} + '@ts-morph/common@0.29.0': + resolution: {integrity: sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -2229,9 +2229,6 @@ packages: '@types/uuid@10.0.0': resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - '@types/validate-npm-package-name@4.0.2': resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} @@ -2467,9 +2464,6 @@ packages: bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -2496,9 +2490,6 @@ packages: resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} engines: {node: '>=18'} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@5.0.5: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} @@ -2592,10 +2583,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} - class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} @@ -2894,9 +2881,6 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - eciesjs@0.4.17: resolution: {integrity: sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} @@ -2913,9 +2897,6 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -3172,10 +3153,6 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -3263,11 +3240,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - globby@14.1.0: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} @@ -3536,9 +3508,6 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -3711,9 +3680,6 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -3944,17 +3910,9 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -4075,9 +4033,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -4124,10 +4079,6 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} @@ -4288,10 +4239,6 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} - engines: {node: '>= 20.19.0'} - recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -4544,10 +4491,6 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -4670,6 +4613,9 @@ packages: ts-morph@27.0.2: resolution: {integrity: sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==} + ts-morph@28.0.0: + resolution: {integrity: sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==} + tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -4810,10 +4756,6 @@ packages: resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - validate-npm-package-name@7.0.2: resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} engines: {node: ^20.17.0 || >=22.9.0} @@ -5021,10 +4963,6 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - wrap-ansi@9.0.2: resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} @@ -5067,6 +5005,11 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -5125,13 +5068,13 @@ snapshots: dependencies: json-schema: 0.4.0 - '@amiceli/vitest-cucumber@6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)))': + '@amiceli/vitest-cucumber@6.3.0(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)))': dependencies: callsites: 4.2.0 minimist: 1.2.8 parsecurrency: 1.1.1 ts-morph: 27.0.2 - vitest: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + vitest: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@babel/code-frame@7.27.1': dependencies: @@ -5424,10 +5367,6 @@ snapshots: commander: 13.1.0 source-map-support: 0.5.21 - '@cucumber/gherkin@29.0.0': - dependencies: - '@cucumber/messages': 25.0.1 - '@cucumber/gherkin@31.0.0': dependencies: '@cucumber/messages': 26.0.1 @@ -5436,6 +5375,10 @@ snapshots: dependencies: '@cucumber/messages': 27.2.0 + '@cucumber/gherkin@42.0.1': + dependencies: + '@cucumber/messages': 34.2.1 + '@cucumber/html-formatter@21.15.1(@cucumber/messages@27.2.0)': dependencies: '@cucumber/messages': 27.2.0 @@ -5448,13 +5391,6 @@ snapshots: luxon: 3.7.2 xmlbuilder: 15.1.1 - '@cucumber/messages@25.0.1': - dependencies: - '@types/uuid': 9.0.8 - class-transformer: 0.5.1 - reflect-metadata: 0.2.2 - uuid: 9.0.1 - '@cucumber/messages@26.0.1': dependencies: '@types/uuid': 10.0.0 @@ -5469,6 +5405,8 @@ snapshots: reflect-metadata: 0.2.2 uuid: 11.0.5 + '@cucumber/messages@34.2.1': {} + '@cucumber/query@13.6.0(@cucumber/messages@27.2.0)': dependencies: '@cucumber/messages': 27.2.0 @@ -5855,15 +5793,6 @@ snapshots: optionalDependencies: '@types/node': 25.6.0 - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5888,7 +5817,7 @@ snapshots: react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - '@ladle/react@5.1.1(@types/node@25.6.0)(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)': + '@ladle/react@5.1.1(@types/node@25.6.0)(@types/react@19.2.14)(jiti@2.6.1)(lightningcss@1.32.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.9.0)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -5900,8 +5829,8 @@ snapshots: '@ladle/react-context': 1.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@mdx-js/mdx': 3.1.1 '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) - '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)) - '@vitejs/plugin-react-swc': 3.11.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)) + '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)) + '@vitejs/plugin-react-swc': 3.11.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)) axe-core: 4.11.1 boxen: 8.0.1 chokidar: 4.0.3 @@ -5928,8 +5857,8 @@ snapshots: remark-gfm: 4.0.1 source-map: 0.7.6 vfile: 6.0.3 - vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0) - vite-tsconfig-paths: 5.1.4(typescript@6.0.3)(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)) + vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0) + vite-tsconfig-paths: 5.1.4(typescript@6.0.3)(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)) transitivePeerDependencies: - '@swc/helpers' - '@types/node' @@ -5947,19 +5876,14 @@ snapshots: - typescript - yaml - '@libar-dev/architect@1.0.0-pre.3(typescript@6.0.3)': + '@libar-dev/software-delivery-protocol@file:../software-delivery-protocol(vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)))': dependencies: - '@cucumber/gherkin': 29.0.0 - '@cucumber/messages': 25.0.1 - '@modelcontextprotocol/sdk': 1.28.0(zod@4.3.6) - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - chokidar: 5.0.0 - glob: 10.5.0 - zod: 4.3.6 - transitivePeerDependencies: - - '@cfworker/json-schema' - - supports-color - - typescript + '@cucumber/gherkin': 42.0.1 + '@cucumber/messages': 34.2.1 + ts-morph: 28.0.0 + yaml: 2.9.0 + optionalDependencies: + vitest: 4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@mdx-js/mdx@3.1.1': dependencies: @@ -6019,28 +5943,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@modelcontextprotocol/sdk@1.28.0(zod@4.3.6)': - dependencies: - '@hono/node-server': 1.19.9(hono@4.11.7) - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.0.6 - express: 5.2.1 - express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.7 - jose: 6.1.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.3.6 - zod-to-json-schema: 3.25.1(zod@4.3.6) - transitivePeerDependencies: - - supports-color - '@mswjs/interceptors@0.41.2': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -6112,9 +6014,6 @@ snapshots: '@oxc-project/types@0.126.0': {} - '@pkgjs/parseargs@0.11.0': - optional: true - '@playwright/test@1.59.1': dependencies: playwright: 1.59.1 @@ -6372,12 +6271,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - '@tailwindcss/vite@4.2.4(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@tailwindcss/vite@4.2.4(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) '@tanstack/history@1.161.6': {} @@ -6416,7 +6315,7 @@ snapshots: react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - '@tanstack/react-start-rsc@0.0.21(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/react-start-rsc@0.0.21(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@tanstack/react-router': 1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/react-start-server': 1.166.41(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -6424,7 +6323,7 @@ snapshots: '@tanstack/router-utils': 1.161.6 '@tanstack/start-client-core': 1.167.17 '@tanstack/start-fn-stubs': 1.161.6 - '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@tanstack/start-server-core': 1.167.19 '@tanstack/start-storage-context': 1.166.29 pathe: 2.0.3 @@ -6450,20 +6349,20 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start@1.167.42(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/react-start@1.167.42(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@tanstack/react-router': 1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/react-start-client': 1.166.40(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@tanstack/react-start-rsc': 0.0.21(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/react-start-rsc': 0.0.21(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@tanstack/react-start-server': 1.166.41(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/router-utils': 1.161.6 '@tanstack/start-client-core': 1.167.17 - '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/start-plugin-core': 1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@tanstack/start-server-core': 1.167.19 pathe: 2.0.3 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: - '@rsbuild/core' - crossws @@ -6498,7 +6397,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) @@ -6515,7 +6414,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -6547,7 +6446,7 @@ snapshots: '@tanstack/start-fn-stubs@1.161.6': {} - '@tanstack/start-plugin-core@1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@tanstack/start-plugin-core@1.167.35(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.29.0 @@ -6555,7 +6454,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.40 '@tanstack/router-core': 1.168.15 '@tanstack/router-generator': 1.166.32 - '@tanstack/router-plugin': 1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + '@tanstack/router-plugin': 1.167.22(@tanstack/react-router@1.168.23(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@tanstack/router-utils': 1.161.6 '@tanstack/start-client-core': 1.167.17 '@tanstack/start-server-core': 1.167.19 @@ -6568,8 +6467,8 @@ snapshots: srvx: 0.11.15 tinyglobby: 0.2.15 ufo: 1.6.3 - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) - vitefu: 1.1.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) + vitefu: 1.1.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) xmlbuilder2: 4.0.3 zod: 3.25.76 transitivePeerDependencies: @@ -6613,6 +6512,12 @@ snapshots: path-browserify: 1.0.1 tinyglobby: 0.2.16 + '@ts-morph/common@0.29.0': + dependencies: + minimatch: 10.2.5 + path-browserify: 1.0.1 + tinyglobby: 0.2.16 + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -6694,8 +6599,6 @@ snapshots: '@types/uuid@10.0.0': {} - '@types/uuid@9.0.8': {} - '@types/validate-npm-package-name@4.0.2': {} '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': @@ -6809,15 +6712,15 @@ snapshots: '@vercel/oidc@3.2.0': {} - '@vitejs/plugin-react-swc@3.11.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0))': + '@vitejs/plugin-react-swc@3.11.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.27 '@swc/core': 1.15.11 - vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0) + vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -6825,14 +6728,14 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0) + vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@vitejs/plugin-react@6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) '@vitest/expect@4.1.5': dependencies: @@ -6843,14 +6746,14 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.5(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0))': + '@vitest/mocker@4.1.5(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.8(@types/node@25.6.0)(typescript@6.0.3) - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) '@vitest/pretty-format@4.1.5': dependencies: @@ -6972,8 +6875,6 @@ snapshots: bail@2.0.2: {} - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} baseline-browser-mapping@2.9.19: {} @@ -7009,10 +6910,6 @@ snapshots: widest-line: 5.0.0 wrap-ansi: 9.0.2 - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -7118,10 +7015,6 @@ snapshots: dependencies: readdirp: 4.1.2 - chokidar@5.0.0: - dependencies: - readdirp: 5.0.0 - class-transformer@0.5.1: {} class-variance-authority@0.7.1: @@ -7344,8 +7237,6 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - eastasianwidth@0.2.0: {} - eciesjs@0.4.17: dependencies: '@ecies/ciphers': 0.2.5(@noble/ciphers@1.3.0) @@ -7361,8 +7252,6 @@ snapshots: emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -7758,11 +7647,6 @@ snapshots: flatted@3.3.3: {} - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -7838,15 +7722,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.5.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - globby@14.1.0: dependencies: '@sindresorhus/merge-streams': 2.3.0 @@ -8162,12 +8037,6 @@ snapshots: isexe@3.1.1: {} - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - jiti@2.6.1: {} jose@6.1.3: {} @@ -8324,8 +8193,6 @@ snapshots: dependencies: js-tokens: 4.0.0 - lru-cache@10.4.3: {} - lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -8808,14 +8675,8 @@ snapshots: dependencies: brace-expansion: 5.0.5 - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - minimist@1.2.8: {} - minipass@7.1.2: {} - ms@2.1.3: {} msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3): @@ -8951,8 +8812,6 @@ snapshots: dependencies: p-limit: 3.1.0 - package-json-from-dist@1.0.1: {} - parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -9001,11 +8860,6 @@ snapshots: path-key@4.0.0: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - path-to-regexp@6.3.0: {} path-to-regexp@8.3.0: {} @@ -9150,8 +9004,6 @@ snapshots: readdirp@4.1.2: {} - readdirp@5.0.0: {} - recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -9525,12 +9377,6 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.2 - string-width@7.2.0: dependencies: emoji-regex: 10.6.0 @@ -9640,6 +9486,11 @@ snapshots: '@ts-morph/common': 0.28.1 code-block-writer: 13.0.3 + ts-morph@28.0.0: + dependencies: + '@ts-morph/common': 0.29.0 + code-block-writer: 13.0.3 + tsconfck@3.1.6(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 @@ -9777,8 +9628,6 @@ snapshots: uuid@14.0.0: {} - uuid@9.0.1: {} - validate-npm-package-name@7.0.2: {} vary@1.1.2: {} @@ -9798,18 +9647,18 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-tsconfig-paths@5.1.4(typescript@6.0.3)(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)): + vite-tsconfig-paths@5.1.4(typescript@6.0.3)(vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@6.0.3) optionalDependencies: - vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0) + vite: 6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0) transitivePeerDependencies: - supports-color - typescript - vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0): + vite@6.4.1(@types/node@25.6.0)(jiti@2.6.1)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.9.0): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -9823,8 +9672,9 @@ snapshots: jiti: 2.6.1 lightningcss: 1.32.0 tsx: 4.21.0 + yaml: 2.9.0 - vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0): + vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -9837,15 +9687,16 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 tsx: 4.21.0 + yaml: 2.9.0 - vitefu@1.1.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)): + vitefu@1.1.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)): optionalDependencies: - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) - vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)): + vitest@4.1.5(@edge-runtime/vm@5.0.0)(@opentelemetry/api@1.9.0)(@types/node@25.6.0)(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)) + '@vitest/mocker': 4.1.5(msw@2.12.8(@types/node@25.6.0)(typescript@6.0.3))(vite@8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.5 '@vitest/runner': 4.1.5 '@vitest/snapshot': 4.1.5 @@ -9862,7 +9713,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0) + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@edge-runtime/vm': 5.0.0 @@ -9914,12 +9765,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 5.1.2 - strip-ansi: 7.1.2 - wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 @@ -9952,6 +9797,8 @@ snapshots: yallist@3.1.1: {} + yaml@2.9.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: @@ -9976,10 +9823,6 @@ snapshots: dependencies: zod: 3.25.76 - zod-to-json-schema@3.25.1(zod@4.3.6): - dependencies: - zod: 4.3.6 - zod@3.25.76: {} zod@4.3.6: {} diff --git a/scripts/generate-dcb-docs.ts b/scripts/generate-dcb-docs.ts index 05535721..18b96758 100644 --- a/scripts/generate-dcb-docs.ts +++ b/scripts/generate-dcb-docs.ts @@ -1,89 +1,17 @@ #!/usr/bin/env npx tsx /** - * POC: Generate DCB API Reference Documentation + * Retired: DCB API reference generation via architect-generate. * - * Demonstrates code-first documentation generation using architect's built-in - * `doc-from-decision` generator. Extracts TypeScript types from annotated source files - * and generates both compact (for Claude context) and detailed (for humans) output. + * The architect docs-living / doc-from-decision workflow is no longer on the delivery path. + * Author and bind DCB intent under specs/ (see spec:platform.dcb-api-reference and related + * pattern Specs) and use SDP projections instead: * - * Usage: npx tsx scripts/generate-dcb-docs.ts - * - * Output: - * - docs-generated/_claude-md/platform/dcb-api-reference.md (compact) - * - docs-generated/docs/DCB-API-REFERENCE.md (detailed) + * pnpm sdp:build + * pnpm sdp:validate + * pnpm sdp:view */ -import { execSync } from "node:child_process"; -import * as path from "node:path"; -import * as fs from "node:fs"; - -const ROOT_DIR = path.resolve(import.meta.dirname, ".."); -const OUTPUT_DIR = path.join(ROOT_DIR, "docs-generated"); - -console.log("=".repeat(60)); -console.log("POC: DCB API Reference - Code-First Documentation"); -console.log("=".repeat(60)); -console.log(); - -// Ensure output directory exists -if (!fs.existsSync(OUTPUT_DIR)) { - fs.mkdirSync(OUTPUT_DIR, { recursive: true }); - console.log(`Created output directory: ${OUTPUT_DIR}`); -} - -// Use architect-generate with the built-in doc-from-decision generator. -const cmd = [ - "pnpm exec architect-generate", - "-g doc-from-decision", - "-i 'packages/platform-core/src/dcb/**/*.ts'", // TypeScript sources for shape extraction - "--features 'specs/platform/generated-docs/*.feature'", - `-o docs-generated`, - "-f", // force overwrite -].join(" "); - -console.log(`Running: ${cmd}`); -console.log(); - -try { - execSync(cmd, { - cwd: ROOT_DIR, - stdio: "inherit", - }); - - console.log(); - console.log("=".repeat(60)); - console.log("POC Complete!"); - console.log("=".repeat(60)); - console.log(); - - // List generated files - const listFiles = (dir: string, prefix = "") => { - if (!fs.existsSync(dir)) return; - const entries = fs.readdirSync(dir, { withFileTypes: true }); - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - console.log(`${prefix}${entry.name}/`); - listFiles(fullPath, prefix + " "); - } else { - const stats = fs.statSync(fullPath); - console.log(`${prefix}${entry.name} (${stats.size} bytes)`); - } - } - }; - - console.log("Generated files:"); - listFiles(OUTPUT_DIR); - console.log(); -} catch (error) { - console.error("Generation failed:"); - if (error instanceof Error) { - console.error(error.message); - if ("stderr" in error && error.stderr) { - console.error("stderr:", String(error.stderr)); - } - } else { - console.error(error); - } - process.exit(1); -} +console.error( + "generate-dcb-docs.ts is retired with @libar-dev/architect. Use pnpm sdp:build / sdp:validate / sdp:view.", +); +process.exit(1); diff --git a/scripts/migrate-architect-corpus.mjs b/scripts/migrate-architect-corpus.mjs new file mode 100644 index 00000000..8cda5c6c --- /dev/null +++ b/scripts/migrate-architect-corpus.mjs @@ -0,0 +1,317 @@ +#!/usr/bin/env node +/** + * Migrate architect/*.feature carriers into SDP Markdown Specs/Packs under specs/. + * Distills Feature title + problem/solution into Intent; does not dump full Gherkin. + * + * Usage: node scripts/migrate-architect-corpus.mjs [--dry-run] + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const DRY_RUN = process.argv.includes("--dry-run"); +const ARCHITECT = path.join(ROOT, "docs", "lineage", "architect"); + +/** @param {string} name */ +function toKebab(name) { + return name + .replace(/([a-z0-9])([A-Z])/g, "$1-$2") + .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2") + .replace(/([A-Za-z])(\d)/g, "$1-$2") + .replace(/(\d)([A-Za-z])/g, "$1-$2") + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-+|-+$/g, ""); +} + +/** + * @param {string} content + */ +function parseFeature(content) { + const lines = content.split("\n"); + /** @type {Record} */ + const tags = {}; + let title = ""; + const prose = []; + + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed.startsWith("@architect")) { + const body = trimmed.slice(1); // drop @ + const colon = body.indexOf(":"); + if (colon === -1) { + tags[body] = "true"; + } else { + tags[body.slice(0, colon)] = body.slice(colon + 1).trim(); + } + continue; + } + if (trimmed.startsWith("Feature:")) { + title = trimmed.slice("Feature:".length).trim(); + continue; + } + if (/^(Background:|Rule:|Scenario:|Scenario Outline:|Example:)/.test(trimmed)) { + break; + } + if (title) prose.push(line); + } + + const proseText = prose.join("\n").trim(); + const problem = extractSection(proseText, "Problem"); + const solution = extractSection(proseText, "Solution"); + return { tags, title, problem, solution, proseText }; +} + +/** + * @param {string} text + * @param {string} heading + */ +function extractSection(text, heading) { + const re = new RegExp( + `\\*\\*${heading}:?\\*\\*\\s*([\\s\\S]*?)(?=\\n\\s*\\*\\*[A-Z][^*]+\\*\\*|$)`, + "i", + ); + const m = text.match(re); + if (!m) return ""; + return m[1] + .split("\n") + .map((l) => l.replace(/^\s*-\s*/, "").trim()) + .filter(Boolean) + .join(" ") + .replace(/\s+/g, " ") + .trim() + .slice(0, 400); +} + +/** + * @param {string} filePath + * @param {"platform"|"decisions"|"releases"|"example-app"|"specs"} family + */ +function migrateFile(filePath, family) { + const content = fs.readFileSync(filePath, "utf8"); + const { tags, title, problem, solution } = parseFeature(content); + const base = path.basename(filePath, ".feature"); + const pattern = tags["architect-pattern"] || tags["architect-implements"]; + + let id; + let kind; + let altitude = "feature"; + let outDir; + let fileStem; + + if (family === "decisions") { + id = `spec:decisions.${toKebab(base)}`; + kind = "decision"; + altitude = "feature"; + outDir = path.join(ROOT, "specs", "decisions"); + fileStem = toKebab(base); + } else if (family === "releases") { + id = `spec:releases.${toKebab(base)}`; + kind = "behavior"; + altitude = "epic"; + outDir = path.join(ROOT, "specs", "releases"); + fileStem = toKebab(base); + } else if (family === "example-app") { + const stem = pattern ? toKebab(pattern) : toKebab(base); + id = `spec:example-app.${stem}`; + kind = "behavior"; + outDir = path.join(ROOT, "specs", "example-app"); + fileStem = stem; + } else { + const stem = pattern ? toKebab(pattern) : toKebab(base); + id = `spec:platform.${stem}`; + kind = stem.includes("architecture") || stem.includes("package") ? "model" : "behavior"; + outDir = path.join(ROOT, "specs", "platform"); + fileStem = stem; + } + + const outcome = + (problem && `Address: ${problem}`) || + (solution && `Deliver: ${solution}`) || + `Capture former architect intent for ${title || base}.`; + + const status = tags["architect-status"]; + const readiness = + status === "completed" || status === "active" ? "scoped" : "idea"; + + const body = `--- +id: ${id} +kind: ${kind} +altitude: ${altitude} +readiness: ${readiness} +relations: {} +--- +# ${title || base} + +## Intent + +- outcome: ${outcome.slice(0, 500)} +${ + solution + ? ` +## Design + +${solution} +` + : "" +}${ + kind === "decision" + ? ` +## Decision + +- ruling: Migrated from architect decision carrier \`${path.relative(ROOT, filePath)}\`; see Intent for the durable outcome. +` + : "" +}`; + + const outPath = path.join(outDir, `${fileStem}.sdp.md`); + return { id, outPath, body, title: title || base }; +} + +/** @type {{ id: string, outPath: string, body: string, title: string }[]} */ +const migrated = []; + +function migrateGlob(dir, family) { + if (!fs.existsSync(dir)) return; + for (const name of fs.readdirSync(dir)) { + if (!name.endsWith(".feature")) continue; + migrated.push(migrateFile(path.join(dir, name), family)); + } +} + +migrateGlob(path.join(ARCHITECT, "specs", "platform"), "platform"); +migrateGlob(path.join(ARCHITECT, "specs", "example-app"), "example-app"); +migrateGlob(path.join(ARCHITECT, "decisions"), "decisions"); +migrateGlob(path.join(ARCHITECT, "releases"), "releases"); + +// Top-level architect/specs/*.feature (not in platform/ or example-app/) +for (const name of fs.readdirSync(path.join(ARCHITECT, "specs"))) { + if (!name.endsWith(".feature")) continue; + migrated.push( + migrateFile(path.join(ARCHITECT, "specs", name), "platform"), + ); +} + +// DCB API reference formerly under specs/platform/generated-docs +const dcbFeature = path.join( + ROOT, + "specs", + "platform", + "generated-docs", + "dcb-api-reference.feature", +); +if (fs.existsSync(dcbFeature)) { + migrated.push(migrateFile(dcbFeature, "platform")); +} + +const byFamily = { + platform: migrated.filter((m) => m.id.startsWith("spec:platform.")), + decisions: migrated.filter((m) => m.id.startsWith("spec:decisions.")), + releases: migrated.filter((m) => m.id.startsWith("spec:releases.")), + "example-app": migrated.filter((m) => m.id.startsWith("spec:example-app.")), +}; + +if (!DRY_RUN) { + for (const item of migrated) { + fs.mkdirSync(path.dirname(item.outPath), { recursive: true }); + // Prefer richer existing Spec if already present with same path; overwrite for migration freshness. + fs.writeFileSync(item.outPath, item.body); + } + + // Remove foreign bare-.feature carrier so it is not confused with SDP. + if (fs.existsSync(dcbFeature)) { + fs.unlinkSync(dcbFeature); + const genDocsDir = path.dirname(dcbFeature); + if (fs.existsSync(genDocsDir) && fs.readdirSync(genDocsDir).length === 0) { + fs.rmdirSync(genDocsDir); + } + } + + writePack( + path.join(ROOT, "specs", "platform.pack.sdp.md"), + "pack:platform", + "Platform", + "Platform delivery Specs migrated from the former architect corpus.", + byFamily.platform.map((m) => m.id), + ); + writePack( + path.join(ROOT, "specs", "decisions.pack.sdp.md"), + "pack:decisions", + "Decisions", + "Decision Specs migrated from architect/decisions.", + byFamily.decisions.map((m) => m.id), + ); + writePack( + path.join(ROOT, "specs", "releases.pack.sdp.md"), + "pack:releases", + "Releases", + "Release Specs migrated from architect/releases.", + byFamily.releases.map((m) => m.id), + ); + if (byFamily["example-app"].length > 0) { + writePack( + path.join(ROOT, "specs", "example-app.pack.sdp.md"), + "pack:example-app", + "Example app", + "Example-app Specs migrated from architect/specs/example-app.", + byFamily["example-app"].map((m) => m.id), + ); + } + + const readme = `# SDP corpus (libar-platform) + +Designated delivery corpus root for Libar Software Delivery Protocol: repository root \`.\\` +with carriers under \`specs/\`. Historical \`architect/\` Gherkin is retained as lineage only and +is excluded from \`sdp\` discovery. + +## Commands + +\`\`\`sh +pnpm sdp:build # extract graph + contracts +pnpm sdp:validate # conformance + honesty checks +pnpm sdp:view # Design Review projection +pnpm sdp:q 'return g.specs().map((s) => s.id)' +\`\`\` + +Excludes (wired in package scripts): \`docs-living\`, \`docs-generated\`, \`architect\`, \`docs\`. +\`node_modules\`, \`dist\`, and \`generated\` are skipped by Protocol discovery automatically. +`; + fs.writeFileSync(path.join(ROOT, "specs", "README.md"), readme); +} + +/** + * @param {string} outPath + * @param {string} id + * @param {string} title + * @param {string} framing + * @param {string[]} specIds + */ +function writePack(outPath, id, title, framing, specIds) { + const unique = [...new Set(specIds)].sort(); + const body = `--- +id: ${id} +specs: +${unique.map((s) => ` - ${s}`).join("\n")} +--- +# ${title} + +${framing} +`; + fs.writeFileSync(outPath, body); +} + +console.log( + JSON.stringify( + { + dryRun: DRY_RUN, + migrated: migrated.length, + packs: ["pack:platform", "pack:decisions", "pack:releases", "pack:example-app"], + byFamily: Object.fromEntries( + Object.entries(byFamily).map(([k, v]) => [k, v.length]), + ), + ids: migrated.map((m) => m.id).sort(), + }, + null, + 2, + ), +); diff --git a/scripts/migrate-architect-tags.mjs b/scripts/migrate-architect-tags.mjs new file mode 100644 index 00000000..a26e8d3e --- /dev/null +++ b/scripts/migrate-architect-tags.mjs @@ -0,0 +1,278 @@ +#!/usr/bin/env node +/** + * Strip retired @architect / @architect-* annotation tags from the live delivery + * surface, ensure idea-rung Specs exist for each discovered pattern, and emit one + * SDP codeAnchor binding module (unique IDs) for the migrated surface. + * + * Usage: node scripts/migrate-architect-tags.mjs [--dry-run] + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const DRY_RUN = process.argv.includes("--dry-run"); + +const SKIP_DIR_NAMES = new Set([ + "node_modules", + "dist", + "generated", + "coverage", + "docs-living", + "docs-generated", + "architect", + ".git", +]); + +const SOURCE_SUFFIXES = new Set([".ts", ".tsx", ".feature", ".feature.md", ".md"]); + +/** @param {string} name */ +function toKebab(name) { + return name + .replace(/([a-z0-9])([A-Z])/g, "$1-$2") + .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2") + .replace(/([A-Za-z])(\d)/g, "$1-$2") + .replace(/(\d)([A-Za-z])/g, "$1-$2") + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-+|-+$/g, ""); +} + +/** @param {string} pattern */ +function patternToSpecId(pattern) { + return `spec:platform.${toKebab(pattern)}`; +} + +/** @param {string} pattern */ +function patternToAnchorId(pattern) { + return `impl:platform.${toKebab(pattern)}`; +} + +/** @param {string} pattern */ +function camelFromPattern(pattern) { + const kebab = toKebab(pattern); + const parts = kebab.split("-"); + return ( + parts[0] + + parts + .slice(1) + .map((p) => p.charAt(0).toUpperCase() + p.slice(1)) + .join("") + ); +} + +/** + * @param {string} dir + * @param {(filePath: string) => void} visit + */ +function walk(dir, visit) { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP_DIR_NAMES.has(entry.name)) continue; + walk(full, visit); + continue; + } + if (!entry.isFile()) continue; + const ext = entry.name.endsWith(".feature.md") + ? ".feature.md" + : path.extname(entry.name); + if (!SOURCE_SUFFIXES.has(ext)) continue; + // Do not rewrite our own generated SDP carriers or this script's outputs mid-pass. + if (entry.name.endsWith(".sdp.md") || entry.name.endsWith(".pack.sdp.md")) continue; + if (entry.name === "sdp-bindings.ts") continue; + visit(full); + } +} + +/** + * @param {string} content + */ +function stripArchitectTags(content) { + const lines = content.split("\n"); + const out = []; + let removed = 0; + + for (const line of lines) { + if (/^\s*\*\s*@architect(?:-[\w-]+)?(?:\s|$|:)/.test(line)) { + removed++; + continue; + } + if (/^@architect(?:-[\w-]+)?(?:$|[\s:])/.test(line.trim())) { + removed++; + continue; + } + out.push(line); + } + + let text = out.join("\n"); + text = text.replace(/\/\*\*\s*\n(?:\s*\*\s*\n)*\s*\*\//g, ""); + text = text.replace(/\/\*\*\n(\s*\*\s*\n)+/g, "/**\n"); + return { text, removed }; +} + +/** + * Only JSDoc / feature-tag lines; require PascalCase pattern tokens (reject prose hits). + * @param {string} content + */ +function extractBindingPatterns(content) { + const patterns = []; + const lineRe = + /^\s*(?:\*\s*)?@architect-(?:pattern|implements)[:\s]+([A-Z][A-Za-z0-9]*)\b/; + for (const line of content.split("\n")) { + const m = line.match(lineRe); + if (m) patterns.push(m[1]); + } + return patterns; +} + +/** + * @param {string} pattern + */ +function ensurePatternSpec(pattern) { + const kebab = toKebab(pattern); + const specDir = path.join(ROOT, "specs", "platform", "patterns"); + const specPath = path.join(specDir, `${kebab}.sdp.md`); + const id = patternToSpecId(pattern); + if (fs.existsSync(specPath)) return { specPath, created: false, id }; + + // Also skip if another family already carries this id (corpus migration may have authored it). + const existing = findSpecById(id); + if (existing) return { specPath: existing, created: false, id }; + + const content = `--- +id: ${id} +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ${pattern} + +## Intent + +- outcome: Preserve the former architect pattern "${pattern}" as an SDP Spec for delivery binding. +`; + + if (!DRY_RUN) { + fs.mkdirSync(specDir, { recursive: true }); + fs.writeFileSync(specPath, content); + } + return { specPath, created: true, id }; +} + +/** @param {string} id */ +function findSpecById(id) { + const specsRoot = path.join(ROOT, "specs"); + if (!fs.existsSync(specsRoot)) return null; + /** @type {string[]} */ + const found = []; + walkMarkdown(specsRoot, (filePath) => { + const text = fs.readFileSync(filePath, "utf8"); + if (text.includes(`id: ${id}`)) found.push(filePath); + }); + return found[0] ?? null; +} + +/** + * @param {string} dir + * @param {(filePath: string) => void} visit + */ +function walkMarkdown(dir, visit) { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP_DIR_NAMES.has(entry.name)) continue; + walkMarkdown(full, visit); + continue; + } + if (entry.name.endsWith(".sdp.md")) visit(full); + } +} + +const stats = { + scanned: 0, + strippedFiles: 0, + tagsRemoved: 0, + specsCreated: 0, + patterns: new Set(), +}; + +const scanRoots = [ + path.join(ROOT, "packages"), + path.join(ROOT, "examples"), + path.join(ROOT, "apps"), + path.join(ROOT, "specs"), + path.join(ROOT, "scripts"), +]; + +for (const root of scanRoots) { + if (!fs.existsSync(root)) continue; + walk(root, (filePath) => { + stats.scanned++; + const original = fs.readFileSync(filePath, "utf8"); + if (!original.includes("@architect")) return; + + for (const p of extractBindingPatterns(original)) { + stats.patterns.add(p); + } + + const { text, removed } = stripArchitectTags(original); + if (removed === 0) return; + + stats.strippedFiles++; + stats.tagsRemoved += removed; + if (!DRY_RUN && text !== original) { + fs.writeFileSync(filePath, text); + } + }); +} + +const sortedPatterns = [...stats.patterns].sort(); +for (const pattern of sortedPatterns) { + const result = ensurePatternSpec(pattern); + if (result.created) stats.specsCreated++; +} + +const bindingsPath = path.join(ROOT, "specs", "platform", "sdp-bindings.ts"); +const bindingsBody = + `import { codeAnchor, codeAnchorId, ref } from "@libar-dev/software-delivery-protocol";\n\n` + + `/**\n` + + ` * SDP identity bindings for the migrated platform delivery surface.\n` + + ` * One anchor per former architect pattern / implements target.\n` + + ` */\n\n` + + sortedPatterns + .map((pattern) => { + const exportName = `${camelFromPattern(pattern)}Anchor`; + return ( + `export const ${exportName} = codeAnchor({\n` + + ` id: codeAnchorId("${patternToAnchorId(pattern)}"),\n` + + ` label: ${JSON.stringify(pattern)},\n` + + ` satisfies: ref("${patternToSpecId(pattern)}"),\n` + + `});\n` + ); + }) + .join("\n"); + +if (!DRY_RUN) { + fs.mkdirSync(path.dirname(bindingsPath), { recursive: true }); + fs.writeFileSync(bindingsPath, bindingsBody); +} + +console.log( + JSON.stringify( + { + dryRun: DRY_RUN, + scanned: stats.scanned, + strippedFiles: stats.strippedFiles, + tagsRemoved: stats.tagsRemoved, + specsCreated: stats.specsCreated, + bindingsPath: path.relative(ROOT, bindingsPath), + uniquePatterns: sortedPatterns.length, + patterns: sortedPatterns, + }, + null, + 2, + ), +); diff --git a/scripts/migrate-executable-features.mjs b/scripts/migrate-executable-features.mjs new file mode 100644 index 00000000..fc62c323 --- /dev/null +++ b/scripts/migrate-executable-features.mjs @@ -0,0 +1,322 @@ +#!/usr/bin/env node +/** + * Migrate remaining executable Gherkin feature files (packages/examples/apps) + * into SDP Markdown Specs under specs/behavior/. + * + * One Spec per feature file; each refines a family epic so the graph stays connected. + * Cucumber .feature files stay in place as runtime tests (not SDP carriers). + * + * Usage: node scripts/migrate-executable-features.mjs [--dry-run] + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const DRY_RUN = process.argv.includes("--dry-run"); +const SPECS_ROOT = path.join(ROOT, "specs"); + +const SKIP_DIR = new Set(["node_modules", "dist", "generated", "coverage", ".git"]); + +/** @param {string} name */ +function toKebab(name) { + return name + .replace(/([a-z0-9])([A-Z])/g, "$1-$2") + .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2") + .replace(/_/g, "-") + .toLowerCase() + .replace(/[^a-z0-9-]+/g, "-") + .replace(/^-+|-+$/g, "") + .replace(/-+/g, "-"); +} + +/** Path segments must match /^[A-Za-z0-9][A-Za-z0-9-]*$/ */ +function sanitizeSegment(name) { + let s = toKebab(name); + if (!s) s = "unnamed"; + if (!/^[A-Za-z]/.test(s)) s = `n-${s}`; + return s; +} + +/** + * @param {string} dir + * @param {(filePath: string) => void} visit + */ +function walk(dir, visit) { + if (!fs.existsSync(dir)) return; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP_DIR.has(entry.name)) continue; + walk(full, visit); + continue; + } + if (entry.isFile() && entry.name.endsWith(".feature")) visit(full); + } +} + +/** + * @param {string} content + */ +function parseFeature(content) { + const lines = content.split("\n"); + let title = ""; + const intentLines = []; + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed.startsWith("@")) continue; + if (trimmed.startsWith("Feature:")) { + title = trimmed.slice("Feature:".length).trim(); + continue; + } + if ( + /^(Background:|Rule:|Scenario:|Scenario Outline:|Example:|# ===)/.test( + trimmed, + ) + ) { + break; + } + if (title && trimmed) intentLines.push(trimmed); + } + + const asA = intentLines.find((l) => /^As an?\b/i.test(l)); + const iWant = intentLines.find((l) => /^I want\b/i.test(l)); + const soThat = intentLines.find((l) => /^So that\b/i.test(l)); + let outcome = ""; + if (iWant && soThat) { + outcome = `${iWant.replace(/^I want\s+/i, "")} so that ${soThat.replace(/^So that\s+/i, "")}`; + } else if (soThat) { + outcome = soThat.replace(/^So that\s+/i, ""); + } else if (iWant) { + outcome = iWant.replace(/^I want\s+/i, ""); + } else if (asA) { + outcome = intentLines.slice(0, 3).join(" "); + } else { + outcome = intentLines.slice(0, 4).join(" ").slice(0, 400); + } + if (!outcome) outcome = `Capture executable behavior formerly carried in this Gherkin feature.`; + return { title, outcome: outcome.replace(/\s+/g, " ").trim().slice(0, 500) }; +} + +/** + * Map a feature file to family + relative stem under that family. + * @param {string} filePath + */ +function classify(filePath) { + const rel = path.relative(ROOT, filePath).split(path.sep).join("/"); + const parts = rel.split("/"); + /** @type {string} */ + let family; + /** @type {string[]} */ + let rest; + if (parts[0] === "packages") { + family = sanitizeSegment(parts[1] ?? "package"); + const testsIdx = parts.indexOf("tests"); + const featuresIdx = parts.indexOf("features"); + const cut = featuresIdx >= 0 ? featuresIdx + 1 : testsIdx >= 0 ? testsIdx + 1 : 2; + rest = parts.slice(cut); + if (rest[0] === "behavior") rest = rest.slice(1); + } else if (parts[0] === "examples") { + family = sanitizeSegment(parts[1] ?? "example"); + const featuresIdx = parts.indexOf("features"); + const cut = featuresIdx >= 0 ? featuresIdx + 1 : 2; + rest = parts.slice(cut); + if (rest[0] === "behavior") rest = rest.slice(1); + } else if (parts[0] === "apps") { + family = sanitizeSegment(parts[1] ?? "app"); + const featuresIdx = parts.indexOf("features"); + const testsIdx = parts.indexOf("tests"); + const cut = featuresIdx >= 0 ? featuresIdx + 1 : testsIdx >= 0 ? testsIdx + 1 : 2; + rest = parts.slice(cut); + if (rest[0] === "behavior") rest = rest.slice(1); + } else { + family = "misc"; + rest = parts.slice(1); + } + const file = rest.pop() ?? "feature.feature"; + const stem = sanitizeSegment(file.replace(/\.feature$/i, "")); + const dirs = rest.map(sanitizeSegment).filter(Boolean); + return { family, dirs, stem, rel }; +} + +/** @type {Set} */ +const usedIds = new Set(); + +function collectExistingIds() { + if (!fs.existsSync(SPECS_ROOT)) return; + walkMarkdown(SPECS_ROOT, (p) => { + if (p.endsWith(".pack.sdp.md")) return; + const text = fs.readFileSync(p, "utf8"); + const m = text.match(/^id:\s*(\S+)/m); + if (m) usedIds.add(m[1]); + }); +} + +/** + * @param {string} dir + * @param {(filePath: string) => void} visit + */ +function walkMarkdown(dir, visit) { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP_DIR.has(entry.name)) continue; + walkMarkdown(full, visit); + continue; + } + if (entry.name.endsWith(".sdp.md")) visit(full); + } +} + +/** + * @param {string} preferred + */ +function uniqueId(preferred) { + if (!usedIds.has(preferred)) { + usedIds.add(preferred); + return preferred; + } + let i = 2; + while (usedIds.has(`${preferred}-${i}`)) i++; + const id = `${preferred}-${i}`; + usedIds.add(id); + return id; +} + +collectExistingIds(); + +/** @type {Map} */ +const epics = new Map(); + +function ensureEpic(family) { + if (epics.has(family)) return epics.get(family); + const id = uniqueId(`spec:behavior.${family}`); + const title = `${family} executable behavior`; + const outPath = path.join(SPECS_ROOT, "behavior", family, `_epic.sdp.md`); + const body = `--- +id: ${id} +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# ${title} + +## Intent + +- outcome: Hold the executable Gherkin behavior Specs migrated from the ${family} test corpus. +`; + if (!DRY_RUN) { + fs.mkdirSync(path.dirname(outPath), { recursive: true }); + fs.writeFileSync(outPath, body); + } + const epic = { id, title, outPath }; + epics.set(family, epic); + return epic; +} + +/** @type {{ id: string, family: string, outPath: string, source: string }[]} */ +const created = []; +const features = []; +for (const root of [ + path.join(ROOT, "packages"), + path.join(ROOT, "examples"), + path.join(ROOT, "apps"), +]) { + walk(root, (filePath) => features.push(filePath)); +} +features.sort(); + +for (const filePath of features) { + const { family, dirs, stem, rel } = classify(filePath); + const epic = ensureEpic(family); + const pathSegs = ["behavior", family, ...dirs, stem]; + const preferredId = `spec:${pathSegs.join(".")}`; + const id = uniqueId(preferredId); + const { title, outcome } = parseFeature(fs.readFileSync(filePath, "utf8")); + const outPath = path.join(SPECS_ROOT, ...pathSegs) + ".sdp.md"; + const displayTitle = title || stem; + const body = `--- +id: ${id} +kind: behavior +altitude: story +readiness: idea +relations: + refines: ${epic.id} +--- +# ${displayTitle} + +## Intent + +- outcome: ${outcome} (test carrier: ${rel}) +`; + if (!DRY_RUN) { + fs.mkdirSync(path.dirname(outPath), { recursive: true }); + fs.writeFileSync(outPath, body); + } + created.push({ id, family, outPath, source: rel }); +} + +// Packs: one per family + an umbrella pack +/** @type {Map} */ +const byFamily = new Map(); +for (const item of created) { + const list = byFamily.get(item.family) ?? []; + list.push(item.id); + byFamily.set(item.family, list); +} + +function writePack(outPath, packId, title, framing, ids) { + const unique = [...new Set(ids)].sort(); + const body = `--- +id: ${packId} +specs: +${unique.map((s) => ` - ${s}`).join("\n")} +--- +# ${title} + +${framing} +`; + if (!DRY_RUN) { + fs.mkdirSync(path.dirname(outPath), { recursive: true }); + fs.writeFileSync(outPath, body); + } +} + +const umbrella = []; +for (const [family, ids] of [...byFamily.entries()].sort()) { + const epic = epics.get(family); + const members = epic ? [epic.id, ...ids] : ids; + umbrella.push(...members); + writePack( + path.join(SPECS_ROOT, `behavior-${family}.pack.sdp.md`), + `pack:behavior-${family}`, + `${family} behavior`, + `Executable Gherkin behavior Specs migrated from the ${family} test corpus.`, + members, + ); +} +writePack( + path.join(SPECS_ROOT, "behavior.pack.sdp.md"), + "pack:behavior", + "Executable behavior", + "All executable Gherkin behavior Specs migrated from packages, examples, and apps.", + umbrella, +); + +console.log( + JSON.stringify( + { + dryRun: DRY_RUN, + featuresScanned: features.length, + specsCreated: created.length, + epics: [...epics.keys()], + byFamily: Object.fromEntries( + [...byFamily.entries()].map(([k, v]) => [k, v.length]), + ), + }, + null, + 2, + ), +); diff --git a/scripts/migrate-scenarios-and-unimplemented.mjs b/scripts/migrate-scenarios-and-unimplemented.mjs new file mode 100644 index 00000000..838c8147 --- /dev/null +++ b/scripts/migrate-scenarios-and-unimplemented.mjs @@ -0,0 +1,325 @@ +#!/usr/bin/env node +/** + * Migrate (1) every Gherkin Scenario as an SDP example Spec and + * (2) non-implemented architect deliverables / remaining-work items + * as idea-rung behavior Specs. + * + * Usage: node scripts/migrate-scenarios-and-unimplemented.mjs [--dry-run] + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const SPECS = path.join(ROOT, "specs"); +const DRY_RUN = process.argv.includes("--dry-run"); +const SKIP = new Set(["node_modules", "dist", "generated", "coverage", ".git"]); + +function toKebab(name) { + return String(name) + .replace(/([a-z0-9])([A-Z])/g, "$1-$2") + .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2") + .replace(/_/g, "-") + .toLowerCase() + .replace(/[^a-z0-9-]+/g, "-") + .replace(/^-+|-+$/g, "") + .replace(/-+/g, "-"); +} + +function sanitizeSegment(name) { + let s = toKebab(name); + if (!s) s = "unnamed"; + if (!/^[A-Za-z]/.test(s)) s = `n-${s}`; + if (s.length > 80) s = s.slice(0, 80).replace(/-+$/g, ""); + return s; +} + +function walk(dir, pred, out = []) { + if (!fs.existsSync(dir)) return out; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP.has(entry.name)) continue; + walk(full, pred, out); + continue; + } + if (entry.isFile() && pred(full, entry.name)) out.push(full); + } + return out; +} + +function relPosix(filePath) { + return path.relative(ROOT, filePath).split(path.sep).join("/"); +} + +/** @type {Set} */ +const usedIds = new Set(); + +function loadExistingIdsAndParents() { + /** @type {Map} */ + const carrierToId = new Map(); + /** @type {Map} */ + const stemToId = new Map(); + /** @type {Map} */ + const idToFile = new Map(); + for (const file of walk(SPECS, (p, name) => name.endsWith(".sdp.md") && !name.endsWith(".pack.sdp.md"))) { + const text = fs.readFileSync(file, "utf8"); + const idMatch = text.match(/^id:\s*(\S+)/m); + if (!idMatch) continue; + usedIds.add(idMatch[1]); + idToFile.set(idMatch[1], file); + const carrier = text.match(/test carrier:\s*([^)\n]+)/); + if (carrier) carrierToId.set(carrier[1].trim(), idMatch[1]); + stemToId.set(path.basename(file, ".sdp.md"), idMatch[1]); + } + return { carrierToId, stemToId, idToFile }; +} + +function uniqueId(preferred) { + if (!usedIds.has(preferred)) { + usedIds.add(preferred); + return preferred; + } + let i = 2; + while (usedIds.has(`${preferred}-${i}`)) i++; + const id = `${preferred}-${i}`; + usedIds.add(id); + return id; +} + +function parseScenarios(content) { + const lines = content.split("\n"); + /** @type {{ title: string, outline: boolean, line: number }[]} */ + const out = []; + for (let i = 0; i < lines.length; i++) { + const m = lines[i].match(/^\s*Scenario(?: Outline)?:\s*(.*)$/); + if (!m) continue; + out.push({ + title: (m[1] ?? "").trim() || `scenario-${out.length + 1}`, + outline: /^\s*Scenario Outline:/.test(lines[i]), + line: i + 1, + }); + } + return out; +} + +function parsePendingDeliverables(content) { + const rows = []; + for (const line of content.split("\n")) { + if (!/\|\s*pending\s*\|/i.test(line)) continue; + const cells = line + .split("|") + .map((c) => c.trim()) + .filter((c) => c.length > 0); + if (cells.length < 2) continue; + if (/^deliverable$/i.test(cells[0])) continue; + rows.push({ name: cells[0], status: "pending", location: cells[2] ?? "" }); + } + return rows; +} + +function writeSpec(outPath, body) { + if (DRY_RUN) return; + fs.mkdirSync(path.dirname(outPath), { recursive: true }); + fs.writeFileSync(outPath, body); +} + +function specBody({ id, kind, altitude, parent, title, outcome }) { + const relations = parent + ? `relations:\n refines: ${parent}` + : "relations: {}"; + return `--- +id: ${id} +kind: ${kind} +altitude: ${altitude} +readiness: idea +${relations} +--- +# ${title} + +## Intent + +- outcome: ${outcome} +`; +} + +const { carrierToId, stemToId, idToFile } = loadExistingIdsAndParents(); + +const unimplementedEpicId = uniqueId("spec:unimplemented.backlog"); +writeSpec( + path.join(SPECS, "unimplemented", "_epic.sdp.md"), + specBody({ + id: unimplementedEpicId, + kind: "behavior", + altitude: "epic", + parent: null, + title: "Unimplemented delivery backlog", + outcome: + "Hold non-implemented architect deliverables and remaining-work items until they are authored to a higher readiness rung.", + }), +); + +let exampleCount = 0; +let unimplementedCount = 0; +/** @type {string[]} */ +const unimplementedIds = [unimplementedEpicId]; +/** @type {Map} */ +const examplesByParent = new Map(); + +function addExample(parentId, id) { + const list = examplesByParent.get(parentId) ?? []; + list.push(id); + examplesByParent.set(parentId, list); +} + +function migrateFeatureScenarios(filePath, parentId, destDir, kindLabel) { + const rel = relPosix(filePath); + const scenarios = parseScenarios(fs.readFileSync(filePath, "utf8")); + scenarios.forEach((scenario, index) => { + const slug = sanitizeSegment(scenario.title); + const seq = String(index + 1).padStart(3, "0"); + const id = uniqueId(`${parentId}.${slug}`); + const fileName = `${sanitizeSegment(`s-${seq}-${slug}`)}.sdp.md`; + const title = scenario.title.replace(/"/g, "'").replace(/<([^>]+)>/g, "$1"); + const outcome = `${kindLabel} "${title}" from ${rel}`; + writeSpec( + path.join(destDir, fileName), + specBody({ + id, + kind: "example", + altitude: "story", + parent: parentId, + title, + outcome, + }), + ); + addExample(parentId, id); + exampleCount++; + }); + return scenarios.length; +} + +// --- executable tests (packages / examples / apps) --- +for (const rootName of ["packages", "examples", "apps"]) { + for (const filePath of walk(path.join(ROOT, rootName), (p, name) => + name.endsWith(".feature"), + ).sort()) { + const rel = relPosix(filePath); + const parentId = carrierToId.get(rel); + if (!parentId) { + console.error(`missing parent Spec for ${rel}`); + continue; + } + const parentFile = idToFile.get(parentId); + const destDir = parentFile + ? path.join(path.dirname(parentFile), path.basename(parentFile, ".sdp.md") + ".examples") + : path.join(SPECS, "behavior", "unmapped.examples"); + migrateFeatureScenarios(filePath, parentId, destDir, "Executable scenario"); + } +} + +// --- architect scenarios (design / often unimplemented) --- +for (const filePath of walk(path.join(ROOT, "docs", "lineage", "architect"), (p, name) => + name.endsWith(".feature"), +).sort()) { + const stem = path.basename(filePath, ".feature"); + const parentId = stemToId.get(toKebab(stem)) ?? stemToId.get(stem) ?? unimplementedEpicId; + const destDir = path.join(SPECS, "unimplemented", "architect-scenarios", sanitizeSegment(stem)); + migrateFeatureScenarios(filePath, parentId, destDir, "Architect scenario (not an SDP test carrier)"); +} + +// --- pending deliverable rows --- +for (const filePath of walk(path.join(ROOT, "docs", "lineage", "architect"), (p, name) => + name.endsWith(".feature"), +).sort()) { + const stem = path.basename(filePath, ".feature"); + const parentId = stemToId.get(toKebab(stem)) ?? stemToId.get(stem) ?? unimplementedEpicId; + const rows = parsePendingDeliverables(fs.readFileSync(filePath, "utf8")); + rows.forEach((row, index) => { + const slug = sanitizeSegment(row.name); + const seq = String(index + 1).padStart(3, "0"); + const id = uniqueId(`spec:unimplemented.${sanitizeSegment(stem)}.${slug}`); + const title = row.name.replace(/"/g, "'").replace(/<([^>]+)>/g, "$1"); + writeSpec( + path.join( + SPECS, + "unimplemented", + "deliverables", + sanitizeSegment(stem), + `${sanitizeSegment(`d-${seq}-${slug}`)}.sdp.md`, + ), + specBody({ + id, + kind: "behavior", + altitude: "story", + parent: parentId, + title, + outcome: `Unimplemented deliverable "${title}" from ${relPosix(filePath)}${row.location ? ` at ${row.location}` : ""}.`, + }), + ); + unimplementedIds.push(id); + unimplementedCount++; + }); +} + +// --- docs-living remaining + current (non-implemented / in-flight) --- +for (const folder of ["remaining", "current"]) { + const dir = path.join(ROOT, "docs-living", folder); + if (!fs.existsSync(dir)) continue; + for (const name of fs.readdirSync(dir).filter((n) => n.endsWith(".md")).sort()) { + const filePath = path.join(dir, name); + const text = fs.readFileSync(filePath, "utf8"); + const heading = (text.match(/^#\s+(.+)$/m)?.[1] ?? name).trim(); + const slug = sanitizeSegment(name.replace(/\.md$/, "")); + const id = uniqueId(`spec:unimplemented.${folder}.${slug}`); + writeSpec( + path.join(SPECS, "unimplemented", folder, `${slug}.sdp.md`), + specBody({ + id, + kind: "behavior", + altitude: "feature", + parent: unimplementedEpicId, + title: heading.replace(/"/g, "'"), + outcome: `Non-implemented or in-flight work captured from docs-living/${folder}/${name}.`, + }), + ); + unimplementedIds.push(id); + unimplementedCount++; + } +} + +function writePack(outPath, packId, title, framing, ids) { + const unique = [...new Set(ids)].sort(); + const body = `--- +id: ${packId} +specs: +${unique.map((s) => ` - ${s}`).join("\n")} +--- +# ${title} + +${framing} +`; + writeSpec(outPath, body); +} + +writePack( + path.join(SPECS, "unimplemented.pack.sdp.md"), + "pack:unimplemented", + "Unimplemented", + "Non-implemented architect deliverables, remaining-work items, and in-flight docs-living rows.", + unimplementedIds, +); + +console.log( + JSON.stringify( + { + dryRun: DRY_RUN, + exampleSpecs: exampleCount, + unimplementedSpecs: unimplementedCount, + parentsWithExamples: examplesByParent.size, + knownCarriers: carrierToId.size, + }, + null, + 2, + ), +); diff --git a/scripts/rewrite-spec-content.py b/scripts/rewrite-spec-content.py new file mode 100644 index 00000000..9777c56a --- /dev/null +++ b/scripts/rewrite-spec-content.py @@ -0,0 +1,408 @@ +#!/usr/bin/env python3 +"""Fill migrated SDP Specs with actual Gherkin/architect content (not title-only stubs).""" +from __future__ import annotations + +import re +from pathlib import Path + +ROOT = Path("/home/darkomijic/dev-libar/libar-platform") +SPECS = ROOT / "specs" +SKIP = {"node_modules", "dist", "generated", ".git"} + + +def walk_features() -> list[Path]: + out = [] + for p in ROOT.rglob("*.feature"): + if any(s in p.parts for s in SKIP): + continue + out.append(p) + return sorted(out) + + +def sanitize_prose(text: str, limit: int = 700) -> str: + text = re.sub(r"<[^>\n]+>", " ", text) + text = text.replace("|", " / ").replace("`", "'").replace("<", "(").replace(">", ")") + text = re.sub(r"\s+", " ", text).strip() + if len(text) > limit: + text = text[: limit - 1].rstrip() + "…" + return text + + +def sanitize_step(text: str) -> str: + text = re.sub(r"<[^>\n]+>", "value", text) + text = text.replace("|", " ").replace("`", "'") + text = re.sub(r"\s+", " ", text).strip() + if not text: + text = "the fixture holds" + if len(text) > 240: + text = text[:239].rstrip() + "…" + return text + + +def parse_feature(path: Path) -> dict: + lines = path.read_text(errors="ignore").splitlines() + title = "" + header: list[str] = [] + rules: list[str] = [] + background: list[tuple[str, str]] = [] + scenarios: list[dict] = [] + mode = "header" + current: dict | None = None + pending_step: tuple[str, str] | None = None + in_table = False + in_doc = False + doc_buf: list[str] = [] + + def flush_doc(): + nonlocal pending_step, in_doc, doc_buf + if pending_step and doc_buf: + extra = sanitize_step(" ".join(doc_buf)[:200]) + pending_step = (pending_step[0], pending_step[1] + " " + extra) + in_doc = False + doc_buf = [] + + def attach_step(kw: str, text: str): + nonlocal pending_step + pending_step = (kw, sanitize_step(text)) + if mode == "background": + background.append(pending_step) + elif current is not None: + current["steps"].append(pending_step) + + i = 0 + while i < len(lines): + raw = lines[i] + stripped = raw.strip() + i += 1 + if in_doc: + if stripped in ('"""', "'''"): + flush_doc() + else: + doc_buf.append(stripped) + continue + if stripped in ('"""', "'''"): + in_doc = True + doc_buf = [] + continue + if stripped.startswith("|"): + in_table = True + continue + if in_table and not stripped.startswith("|"): + in_table = False + if not stripped or stripped.startswith("#") or stripped.startswith("@"): + continue + if stripped.startswith("Feature:"): + title = stripped[len("Feature:") :].strip() + mode = "header" + continue + if stripped.startswith("Background:"): + mode = "background" + current = None + continue + if stripped.startswith("Rule:"): + rules.append(sanitize_prose(stripped[len("Rule:") :].strip(), 240)) + mode = "rule" + current = None + continue + m_sc = re.match(r"Scenario(?: Outline)?:\s*(.*)$", stripped) + if m_sc: + current = {"title": (m_sc.group(1) or "").strip(), "steps": []} + scenarios.append(current) + mode = "scenario" + continue + m_st = re.match(r"^(Given|When|Then|And|But)\s+(.*)$", stripped) + if m_st: + kw = m_st.group(1) + if kw == "But": + kw = "And" + attach_step(kw, m_st.group(2)) + continue + if mode == "header" and title: + header.append(stripped) + + as_a = next((h for h in header if re.match(r"^As an?\b", h, re.I)), "") + i_want = next((h for h in header if re.match(r"^I want\b", h, re.I)), "") + so_that = next((h for h in header if re.match(r"^So that\b", h, re.I)), "") + problem = "" + solution = "" + blob = " ".join(header) + pm = re.search(r"\*\*Problem:?\*\*\s*(.+?)(?=\*\*[A-Z]|\Z)", blob) + sm = re.search(r"\*\*Solution:?\*\*\s*(.+?)(?=\*\*[A-Z]|\Z)", blob) + if pm: + problem = sanitize_prose(pm.group(1), 500) + if sm: + solution = sanitize_prose(sm.group(1), 500) + outcome = "" + if i_want and so_that: + outcome = sanitize_prose( + f"{i_want[len('I want'):].strip()} so that {so_that[len('So that'):].strip()}", + 500, + ) + elif so_that: + outcome = sanitize_prose(so_that[len("So that") :].strip(), 500) + elif i_want: + outcome = sanitize_prose(i_want[len("I want") :].strip(), 500) + elif problem: + outcome = problem + else: + outcome = sanitize_prose(title or path.stem, 400) + return { + "title": title or path.stem, + "actor": sanitize_prose(as_a[len("As ") :].strip() if as_a.lower().startswith("as ") else as_a, 200) + if as_a + else "", + "outcome": outcome, + "problem": problem, + "solution": solution, + "rules": [r for r in rules if r], + "background": background, + "scenarios": scenarios, + "rel": str(path.relative_to(ROOT)).replace("\\", "/"), + } + + +def to_gwt(background: list[tuple[str, str]], steps: list[tuple[str, str]]) -> list[str]: + given: list[str] = [] + when: list[str] = [] + then: list[str] = [] + phase = None + for kw, text in background + steps: + if kw in ("Given", "When", "Then"): + phase = kw + elif kw == "And" and phase is None: + phase = "Given" + if phase == "Given": + given.append(text) + elif phase == "When": + when.append(text) + else: + then.append(text) + if not given: + given = ["the feature fixture is in place"] + if not when: + when = ["the scenario runs"] + if len(when) > 1: + when = [sanitize_step(" and ".join(when))] + if not then: + then = ["the expected outcome holds"] + lines = [f"Given {given[0]}"] + for g in given[1:]: + lines.append(f"And {g}") + lines.append(f"When {when[0]}") + lines.append(f"Then {then[0]}") + for t in then[1:]: + lines.append(f"And {t}") + return lines + + +def yaml_escape_title(title: str) -> str: + title = title.replace('"', "'") + title = re.sub(r"<[^>\n]+>", "value", title) + title = title.replace("<", "(").replace(">", ")") + return title.strip() or "Untitled scenario" + + +def write(path: Path, body: str) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(body if body.endswith("\n") else body + "\n") + + +def load_id_maps(): + carrier_to_file: dict[str, Path] = {} + stem_to_file: dict[str, Path] = {} + id_of: dict[Path, str] = {} + for p in SPECS.rglob("*.sdp.md"): + if p.name.endswith(".pack.sdp.md"): + continue + text = p.read_text() + m = re.search(r"^id:\s*(\S+)", text, re.M) + if not m: + continue + id_of[p] = m.group(1) + c = re.search(r"test carrier:\s*([^)\n]+)", text) + if c: + carrier_to_file[c.group(1).strip()] = p + stem_to_file[spec_stem(p)] = p + return carrier_to_file, stem_to_file, id_of + + +def spec_stem(path: Path) -> str: + name = path.name + if name.endswith(".sdp.md"): + return name[: -len(".sdp.md")] + return path.stem + + +def parent_examples_dir(parent: Path) -> Path: + return parent.parent / (spec_stem(parent) + ".examples") + + +def kebab(name: str) -> str: + s = re.sub(r"([a-z0-9])([A-Z])", r"\1-\2", name) + s = s.replace("_", "-").lower() + s = re.sub(r"[^a-z0-9-]+", "-", s) + return re.sub(r"-+", "-", s).strip("-") + + +carrier_to_file, stem_to_file, id_of = load_id_maps() + +rewritten_parents = 0 +rewritten_examples = 0 +rewritten_unimpl = 0 +missing_parent = 0 +gwt_examples = 0 + + +def rewrite_parent(parent: Path, feat: dict, kind: str) -> None: + global rewritten_parents + sid = id_of.get(parent) + if not sid: + return + # keep existing frontmatter kind/altitude/readiness/relations + old = parent.read_text() + fm = re.match(r"^---\n(.*?)\n---\n", old, re.S) + if not fm: + return + front = fm.group(1) + # force kind if missing + intent_lines = [f"- outcome: {feat['outcome']}"] + if feat["actor"]: + intent_lines.insert(0, f"- actor: {feat['actor']}") + if feat["problem"]: + intent_lines.append(f"- problem: {feat['problem']}") + if feat["solution"]: + intent_lines.append(f"- value: {feat['solution']}") + body = f"---\n{front}\n---\n# {yaml_escape_title(feat['title'])}\n\n## Intent\n\n" + body += "\n".join(intent_lines) + "\n" + if feat["rules"] and "kind: decision" not in front and "kind: example" not in front: + body += "\n## Behavior\n\n" + for rule in feat["rules"][:40]: + body += f"- rule: {rule}\n" + if "kind: decision" in front: + ruling = feat["solution"] or feat["outcome"] + body += "\n## Decision\n\n" + body += f"- ruling: {ruling}\n" + write(parent, body) + rewritten_parents += 1 + + +def rewrite_examples(parent: Path, feat: dict) -> None: + global rewritten_examples, gwt_examples + dest = parent_examples_dir(parent) + if not dest.is_dir(): + # architect scenarios live under unimplemented/architect-scenarios/ + alt = SPECS / "unimplemented" / "architect-scenarios" / kebab(Path(feat["rel"]).stem) + dest = alt if alt.is_dir() else dest + files = sorted(dest.glob("s-*.sdp.md")) if dest.is_dir() else [] + for idx, scenario in enumerate(feat["scenarios"]): + target = None + seq = f"s-{idx + 1:03d}-" + for f in files: + if f.name.startswith(seq): + target = f + break + if target is None: + continue + old = target.read_text() + fm = re.match(r"^---\n(.*?)\n---\n", old, re.S) + if not fm: + continue + front = fm.group(1) + title = yaml_escape_title(scenario["title"] or f"scenario {idx + 1}") + gwt = to_gwt(feat["background"], scenario["steps"]) + outcome = sanitize_prose(f"Executable scenario: {title}", 400) + body = ( + f"---\n{front}\n---\n# {title}\n\n## Intent\n\n" + f"- outcome: {outcome}\n\n" + "```gwt\n" + "\n".join(gwt) + "\n```\n" + ) + write(target, body) + rewritten_examples += 1 + gwt_examples += 1 + + +for path in walk_features(): + feat = parse_feature(path) + rel = feat["rel"] + parent = carrier_to_file.get(rel) + if parent is None: + stem = kebab(path.stem) + parent = stem_to_file.get(stem) or stem_to_file.get(path.stem) + if parent is None: + missing_parent += 1 + continue + kind = "behavior" + rewrite_parent(parent, feat, kind) + rewrite_examples(parent, feat) + +# Unimplemented remaining/current: copy sanitized prose into Intent description +for folder in ("remaining", "current"): + src_dir = ROOT / "docs-living" / folder + dest_dir = SPECS / "unimplemented" / folder + if not dest_dir.is_dir(): + continue + for dest in dest_dir.glob("*.sdp.md"): + src = src_dir / (spec_stem(dest) + ".md") + if not src.exists(): + continue + raw = src.read_text(errors="ignore") + # drop tables + raw = re.sub(r"(?m)^\s*\|.*$", " ", raw) + raw = re.sub(r"[#*`]", " ", raw) + prose = sanitize_prose(raw, 800) + old = dest.read_text() + fm = re.match(r"^---\n(.*?)\n---\n", old, re.S) + if not fm: + continue + title_m = re.search(r"^#\s+(.+)$", old, re.M) + title = title_m.group(1) if title_m else dest.stem + outcome_m = re.search(r"^- outcome:\s+(.+)$", old, re.M) + outcome = outcome_m.group(1) if outcome_m else prose[:300] + body = ( + f"---\n{fm.group(1)}\n---\n# {yaml_escape_title(title)}\n\n## Intent\n\n" + f"{prose}\n\n- outcome: {sanitize_prose(outcome, 400)}\n" + ) + write(dest, body) + rewritten_unimpl += 1 + +# Unimplemented deliverables: attach parent problem/solution as problem/value +parent_by_id = {sid: p for p, sid in id_of.items()} +for dest in (SPECS / "unimplemented" / "deliverables").rglob("*.sdp.md"): + old = dest.read_text() + fm = re.match(r"^---\n(.*?)\n---\n", old, re.S) + if not fm: + continue + ref = re.search(r"refines:\s*(\S+)", fm.group(1)) + title_m = re.search(r"^#\s+(.+)$", old, re.M) + title = title_m.group(1) if title_m else dest.stem + loc_m = re.search(r" at ([^.\n]+)", old) + loc = loc_m.group(1).strip() if loc_m else "" + problem = "" + if ref and ref.group(1) in {id_of[p] for p in id_of}: + parent_path = next((p for p, sid in id_of.items() if sid == ref.group(1)), None) + if parent_path and parent_path.exists(): + pt = parent_path.read_text() + pm = re.search(r"^- problem:\s+(.+)$", pt, re.M) + if pm: + problem = pm.group(1) + outcome = sanitize_prose( + f"Unimplemented deliverable: {title}" + (f" at {loc}" if loc else ""), + 400, + ) + lines = [f"- outcome: {outcome}"] + if problem: + lines.append(f"- problem: {sanitize_prose(problem, 400)}") + body = f"---\n{fm.group(1)}\n---\n# {yaml_escape_title(title)}\n\n## Intent\n\n" + "\n".join(lines) + "\n" + write(dest, body) + rewritten_unimpl += 1 + +print( + { + "rewritten_parents": rewritten_parents, + "rewritten_examples": rewritten_examples, + "gwt_examples": gwt_examples, + "rewritten_unimpl": rewritten_unimpl, + "missing_parent": missing_parent, + "features": len(walk_features()), + } +) diff --git a/scripts/sdp-honesty-repair.mjs b/scripts/sdp-honesty-repair.mjs new file mode 100644 index 00000000..43cf843c --- /dev/null +++ b/scripts/sdp-honesty-repair.mjs @@ -0,0 +1,223 @@ +#!/usr/bin/env node +/** + * Repair honesty-floor errors left by the migrate-specs-to-sdp run: + * - 64 examples stated defined but derived only scoped (unbound/malformed slots) + * - 27 decisions stated defined with no authored relation + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const SPECS = path.join(ROOT, "specs"); + +const EXAMPLE_IDS = new Set([ + "spec:behavior.frontend.admin.agent-approvals.click-approval-card-to-navigate-to-detail", + "spec:behavior.platform-core.dcb.scope-key.create-valid-scope-key-from-components", + "spec:behavior.platform-core.dcb.scope-key.scope-id-may-contain-colons-for-composite-identifiers", + "spec:behavior.platform-core.dcb.scope-key.create-scope-key-throws-on-invalid-input", + "spec:behavior.platform-core.dcb.scope-key.try-create-scope-key-returns-scope-key-for-valid-input", + "spec:behavior.platform-core.dcb.scope-key.try-create-scope-key-returns-null-for-invalid-input", + "spec:behavior.platform-core.dcb.scope-key.parse-valid-scope-key-into-components", + "spec:behavior.platform-core.dcb.scope-key.parse-scope-key-with-composite-scope-id-containing-colons", + "spec:behavior.platform-core.dcb.scope-key.parse-scope-key-returns-null-for-invalid-format", + "spec:behavior.platform-core.dcb.scope-key.validate-scope-key-returns-null-for-valid-scope-key", + "spec:behavior.platform-core.dcb.scope-key.validate-scope-key-returns-scope-key-empty-error-for-empty-string", + "spec:behavior.platform-core.dcb.scope-key.validate-scope-key-returns-error-for-missing-tenant-prefix", + "spec:behavior.platform-core.dcb.scope-key.validate-scope-key-returns-error-for-malformed-scope-key", + "spec:behavior.platform-core.dcb.scope-key.is-valid-scope-key-type-guard", + "spec:behavior.platform-core.dcb.scope-key.assert-valid-scope-key-throws-on-invalid-input", + "spec:behavior.platform-core.dcb.scope-key.assert-valid-scope-key-succeeds-on-valid-input", + "spec:behavior.platform-core.dcb.scope-key.is-scope-tenant-checks-tenant-membership", + "spec:behavior.platform-core.dcb.scope-key.extract-tenant-id-returns-tenant-id-from-scope-key", + "spec:behavior.platform-core.dcb.scope-key.extract-scope-type-returns-scope-type-from-scope-key", + "spec:behavior.platform-core.dcb.scope-key.extract-scope-id-returns-scope-id-from-scope-key", + "spec:behavior.platform-core.ecst.fat-event-builder.create-fat-event-with-schema-definition", + "spec:behavior.platform-core.ecst.fat-event-builder.schema-validation-failure", + "spec:behavior.platform-core.ecst.fat-event-builder.create-fat-event-with-correlation-id", + "spec:behavior.platform-core.ecst.privacy-markers.mark-single-field-for-shredding", + "spec:behavior.platform-core.ecst.privacy-markers.mark-multiple-fields-for-shredding", + "spec:behavior.platform-core.ecst.privacy-markers.non-pii-fields-are-not-marked", + "spec:behavior.platform-core.ecst.privacy-markers.mark-fields-in-collection-items", + "spec:behavior.platform-core.reservation.confirm-operation.confirm-reservation-with-entity-id", + "spec:behavior.platform-core.reservation.confirm-operation.cannot-confirm-expired-reservation", + "spec:behavior.platform-core.reservation.confirm-operation.cannot-confirm-already-confirmed-reservation", + "spec:behavior.platform-core.reservation.confirm-operation.cannot-confirm-non-existent-reservation", + "spec:behavior.platform-core.reservation.confirm-operation.cannot-confirm-released-reservation", + "spec:behavior.platform-core.reservation.confirm-operation.entity-id-is-required", + "spec:behavior.platform-core.reservation.confirm-operation.entity-id-can-be-any-string-identifier", + "spec:behavior.platform-core.reservation.release-operation.release-active-reservation", + "spec:behavior.platform-core.reservation.release-operation.released-value-can-be-immediately-reserved", + "spec:behavior.platform-core.reservation.release-operation.cannot-release-confirmed-reservation", + "spec:behavior.platform-core.reservation.release-operation.cannot-release-already-released-reservation", + "spec:behavior.platform-core.reservation.release-operation.cannot-release-expired-reservation", + "spec:behavior.platform-core.reservation.release-operation.cannot-release-non-existent-reservation", + "spec:behavior.platform-core.reservation.reservation-key.email-reservation-key-format", + "spec:behavior.platform-core.reservation.reservation-key.username-reservation-key-format", + "spec:behavior.platform-core.reservation.reservation-key.custom-type-reservation-key-format", + "spec:behavior.platform-core.reservation.reservation-key.same-value-different-types", + "spec:behavior.platform-core.reservation.reservation-key.independent-type-uniqueness", + "spec:behavior.platform-core.reservation.reservation-key.type-is-required", + "spec:behavior.platform-core.reservation.reservation-key.value-is-required", + "spec:behavior.platform-core.reservation.reservation-key.empty-type-is-invalid", + "spec:behavior.platform-core.reservation.reservation-key.empty-value-is-invalid", + "spec:behavior.platform-core.reservation.reservation-key.find-reservation-by-key", + "spec:behavior.platform-core.reservation.reservation-key.find-reservation-by-type-and-value", + "spec:behavior.platform-core.reservation.reservation-key.non-existent-key-returns-null", + "spec:behavior.platform-core.reservation.reservation-key.type-containing-colon-is-rejected", + "spec:behavior.platform-core.reservation.reservation-key.value-can-contain-colon-url-with-port", + "spec:behavior.platform-core.reservation.reserve-operation.reserve-an-email-address", + "spec:behavior.platform-core.reservation.reserve-operation.reserve-with-correlation-id", + "spec:behavior.platform-core.reservation.reserve-operation.reserved-value-cannot-be-re-reserved", + "spec:behavior.platform-core.reservation.reserve-operation.ttl-must-be-positive", + "spec:behavior.platform-core.reservation.reserve-operation.ttl-has-maximum-limit", + "spec:behavior.platform-core.reservation.reserve-operation.negative-ttl-is-rejected", + "spec:behavior.platform-core.reservation.reserve-operation.ttl-at-minimum-boundary-succeeds", + "spec:behavior.platform-core.reservation.reserve-operation.ttl-just-below-minimum-is-rejected", + "spec:behavior.platform-core.reservation.reserve-operation.whitespace-only-type-is-invalid", + "spec:behavior.platform-core.reservation.reserve-operation.whitespace-only-value-is-invalid", +]); + +function walk(dir, out = []) { + for (const name of fs.readdirSync(dir)) { + if (name === "generated" || name === "node_modules") continue; + const full = path.join(dir, name); + const st = fs.statSync(full); + if (st.isDirectory()) walk(full, out); + else if (name.endsWith(".sdp.md") && !name.endsWith(".pack.sdp.md")) out.push(full); + } + return out; +} + +function split(text) { + if (!text.startsWith("---\n")) return null; + const end = text.indexOf("\n---\n", 4); + if (end === -1) return null; + return { fm: text.slice(4, end), body: text.slice(end + 5) }; +} + +function field(fm, name) { + const m = fm.match(new RegExp(`^${name}:\\s*(.*)$`, "m")); + return m ? m[1].trim() : ""; +} + +function setField(fm, name, value) { + return fm.replace(new RegExp(`^${name}:\\s*.*$`, "m"), `${name}: ${value}`); +} + +function upsertRelation(fm, name, value) { + if (new RegExp(`^\\s+${name}:\\s+\\S`, "m").test(fm)) return fm; + if (/^relations:\s*\{\}\s*$/m.test(fm)) { + return fm.replace(/^relations:\s*\{\}\s*$/m, `relations:\n ${name}: ${value}`); + } + if (/^relations:\s*$/m.test(fm)) { + return fm.replace(/^relations:\s*$/m, `relations:\n ${name}: ${value}`); + } + return fm.replace(/^(relations:\n)/m, `$1 ${name}: ${value}\n`); +} + +const decisionsEpic = path.join(SPECS, "decisions", "_epic.sdp.md"); +fs.writeFileSync( + decisionsEpic, + `--- +id: spec:decisions.process +kind: decision +altitude: epic +readiness: idea +relations: {} +--- +# Process decision registry + +## Intent + +- outcome: Hold the monorepo Process Decision Records as a single refinement parent so each PDR can declare a relation without inventing a second decision. + +## Decision + +- decision: Every PDR under specs/decisions/ refines spec:decisions.process. +`, +); + +const releasesEpic = path.join(SPECS, "releases", "_epic.sdp.md"); +fs.writeFileSync( + releasesEpic, + `--- +id: spec:releases.line +kind: decision +altitude: epic +readiness: idea +relations: {} +--- +# Release boundary registry + +## Intent + +- outcome: Hold numbered and vNEXT release-boundary Specs as a single refinement parent. + +## Decision + +- decision: Every release Spec under specs/releases/ refines spec:releases.line. +`, +); + +let edited = 0; +for (const file of walk(SPECS)) { + const text = fs.readFileSync(file, "utf8"); + const parts = split(text); + if (!parts) continue; + let { fm, body } = parts; + const id = field(fm, "id"); + let changed = false; + + if (EXAMPLE_IDS.has(id) && field(fm, "readiness") === "defined") { + fm = setField(fm, "readiness", "scoped"); + changed = true; + } + + if (id.startsWith("spec:decisions.pdr-")) { + const next = upsertRelation(fm, "refines", "spec:decisions.process"); + if (next !== fm) { + fm = next; + changed = true; + } + } + + if (id.startsWith("spec:releases.v")) { + const next = upsertRelation(fm, "refines", "spec:releases.line"); + if (next !== fm) { + fm = next; + changed = true; + } + } + + if (id === "spec:platform.test-content-blocks" && field(fm, "kind") === "example") { + fm = setField(fm, "kind", "behavior"); + fm = setField(fm, "altitude", "feature"); + changed = true; + } + + if (!changed) continue; + fs.writeFileSync(file, `---\n${fm}\n---\n${body.startsWith("\n") ? body : body}`); + edited += 1; +} + +const decisionsPack = path.join(SPECS, "decisions.pack.sdp.md"); +let pack = fs.readFileSync(decisionsPack, "utf8"); +if (!pack.includes("spec:decisions.process")) { + pack = pack.replace( + "specs:\n - spec:decisions.pdr-001", + "specs:\n - spec:decisions.process\n - spec:decisions.pdr-001", + ); + fs.writeFileSync(decisionsPack, pack); +} + +const releasesPack = path.join(SPECS, "releases.pack.sdp.md"); +let rpack = fs.readFileSync(releasesPack, "utf8"); +if (!rpack.includes("spec:releases.line")) { + rpack = rpack.replace( + "specs:\n - spec:releases.v0.1.0", + "specs:\n - spec:releases.line\n - spec:releases.v0.1.0", + ); + fs.writeFileSync(releasesPack, rpack); +} + +console.log(JSON.stringify({ edited, decisionsEpic: true, releasesEpic: true }, null, 2)); diff --git a/scripts/sdp-protocol-migrate.mjs b/scripts/sdp-protocol-migrate.mjs new file mode 100644 index 00000000..4d72295b --- /dev/null +++ b/scripts/sdp-protocol-migrate.mjs @@ -0,0 +1,289 @@ +#!/usr/bin/env node +/** + * Mechanical Libar SDP protocol upgrade for the already-extracted specs/ corpus. + * + * Safe / idempotent: + * - adds example `verifies` to the refining parent + * - rewrites title-echo Decision stubs from lineage PDR features + * - rewrites "Executable scenario:" / "Unimplemented deliverable:" outcome stubs + * - never invents example-space (Markdown gwt-vocabulary allows exactly one When) + * - never states `ready` + * + * Usage: node scripts/sdp-protocol-migrate.mjs [--dry-run] + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const SPECS = path.join(ROOT, "specs"); +const LINEAGE_DECISIONS = path.join( + ROOT, + "docs", + "lineage", + "architect", + "decisions", +); +const DRY_RUN = process.argv.includes("--dry-run"); +const SKIP = new Set(["node_modules", "dist", "generated", "coverage", ".git"]); + +function walk(dir, pred, out = []) { + if (!fs.existsSync(dir)) return out; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + if (entry.name.startsWith(".")) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + if (SKIP.has(entry.name)) continue; + walk(full, pred, out); + continue; + } + if (entry.isFile() && pred(full, entry.name)) out.push(full); + } + return out; +} + +function splitFrontmatter(text) { + if (!text.startsWith("---\n")) return null; + const end = text.indexOf("\n---\n", 4); + if (end === -1) return null; + return { + fm: text.slice(4, end), + body: text.slice(end + 5), + }; +} + +function field(fm, name) { + const m = fm.match(new RegExp(`^${name}:\\s*(.*)$`, "m")); + return m ? m[1].trim() : ""; +} + +function hasRelation(fm, name) { + return new RegExp(`^\\s+${name}:\\s+\\S`, "m").test(fm); +} + +function relationValue(fm, name) { + const m = fm.match(new RegExp(`^\\s+${name}:\\s+(\\S+)`, "m")); + return m ? m[1].trim() : ""; +} + +function upsertRelation(fm, name, value) { + if (hasRelation(fm, name)) return fm; + if (/^relations:\s*\{\}\s*$/m.test(fm)) { + return fm.replace( + /^relations:\s*\{\}\s*$/m, + `relations:\n ${name}: ${value}`, + ); + } + if (/^relations:\s*$/m.test(fm)) { + return fm.replace(/^relations:\s*$/m, `relations:\n ${name}: ${value}`); + } + return fm.replace(/^(relations:\n)/m, `$1 ${name}: ${value}\n`); +} + +function setField(fm, name, value) { + if (new RegExp(`^${name}:\\s*`, "m").test(fm)) { + return fm.replace(new RegExp(`^${name}:\\s*.*$`, "m"), `${name}: ${value}`); + } + return fm; +} + +function sanitizeLine(text, limit = 500) { + return text.replace(/\s+/g, " ").trim().slice(0, limit); +} + +function extractRule(featureText, headingRe) { + const lines = featureText.split("\n"); + let capturing = false; + const buf = []; + for (const line of lines) { + const trimmed = line.trim(); + if (/^Rule:/.test(trimmed)) { + if (capturing) break; + capturing = headingRe.test(trimmed); + continue; + } + if (capturing) { + if ( + /^(Background:|Scenario:|Scenario Outline:|Example:|@)/.test(trimmed) + ) { + break; + } + if (trimmed) buf.push(trimmed); + } + } + return sanitizeLine(buf.join(" "), 700); +} + +function decisionSource(stem) { + const direct = path.join(LINEAGE_DECISIONS, `${stem}.feature`); + if (fs.existsSync(direct)) return fs.readFileSync(direct, "utf8"); + const matches = walk( + LINEAGE_DECISIONS, + (_full, name) => name.startsWith(stem) && name.endsWith(".feature"), + ); + return matches[0] ? fs.readFileSync(matches[0], "utf8") : ""; +} + +function replaceKeyed(body, heading, key, value) { + const headingRe = new RegExp(`^## ${heading}\\s*$`, "m"); + if (!headingRe.test(body)) { + return `${body.trimEnd()}\n\n## ${heading}\n\n- ${key}: ${value}\n`; + } + const keyRe = new RegExp(`^(- ${key}: ).*$`, "m"); + if (keyRe.test(body)) return body.replace(keyRe, `$1${value}`); + return body.replace(headingRe, `## ${heading}\n\n- ${key}: ${value}`); +} + +function ensureDecisionFields(body, fields) { + let next = body; + for (const [key, value] of Object.entries(fields)) { + if (!value) continue; + next = replaceKeyed(next, "Decision", key, value); + } + return next; +} + +function rewriteOutcome(body, outcome) { + if (!outcome) return body; + if (/^- outcome: /m.test(body)) { + return body.replace(/^- outcome: .*$/m, `- outcome: ${outcome}`); + } + return body.replace( + /^## Intent\s*$/m, + `## Intent\n\n- outcome: ${outcome}`, + ); +} + +const files = walk( + SPECS, + (_full, name) => name.endsWith(".sdp.md") && !name.endsWith(".pack.sdp.md"), +); + +/** @type {Map} */ +const byFile = new Map(); +/** @type {Map} */ +const idToFile = new Map(); + +for (const file of files) { + const text = fs.readFileSync(file, "utf8"); + const parts = splitFrontmatter(text); + if (!parts) continue; + const id = field(parts.fm, "id"); + const rec = { file, ...parts, text }; + byFile.set(file, rec); + if (id) idToFile.set(id, file); +} + +let edited = 0; +const counts = { + verifies: 0, + outcomes: 0, + decisions: 0, +}; + +for (const rec of byFile.values()) { + let { fm, body } = rec; + const kind = field(fm, "kind"); + const id = field(fm, "id"); + const title = (body.match(/^# (.+)$/m) || [, ""])[1].trim(); + let changed = false; + + if (kind === "example") { + const parent = relationValue(fm, "refines"); + if (parent && !hasRelation(fm, "verifies")) { + fm = upsertRelation(fm, "verifies", parent); + counts.verifies += 1; + changed = true; + } + + const outcomeMatch = body.match(/^- outcome:\s*(.*)$/m); + const outcome = outcomeMatch ? outcomeMatch[1].trim() : ""; + if (/^Executable scenario:/i.test(outcome)) { + const rest = outcome.replace(/^Executable scenario:\s*/i, "").trim(); + const next = sanitizeLine( + rest ? `Show that ${rest.replace(/\.$/, "")}.` : `Show that ${title}.`, + ); + body = rewriteOutcome(body, next); + counts.outcomes += 1; + changed = true; + } + } + + if (kind === "decision") { + const outcomeMatch = body.match(/^- outcome:\s*(.*)$/m); + const outcome = outcomeMatch ? outcomeMatch[1].trim() : ""; + const decisionMatch = body.match(/^- decision:\s*(.*)$/m); + const decision = decisionMatch ? decisionMatch[1].trim() : ""; + const stubby = + !decision || + decision === title || + decision === outcome || + decision.length < 40; + + if (stubby) { + const stem = path.basename(rec.file, ".sdp.md"); + const source = decisionSource(stem); + if (source) { + const context = extractRule(source, /Context/i); + const chosen = extractRule(source, /Decision/i); + const consequences = extractRule(source, /Consequence/i); + if (chosen) { + const nextOutcome = sanitizeLine( + `Record the process decision: ${title.replace(/^PDR-\d+\s*-?\s*/i, "")}.`, + ); + body = rewriteOutcome(body, nextOutcome); + body = ensureDecisionFields(body, { + context: context || undefined, + decision: chosen, + consequence: consequences || undefined, + }); + counts.decisions += 1; + changed = true; + } + } + } + } + + if (kind === "behavior") { + const outcomeMatch = body.match(/^- outcome:\s*(.*)$/m); + const outcome = outcomeMatch ? outcomeMatch[1].trim() : ""; + if (/^Unimplemented deliverable:/i.test(outcome)) { + const rest = outcome + .replace(/^Unimplemented deliverable:\s*/i, "") + .replace(/\s+at\s+\S.*$/, "") + .trim(); + const next = sanitizeLine( + `Capture the still-unimplemented deliverable "${rest || title}" until it is authored to a higher readiness rung.`, + ); + body = rewriteOutcome(body, next); + counts.outcomes += 1; + changed = true; + } else if ( + /^Preserve the former architect pattern /i.test(outcome) && + title + ) { + const next = sanitizeLine( + `Preserve the former architect pattern "${title}" as a delivery Spec so implementation can bind to a stable identity.`, + ); + if (next !== outcome) { + body = rewriteOutcome(body, next); + counts.outcomes += 1; + changed = true; + } + } + } + + void id; + if (!changed) continue; + const next = `---\n${fm}\n---\n${body.startsWith("\n") ? body : body}`; + if (next === rec.text) continue; + edited += 1; + if (!DRY_RUN) fs.writeFileSync(rec.file, next); +} + +const summary = { + files: files.length, + edited, + ...counts, + dryRun: DRY_RUN, +}; +console.log(JSON.stringify(summary, null, 2)); diff --git a/scripts/sdp-prune-low-value.mjs b/scripts/sdp-prune-low-value.mjs new file mode 100644 index 00000000..fd6c8350 --- /dev/null +++ b/scripts/sdp-prune-low-value.mjs @@ -0,0 +1,86 @@ +#!/usr/bin/env node +/** + * Remove Specs that add no unique intent after a file-by-file check. + * + * Kept on purpose: + * - unimplemented/deliverables/** except the demo fixture (named remaining work) + * - specs/platform/patterns/** (authored outcomes + codeAnchor surface) + * + * Removed: + * - unimplemented/current and unimplemented/remaining: docs-living status dumps + * whose durable intent already lives on specs/platform/* and deliverable children + * - the test-content-blocks demo fixture and its title-echo parent + */ +import fs from "node:fs"; +import path from "node:path"; + +const ROOT = path.resolve(import.meta.dirname, ".."); +const SPECS = path.join(ROOT, "specs"); + +const DELETE_PATHS = [ + path.join(SPECS, "unimplemented", "current"), + path.join(SPECS, "unimplemented", "remaining"), + path.join( + SPECS, + "unimplemented", + "deliverables", + "test-content-blocks", + ), + path.join(SPECS, "test-content-blocks.sdp.md"), +]; + +const DROP_IDS = new Set([ + "spec:unimplemented.current.phase-100-codec-driven-reference-generation", + "spec:unimplemented.current.phase-100-themed-decision-architecture", + "spec:unimplemented.current.phase-15-projection-categories-executable-tests", + "spec:unimplemented.current.phase-22-agent-as-bounded-context", + "spec:unimplemented.current.phase-22-agent-as-bounded-context-ai-driven-event-reactors", + "spec:unimplemented.current.phase-22-agent-churn-risk-completion", + "spec:unimplemented.current.phase-22-confirmed-order-cancellation", + "spec:unimplemented.remaining.phase-100-themed-decision-architecture", + "spec:unimplemented.remaining.phase-18-production-hardening", + "spec:unimplemented.remaining.phase-18-workpool-partitioning-strategy", + "spec:unimplemented.remaining.phase-20-reservation-pattern", + "spec:unimplemented.remaining.phase-21-integration-patterns-21b", + "spec:unimplemented.remaining.phase-22-agent-as-bounded-context", + "spec:unimplemented.remaining.phase-22-agent-as-bounded-context-ai-driven-event-reactors", + "spec:unimplemented.remaining.phase-22-agent-churn-risk-completion", + "spec:unimplemented.remaining.phase-22-confirmed-order-cancellation", + "spec:unimplemented.test-content-blocks.demo-item-1", + "spec:platform.test-content-blocks", +]); + +function rm(target) { + if (!fs.existsSync(target)) return false; + fs.rmSync(target, { recursive: true, force: true }); + return true; +} + +function rewritePack(file, drop) { + const text = fs.readFileSync(file, "utf8"); + const lines = text.split("\n"); + const next = lines.filter((line) => { + const m = line.match(/^\s+-\s+(spec:\S+)\s*$/); + return !(m && drop.has(m[1])); + }); + let body = next.join("\n"); + if (file.endsWith("unimplemented.pack.sdp.md")) { + body = body.replace( + "Non-implemented architect deliverables, remaining-work items, and in-flight docs-living rows.", + "Named remaining-work items that refine a live platform Spec. Status dumps from docs-living are not carriers.", + ); + } + fs.writeFileSync(file, body); +} + +const removed = DELETE_PATHS.filter(rm); +rewritePack(path.join(SPECS, "unimplemented.pack.sdp.md"), DROP_IDS); +rewritePack(path.join(SPECS, "platform.pack.sdp.md"), DROP_IDS); + +console.log( + JSON.stringify( + { removed, droppedIds: [...DROP_IDS].sort() }, + null, + 2, + ), +); diff --git a/specs/README.md b/specs/README.md new file mode 100644 index 00000000..675c88fa --- /dev/null +++ b/specs/README.md @@ -0,0 +1,41 @@ +# Libar Platform — SDP corpus + +Designated **corpus root** for Libar Software Delivery Protocol (SDP) Specs and Packs: + +`specs/` (run from the libar-platform repo root via `pnpm sdp:*`) + +Carriers are Markdown: Specs as `*.sdp.md`, Packs as `*.pack.sdp.md`. Identity bindings live in +`platform/sdp-bindings.ts`. This tree replaces the former `architect/` Gherkin intent surface for +SDP extraction and validation. + +- Feature files under `packages/`, `examples/`, and `apps/` remain Cucumber test carriers; each + Feature has a behavior Spec, and Scenarios with authored intent have example Specs under + `specs/behavior/**/**.examples/`. Pure title-echo scenario mirrors were pruned; the `.feature` + files are the source of truth for those scenarios. +- Named remaining-work items live under `specs/unimplemented/deliverables/` and refine a live + platform Spec. Retired docs-living status dumps are not carriers. +- The `architect/` tree may still exist as lineage; bare `.feature` files are not SDP carriers. + +## Packs + +| Pack ID | Path | Contents | +|---|---|---| +| `pack:platform` | `platform.pack.sdp.md` | Platform Specs including code-originated patterns | +| `pack:platform-patterns` | `platform-patterns.pack.sdp.md` | Pattern Specs from former architect bindings | +| `pack:decisions` | `decisions.pack.sdp.md` | Migrated PDRs | +| `pack:releases` | `releases.pack.sdp.md` | Release-boundary Specs | +| `pack:behavior` | `behavior.pack.sdp.md` | Umbrella pack for all migrated executable Gherkin Specs | +| `pack:behavior-*` | `behavior-.pack.sdp.md` | Per-package/example/app behavior families | +| `pack:unimplemented` | `unimplemented.pack.sdp.md` | Pending deliverables and remaining-work items | + +## Commands + +```bash +pnpm sdp:build +pnpm sdp:validate +pnpm sdp:view +pnpm sdp:q 'return g.specs().map((s) => s.id)' +``` + +`sdp build` must exit 0 with a non-empty Specs/Packs/anchors summary. Re-measure findings with +`sdp validate`; do not quote stale counts from this README. diff --git a/specs/behavior-frontend.pack.sdp.md b/specs/behavior-frontend.pack.sdp.md new file mode 100644 index 00000000..76ba958f --- /dev/null +++ b/specs/behavior-frontend.pack.sdp.md @@ -0,0 +1,17 @@ +--- +id: pack:behavior-frontend +specs: + - spec:behavior.frontend + - spec:behavior.frontend.admin.add-stock + - spec:behavior.frontend.admin.agent-approvals + - spec:behavior.frontend.admin.create-product + - spec:behavior.frontend.dashboard.dashboard + - spec:behavior.frontend.e2e-journeys.full-order-journey + - spec:behavior.frontend.orders.create-order + - spec:behavior.frontend.orders.order-detail + - spec:behavior.frontend.orders.view-orders + - spec:behavior.frontend.products.browse-products +--- +# frontend behavior + +Executable Gherkin behavior Specs migrated from the frontend test corpus. diff --git a/specs/behavior-order-management.pack.sdp.md b/specs/behavior-order-management.pack.sdp.md new file mode 100644 index 00000000..80fe717d --- /dev/null +++ b/specs/behavior-order-management.pack.sdp.md @@ -0,0 +1,105 @@ +--- +id: pack:behavior-order-management +specs: + - spec:behavior.order-management + - spec:behavior.order-management.agent.on-complete + - spec:behavior.order-management.deciders.add-order-item-decider + - spec:behavior.order-management.deciders.add-stock-decider + - spec:behavior.order-management.deciders.cancel-order-decider + - spec:behavior.order-management.deciders.confirm-order-decider + - spec:behavior.order-management.deciders.confirm-reservation-decider + - spec:behavior.order-management.deciders.create-order-decider + - spec:behavior.order-management.deciders.create-product-decider + - spec:behavior.order-management.deciders.expire-reservation-decider + - spec:behavior.order-management.deciders.inventory-evolve + - spec:behavior.order-management.deciders.order-evolve + - spec:behavior.order-management.deciders.release-reservation-decider + - spec:behavior.order-management.deciders.remove-order-item-decider + - spec:behavior.order-management.deciders.reservation-evolve + - spec:behavior.order-management.deciders.reserve-stock-decider + - spec:behavior.order-management.deciders.submit-order-decider + - spec:behavior.order-management.inventory.add-stock + - spec:behavior.order-management.inventory.confirm-reservation + - spec:behavior.order-management.inventory.create-product + - spec:behavior.order-management.inventory.inventory-domain + - spec:behavior.order-management.inventory.product-invariants + - spec:behavior.order-management.inventory.release-reservation + - spec:behavior.order-management.inventory.reservation-domain + - spec:behavior.order-management.inventory.reservation-invariants + - spec:behavior.order-management.inventory.reserve-stock + - spec:behavior.order-management.inventory.stock-invariants + - spec:behavior.order-management.modernization.dcb-multi-product-reservation + - spec:behavior.order-management.modernization.fat-events-order-submitted + - spec:behavior.order-management.modernization.reactive-order-detail + - spec:behavior.order-management.modernization.reference-documentation + - spec:behavior.order-management.orders.add-items + - spec:behavior.order-management.orders.cancel-order + - spec:behavior.order-management.orders.confirm-order + - spec:behavior.order-management.orders.create-order + - spec:behavior.order-management.orders.order-domain + - spec:behavior.order-management.orders.order-invariant-sets + - spec:behavior.order-management.orders.order-invariants + - spec:behavior.order-management.orders.remove-order-item + - spec:behavior.order-management.orders.submit-order + - spec:behavior.order-management.roadmap.projection-categories + - spec:behavior.order-management.sagas.admin + - spec:behavior.order-management.testing-infrastructure.data-table-parsing + - spec:behavior.order-management.testing-infrastructure.decider-assertions + - spec:behavior.order-management.testing-infrastructure.fsm-assertions + - spec:behavior.order-management.testing-infrastructure.test-isolation + - spec:behavior.order-management.tests.integration-features.durability.durable-commands + - spec:behavior.order-management.tests.integration-features.durability.durable-publication + - spec:behavior.order-management.tests.integration-features.durability.event-replay + - spec:behavior.order-management.tests.integration-features.durability.idempotent-append + - spec:behavior.order-management.tests.integration-features.durability.orphan-detection + - spec:behavior.order-management.tests.integration-features.durability.poison-event + - spec:behavior.order-management.tests.integration-features.durable-adapters.dcb-retry + - spec:behavior.order-management.tests.integration-features.durable-adapters.rate-limiting + - spec:behavior.order-management.tests.integration-features.inventory.add-stock + - spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation + - spec:behavior.order-management.tests.integration-features.inventory.create-product + - spec:behavior.order-management.tests.integration-features.inventory.query-inventory + - spec:behavior.order-management.tests.integration-features.inventory.release-reservation + - spec:behavior.order-management.tests.integration-features.inventory.reservation-expiration + - spec:behavior.order-management.tests.integration-features.inventory.reserve-stock + - spec:behavior.order-management.tests.integration-features.orders.add-order-item + - spec:behavior.order-management.tests.integration-features.orders.batch-operations + - spec:behavior.order-management.tests.integration-features.orders.cancel-order + - spec:behavior.order-management.tests.integration-features.orders.create-order + - spec:behavior.order-management.tests.integration-features.orders.query-orders + - spec:behavior.order-management.tests.integration-features.orders.submit-order + - spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + - spec:behavior.order-management.tests.integration-features.sagas.saga-admin + - spec:behavior.order-management.timeline.phase-00-initialization + - spec:behavior.order-management.timeline.phase-01-core-infrastructure + - spec:behavior.order-management.timeline.phase-02-event-store-orchestration + - spec:behavior.order-management.timeline.phase-03-command-bus + - spec:behavior.order-management.timeline.phase-04-orders-bc + - spec:behavior.order-management.timeline.phase-05-inventory-bc + - spec:behavior.order-management.timeline.phase-06-cross-context-integration + - spec:behavior.order-management.timeline.phase-07-projection-engine + - spec:behavior.order-management.timeline.phase-08-documentation-polish + - spec:behavior.order-management.timeline.phase-09-event-system + - spec:behavior.order-management.timeline.phase-10-command-system + - spec:behavior.order-management.timeline.phase-11-bc-formalization + - spec:behavior.order-management.timeline.phase-12-repository-read-model + - spec:behavior.order-management.timeline.phase-13-process-manager + - spec:behavior.order-management.timeline.phase-14-decider-formalization + - spec:behavior.order-management.timeline.phase-15-projection-categories + - spec:behavior.order-management.timeline.phase-16-dcb + - spec:behavior.order-management.timeline.phase-17-reactive-projections + - spec:behavior.order-management.timeline.phase-18-production-hardening + - spec:behavior.order-management.timeline.phase-19-testing-infrastructure + - spec:behavior.order-management.timeline.phase-20-service-independence + - spec:behavior.order-management.timeline.phase-21-integration-patterns + - spec:behavior.order-management.timeline.phase-22-agent-as-bc + - spec:behavior.order-management.timeline.phase-23-process-setup + - spec:behavior.order-management.timeline.phase-24-old-roadmap-porting + - spec:behavior.order-management.timeline.phase-25-adr-porting + - spec:behavior.order-management.timeline.phase-26-workflow-configuration + - spec:behavior.order-management.timeline.phase-27-pattern-annotation-priorities + - spec:behavior.order-management.timeline.phase-28-modular-claude-md +--- +# order-management behavior + +Executable Gherkin behavior Specs migrated from the order-management test corpus. diff --git a/specs/behavior-platform-bc.pack.sdp.md b/specs/behavior-platform-bc.pack.sdp.md new file mode 100644 index 00000000..b3bc1cf1 --- /dev/null +++ b/specs/behavior-platform-bc.pack.sdp.md @@ -0,0 +1,10 @@ +--- +id: pack:behavior-platform-bc +specs: + - spec:behavior.platform-bc + - spec:behavior.platform-bc.bc-contracts + - spec:behavior.platform-bc.bounded-context-foundation-executable-tests +--- +# platform-bc behavior + +Executable Gherkin behavior Specs migrated from the platform-bc test corpus. diff --git a/specs/behavior-platform-bus.pack.sdp.md b/specs/behavior-platform-bus.pack.sdp.md new file mode 100644 index 00000000..d7949e3c --- /dev/null +++ b/specs/behavior-platform-bus.pack.sdp.md @@ -0,0 +1,10 @@ +--- +id: pack:behavior-platform-bus +specs: + - spec:behavior.platform-bus + - spec:behavior.platform-bus.command-bus-foundation-executable-tests + - spec:behavior.platform-bus.idempotency +--- +# platform-bus behavior + +Executable Gherkin behavior Specs migrated from the platform-bus test corpus. diff --git a/specs/behavior-platform-core.pack.sdp.md b/specs/behavior-platform-core.pack.sdp.md new file mode 100644 index 00000000..ce66547f --- /dev/null +++ b/specs/behavior-platform-core.pack.sdp.md @@ -0,0 +1,132 @@ +--- +id: pack:behavior-platform-core +specs: + - spec:behavior.platform-core + - spec:behavior.platform-core.agent.action-handler + - spec:behavior.platform-core.agent.agent-rate-limiter + - spec:behavior.platform-core.agent.agent-subscription + - spec:behavior.platform-core.agent.agent-subscription-action + - spec:behavior.platform-core.agent.approval + - spec:behavior.platform-core.agent.audit + - spec:behavior.platform-core.agent.audit-trail + - spec:behavior.platform-core.agent.checkpoint + - spec:behavior.platform-core.agent.checkpoint-extension + - spec:behavior.platform-core.agent.command-bridge + - spec:behavior.platform-core.agent.command-emission + - spec:behavior.platform-core.agent.command-router + - spec:behavior.platform-core.agent.commands + - spec:behavior.platform-core.agent.cost-budget + - spec:behavior.platform-core.agent.dead-letter + - spec:behavior.platform-core.agent.event-subscription + - spec:behavior.platform-core.agent.human-in-loop + - spec:behavior.platform-core.agent.init + - spec:behavior.platform-core.agent.lifecycle-commands + - spec:behavior.platform-core.agent.lifecycle-fsm + - spec:behavior.platform-core.agent.lifecycle-handlers + - spec:behavior.platform-core.agent.oncomplete-handler + - spec:behavior.platform-core.agent.pattern-detection + - spec:behavior.platform-core.agent.pattern-executor + - spec:behavior.platform-core.agent.pattern-registry + - spec:behavior.platform-core.agent.patterns + - spec:behavior.platform-core.agent.rate-limit + - spec:behavior.platform-core.agent.thread-adapter + - spec:behavior.platform-core.batch.batch-executor + - spec:behavior.platform-core.batch.validation + - spec:behavior.platform-core.cms.upcaster + - spec:behavior.platform-core.commands.categories + - spec:behavior.platform-core.commands.errors + - spec:behavior.platform-core.commands.factories + - spec:behavior.platform-core.commands.naming + - spec:behavior.platform-core.correlation.chain + - spec:behavior.platform-core.correlation.correlation-service + - spec:behavior.platform-core.dcb.execute + - spec:behavior.platform-core.dcb.scope-key + - spec:behavior.platform-core.decider.factory + - spec:behavior.platform-core.durable-function-adapters.dcb-conflict-retry + - spec:behavior.platform-core.durable-function-adapters.integration-patterns + - spec:behavior.platform-core.durable-function-adapters.rate-limit-adapter + - spec:behavior.platform-core.ecst.fat-event-builder + - spec:behavior.platform-core.ecst.fat-vs-thin-selection + - spec:behavior.platform-core.ecst.privacy-markers + - spec:behavior.platform-core.ecst.schema-versioning + - spec:behavior.platform-core.event-replay.replay-progress + - spec:behavior.platform-core.event-store-durability.durable-append + - spec:behavior.platform-core.event-store-durability.durable-publication + - spec:behavior.platform-core.event-store-durability.idempotent-append + - spec:behavior.platform-core.event-store-durability.intent-completion + - spec:behavior.platform-core.event-store-durability.outbox-handler + - spec:behavior.platform-core.event-store-durability.poison-event + - spec:behavior.platform-core.eventbus.convex-event-bus + - spec:behavior.platform-core.eventbus.registry + - spec:behavior.platform-core.events.builder + - spec:behavior.platform-core.events.category + - spec:behavior.platform-core.events.schemas + - spec:behavior.platform-core.events.upcaster + - spec:behavior.platform-core.fsm.fsm + - spec:behavior.platform-core.handlers.result + - spec:behavior.platform-core.ids.branded + - spec:behavior.platform-core.ids.generator + - spec:behavior.platform-core.integration.anti-corruption-layer + - spec:behavior.platform-core.integration.context-map + - spec:behavior.platform-core.integration.contract-testing + - spec:behavior.platform-core.integration.event-versioning + - spec:behavior.platform-core.integration.integration-event-publisher + - spec:behavior.platform-core.integration.published-language + - spec:behavior.platform-core.invariants.create-invariant + - spec:behavior.platform-core.invariants.create-invariant-set + - spec:behavior.platform-core.invariants.invariant-error + - spec:behavior.platform-core.logging.commands + - spec:behavior.platform-core.logging.scoped + - spec:behavior.platform-core.logging.testing + - spec:behavior.platform-core.logging.types + - spec:behavior.platform-core.middleware.middleware-pipeline + - spec:behavior.platform-core.middleware.middlewares + - spec:behavior.platform-core.monitoring.circuit-breaker + - spec:behavior.platform-core.orchestration.command-orchestrator + - spec:behavior.platform-core.orchestration.saga-orchestration-executable-tests + - spec:behavior.platform-core.process-manager.executor + - spec:behavior.platform-core.process-manager.lifecycle + - spec:behavior.platform-core.process-manager.registry + - spec:behavior.platform-core.process-manager.subscription + - spec:behavior.platform-core.process-manager.types + - spec:behavior.platform-core.process-manager.with-pm-checkpoint + - spec:behavior.platform-core.production-hardening.admin-tooling + - spec:behavior.platform-core.production-hardening.circuit-breakers + - spec:behavior.platform-core.production-hardening.distributed-tracing + - spec:behavior.platform-core.production-hardening.durable-function-integration + - spec:behavior.platform-core.production-hardening.health-endpoints + - spec:behavior.platform-core.production-hardening.metrics-collection + - spec:behavior.platform-core.production-hardening.rate-limiting + - spec:behavior.platform-core.projection-categories.category-definitions + - spec:behavior.platform-core.projection-categories.explicit-declaration + - spec:behavior.platform-core.projection-categories.registry-lookup + - spec:behavior.platform-core.projections.categories + - spec:behavior.platform-core.projections.lifecycle + - spec:behavior.platform-core.projections.registry + - spec:behavior.platform-core.projections.with-checkpoint + - spec:behavior.platform-core.queries.factory + - spec:behavior.platform-core.queries.pagination + - spec:behavior.platform-core.reactive-projections.conflict-detection + - spec:behavior.platform-core.reactive-projections.hybrid-model + - spec:behavior.platform-core.reactive-projections.reactive-eligibility + - spec:behavior.platform-core.reactive-projections.shared-evolve + - spec:behavior.platform-core.registry.command-registry + - spec:behavior.platform-core.registry.define-command + - spec:behavior.platform-core.repository.cms-repository + - spec:behavior.platform-core.reservation.confirm-operation + - spec:behavior.platform-core.reservation.release-operation + - spec:behavior.platform-core.reservation.reservation-key + - spec:behavior.platform-core.reservation.reserve-operation + - spec:behavior.platform-core.schemas.command-schemas + - spec:behavior.platform-core.testing.guards + - spec:behavior.platform-core.testing.integration-isolation + - spec:behavior.platform-core.testing.platform-coverage + - spec:behavior.platform-core.testing.polling + - spec:behavior.platform-core.testing.world + - spec:behavior.platform-core.workpool-partitioning.complexity-classifier + - spec:behavior.platform-core.workpool-partitioning.partition-key-helpers + - spec:behavior.platform-core.workpool-partitioning.partition-validation +--- +# platform-core behavior + +Executable Gherkin behavior Specs migrated from the platform-core test corpus. diff --git a/specs/behavior-platform-decider.pack.sdp.md b/specs/behavior-platform-decider.pack.sdp.md new file mode 100644 index 00000000..dfcad932 --- /dev/null +++ b/specs/behavior-platform-decider.pack.sdp.md @@ -0,0 +1,9 @@ +--- +id: pack:behavior-platform-decider +specs: + - spec:behavior.platform-decider + - spec:behavior.platform-decider.decider-outputs +--- +# platform-decider behavior + +Executable Gherkin behavior Specs migrated from the platform-decider test corpus. diff --git a/specs/behavior-platform-fsm.pack.sdp.md b/specs/behavior-platform-fsm.pack.sdp.md new file mode 100644 index 00000000..9fc55cf1 --- /dev/null +++ b/specs/behavior-platform-fsm.pack.sdp.md @@ -0,0 +1,9 @@ +--- +id: pack:behavior-platform-fsm +specs: + - spec:behavior.platform-fsm + - spec:behavior.platform-fsm.fsm-transitions +--- +# platform-fsm behavior + +Executable Gherkin behavior Specs migrated from the platform-fsm test corpus. diff --git a/specs/behavior-platform-store.pack.sdp.md b/specs/behavior-platform-store.pack.sdp.md new file mode 100644 index 00000000..2e1683c3 --- /dev/null +++ b/specs/behavior-platform-store.pack.sdp.md @@ -0,0 +1,10 @@ +--- +id: pack:behavior-platform-store +specs: + - spec:behavior.platform-store + - spec:behavior.platform-store.event-store-foundation-executable-tests + - spec:behavior.platform-store.event-store-types +--- +# platform-store behavior + +Executable Gherkin behavior Specs migrated from the platform-store test corpus. diff --git a/specs/behavior.pack.sdp.md b/specs/behavior.pack.sdp.md new file mode 100644 index 00000000..efe0b731 --- /dev/null +++ b/specs/behavior.pack.sdp.md @@ -0,0 +1,253 @@ +--- +id: pack:behavior +specs: + - spec:behavior.frontend + - spec:behavior.frontend.admin.add-stock + - spec:behavior.frontend.admin.agent-approvals + - spec:behavior.frontend.admin.create-product + - spec:behavior.frontend.dashboard.dashboard + - spec:behavior.frontend.e2e-journeys.full-order-journey + - spec:behavior.frontend.orders.create-order + - spec:behavior.frontend.orders.order-detail + - spec:behavior.frontend.orders.view-orders + - spec:behavior.frontend.products.browse-products + - spec:behavior.order-management + - spec:behavior.order-management.agent.on-complete + - spec:behavior.order-management.deciders.add-order-item-decider + - spec:behavior.order-management.deciders.add-stock-decider + - spec:behavior.order-management.deciders.cancel-order-decider + - spec:behavior.order-management.deciders.confirm-order-decider + - spec:behavior.order-management.deciders.confirm-reservation-decider + - spec:behavior.order-management.deciders.create-order-decider + - spec:behavior.order-management.deciders.create-product-decider + - spec:behavior.order-management.deciders.expire-reservation-decider + - spec:behavior.order-management.deciders.inventory-evolve + - spec:behavior.order-management.deciders.order-evolve + - spec:behavior.order-management.deciders.release-reservation-decider + - spec:behavior.order-management.deciders.remove-order-item-decider + - spec:behavior.order-management.deciders.reservation-evolve + - spec:behavior.order-management.deciders.reserve-stock-decider + - spec:behavior.order-management.deciders.submit-order-decider + - spec:behavior.order-management.inventory.add-stock + - spec:behavior.order-management.inventory.confirm-reservation + - spec:behavior.order-management.inventory.create-product + - spec:behavior.order-management.inventory.inventory-domain + - spec:behavior.order-management.inventory.product-invariants + - spec:behavior.order-management.inventory.release-reservation + - spec:behavior.order-management.inventory.reservation-domain + - spec:behavior.order-management.inventory.reservation-invariants + - spec:behavior.order-management.inventory.reserve-stock + - spec:behavior.order-management.inventory.stock-invariants + - spec:behavior.order-management.modernization.dcb-multi-product-reservation + - spec:behavior.order-management.modernization.fat-events-order-submitted + - spec:behavior.order-management.modernization.reactive-order-detail + - spec:behavior.order-management.modernization.reference-documentation + - spec:behavior.order-management.orders.add-items + - spec:behavior.order-management.orders.cancel-order + - spec:behavior.order-management.orders.confirm-order + - spec:behavior.order-management.orders.create-order + - spec:behavior.order-management.orders.order-domain + - spec:behavior.order-management.orders.order-invariant-sets + - spec:behavior.order-management.orders.order-invariants + - spec:behavior.order-management.orders.remove-order-item + - spec:behavior.order-management.orders.submit-order + - spec:behavior.order-management.roadmap.projection-categories + - spec:behavior.order-management.sagas.admin + - spec:behavior.order-management.testing-infrastructure.data-table-parsing + - spec:behavior.order-management.testing-infrastructure.decider-assertions + - spec:behavior.order-management.testing-infrastructure.fsm-assertions + - spec:behavior.order-management.testing-infrastructure.test-isolation + - spec:behavior.order-management.tests.integration-features.durability.durable-commands + - spec:behavior.order-management.tests.integration-features.durability.durable-publication + - spec:behavior.order-management.tests.integration-features.durability.event-replay + - spec:behavior.order-management.tests.integration-features.durability.idempotent-append + - spec:behavior.order-management.tests.integration-features.durability.orphan-detection + - spec:behavior.order-management.tests.integration-features.durability.poison-event + - spec:behavior.order-management.tests.integration-features.durable-adapters.dcb-retry + - spec:behavior.order-management.tests.integration-features.durable-adapters.rate-limiting + - spec:behavior.order-management.tests.integration-features.inventory.add-stock + - spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation + - spec:behavior.order-management.tests.integration-features.inventory.create-product + - spec:behavior.order-management.tests.integration-features.inventory.query-inventory + - spec:behavior.order-management.tests.integration-features.inventory.release-reservation + - spec:behavior.order-management.tests.integration-features.inventory.reservation-expiration + - spec:behavior.order-management.tests.integration-features.inventory.reserve-stock + - spec:behavior.order-management.tests.integration-features.orders.add-order-item + - spec:behavior.order-management.tests.integration-features.orders.batch-operations + - spec:behavior.order-management.tests.integration-features.orders.cancel-order + - spec:behavior.order-management.tests.integration-features.orders.create-order + - spec:behavior.order-management.tests.integration-features.orders.query-orders + - spec:behavior.order-management.tests.integration-features.orders.submit-order + - spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + - spec:behavior.order-management.tests.integration-features.sagas.saga-admin + - spec:behavior.order-management.timeline.phase-00-initialization + - spec:behavior.order-management.timeline.phase-01-core-infrastructure + - spec:behavior.order-management.timeline.phase-02-event-store-orchestration + - spec:behavior.order-management.timeline.phase-03-command-bus + - spec:behavior.order-management.timeline.phase-04-orders-bc + - spec:behavior.order-management.timeline.phase-05-inventory-bc + - spec:behavior.order-management.timeline.phase-06-cross-context-integration + - spec:behavior.order-management.timeline.phase-07-projection-engine + - spec:behavior.order-management.timeline.phase-08-documentation-polish + - spec:behavior.order-management.timeline.phase-09-event-system + - spec:behavior.order-management.timeline.phase-10-command-system + - spec:behavior.order-management.timeline.phase-11-bc-formalization + - spec:behavior.order-management.timeline.phase-12-repository-read-model + - spec:behavior.order-management.timeline.phase-13-process-manager + - spec:behavior.order-management.timeline.phase-14-decider-formalization + - spec:behavior.order-management.timeline.phase-15-projection-categories + - spec:behavior.order-management.timeline.phase-16-dcb + - spec:behavior.order-management.timeline.phase-17-reactive-projections + - spec:behavior.order-management.timeline.phase-18-production-hardening + - spec:behavior.order-management.timeline.phase-19-testing-infrastructure + - spec:behavior.order-management.timeline.phase-20-service-independence + - spec:behavior.order-management.timeline.phase-21-integration-patterns + - spec:behavior.order-management.timeline.phase-22-agent-as-bc + - spec:behavior.order-management.timeline.phase-23-process-setup + - spec:behavior.order-management.timeline.phase-24-old-roadmap-porting + - spec:behavior.order-management.timeline.phase-25-adr-porting + - spec:behavior.order-management.timeline.phase-26-workflow-configuration + - spec:behavior.order-management.timeline.phase-27-pattern-annotation-priorities + - spec:behavior.order-management.timeline.phase-28-modular-claude-md + - spec:behavior.platform-bc + - spec:behavior.platform-bc.bc-contracts + - spec:behavior.platform-bc.bounded-context-foundation-executable-tests + - spec:behavior.platform-bus + - spec:behavior.platform-bus.command-bus-foundation-executable-tests + - spec:behavior.platform-bus.idempotency + - spec:behavior.platform-core + - spec:behavior.platform-core.agent.action-handler + - spec:behavior.platform-core.agent.agent-rate-limiter + - spec:behavior.platform-core.agent.agent-subscription + - spec:behavior.platform-core.agent.agent-subscription-action + - spec:behavior.platform-core.agent.approval + - spec:behavior.platform-core.agent.audit + - spec:behavior.platform-core.agent.audit-trail + - spec:behavior.platform-core.agent.checkpoint + - spec:behavior.platform-core.agent.checkpoint-extension + - spec:behavior.platform-core.agent.command-bridge + - spec:behavior.platform-core.agent.command-emission + - spec:behavior.platform-core.agent.command-router + - spec:behavior.platform-core.agent.commands + - spec:behavior.platform-core.agent.cost-budget + - spec:behavior.platform-core.agent.dead-letter + - spec:behavior.platform-core.agent.event-subscription + - spec:behavior.platform-core.agent.human-in-loop + - spec:behavior.platform-core.agent.init + - spec:behavior.platform-core.agent.lifecycle-commands + - spec:behavior.platform-core.agent.lifecycle-fsm + - spec:behavior.platform-core.agent.lifecycle-handlers + - spec:behavior.platform-core.agent.oncomplete-handler + - spec:behavior.platform-core.agent.pattern-detection + - spec:behavior.platform-core.agent.pattern-executor + - spec:behavior.platform-core.agent.pattern-registry + - spec:behavior.platform-core.agent.patterns + - spec:behavior.platform-core.agent.rate-limit + - spec:behavior.platform-core.agent.thread-adapter + - spec:behavior.platform-core.batch.batch-executor + - spec:behavior.platform-core.batch.validation + - spec:behavior.platform-core.cms.upcaster + - spec:behavior.platform-core.commands.categories + - spec:behavior.platform-core.commands.errors + - spec:behavior.platform-core.commands.factories + - spec:behavior.platform-core.commands.naming + - spec:behavior.platform-core.correlation.chain + - spec:behavior.platform-core.correlation.correlation-service + - spec:behavior.platform-core.dcb.execute + - spec:behavior.platform-core.dcb.scope-key + - spec:behavior.platform-core.decider.factory + - spec:behavior.platform-core.durable-function-adapters.dcb-conflict-retry + - spec:behavior.platform-core.durable-function-adapters.integration-patterns + - spec:behavior.platform-core.durable-function-adapters.rate-limit-adapter + - spec:behavior.platform-core.ecst.fat-event-builder + - spec:behavior.platform-core.ecst.fat-vs-thin-selection + - spec:behavior.platform-core.ecst.privacy-markers + - spec:behavior.platform-core.ecst.schema-versioning + - spec:behavior.platform-core.event-replay.replay-progress + - spec:behavior.platform-core.event-store-durability.durable-append + - spec:behavior.platform-core.event-store-durability.durable-publication + - spec:behavior.platform-core.event-store-durability.idempotent-append + - spec:behavior.platform-core.event-store-durability.intent-completion + - spec:behavior.platform-core.event-store-durability.outbox-handler + - spec:behavior.platform-core.event-store-durability.poison-event + - spec:behavior.platform-core.eventbus.convex-event-bus + - spec:behavior.platform-core.eventbus.registry + - spec:behavior.platform-core.events.builder + - spec:behavior.platform-core.events.category + - spec:behavior.platform-core.events.schemas + - spec:behavior.platform-core.events.upcaster + - spec:behavior.platform-core.fsm.fsm + - spec:behavior.platform-core.handlers.result + - spec:behavior.platform-core.ids.branded + - spec:behavior.platform-core.ids.generator + - spec:behavior.platform-core.integration.anti-corruption-layer + - spec:behavior.platform-core.integration.context-map + - spec:behavior.platform-core.integration.contract-testing + - spec:behavior.platform-core.integration.event-versioning + - spec:behavior.platform-core.integration.integration-event-publisher + - spec:behavior.platform-core.integration.published-language + - spec:behavior.platform-core.invariants.create-invariant + - spec:behavior.platform-core.invariants.create-invariant-set + - spec:behavior.platform-core.invariants.invariant-error + - spec:behavior.platform-core.logging.commands + - spec:behavior.platform-core.logging.scoped + - spec:behavior.platform-core.logging.testing + - spec:behavior.platform-core.logging.types + - spec:behavior.platform-core.middleware.middleware-pipeline + - spec:behavior.platform-core.middleware.middlewares + - spec:behavior.platform-core.monitoring.circuit-breaker + - spec:behavior.platform-core.orchestration.command-orchestrator + - spec:behavior.platform-core.orchestration.saga-orchestration-executable-tests + - spec:behavior.platform-core.process-manager.executor + - spec:behavior.platform-core.process-manager.lifecycle + - spec:behavior.platform-core.process-manager.registry + - spec:behavior.platform-core.process-manager.subscription + - spec:behavior.platform-core.process-manager.types + - spec:behavior.platform-core.process-manager.with-pm-checkpoint + - spec:behavior.platform-core.production-hardening.admin-tooling + - spec:behavior.platform-core.production-hardening.circuit-breakers + - spec:behavior.platform-core.production-hardening.distributed-tracing + - spec:behavior.platform-core.production-hardening.durable-function-integration + - spec:behavior.platform-core.production-hardening.health-endpoints + - spec:behavior.platform-core.production-hardening.metrics-collection + - spec:behavior.platform-core.production-hardening.rate-limiting + - spec:behavior.platform-core.projection-categories.category-definitions + - spec:behavior.platform-core.projection-categories.explicit-declaration + - spec:behavior.platform-core.projection-categories.registry-lookup + - spec:behavior.platform-core.projections.categories + - spec:behavior.platform-core.projections.lifecycle + - spec:behavior.platform-core.projections.registry + - spec:behavior.platform-core.projections.with-checkpoint + - spec:behavior.platform-core.queries.factory + - spec:behavior.platform-core.queries.pagination + - spec:behavior.platform-core.reactive-projections.conflict-detection + - spec:behavior.platform-core.reactive-projections.hybrid-model + - spec:behavior.platform-core.reactive-projections.reactive-eligibility + - spec:behavior.platform-core.reactive-projections.shared-evolve + - spec:behavior.platform-core.registry.command-registry + - spec:behavior.platform-core.registry.define-command + - spec:behavior.platform-core.repository.cms-repository + - spec:behavior.platform-core.reservation.confirm-operation + - spec:behavior.platform-core.reservation.release-operation + - spec:behavior.platform-core.reservation.reservation-key + - spec:behavior.platform-core.reservation.reserve-operation + - spec:behavior.platform-core.schemas.command-schemas + - spec:behavior.platform-core.testing.guards + - spec:behavior.platform-core.testing.integration-isolation + - spec:behavior.platform-core.testing.platform-coverage + - spec:behavior.platform-core.testing.polling + - spec:behavior.platform-core.testing.world + - spec:behavior.platform-core.workpool-partitioning.complexity-classifier + - spec:behavior.platform-core.workpool-partitioning.partition-key-helpers + - spec:behavior.platform-core.workpool-partitioning.partition-validation + - spec:behavior.platform-decider + - spec:behavior.platform-decider.decider-outputs + - spec:behavior.platform-fsm + - spec:behavior.platform-fsm.fsm-transitions + - spec:behavior.platform-store + - spec:behavior.platform-store.event-store-foundation-executable-tests + - spec:behavior.platform-store.event-store-types +--- +# Executable behavior + +All executable Gherkin behavior Specs migrated from packages, examples, and apps. diff --git a/specs/behavior/frontend/_epic.sdp.md b/specs/behavior/frontend/_epic.sdp.md new file mode 100644 index 00000000..fa6dd319 --- /dev/null +++ b/specs/behavior/frontend/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:behavior.frontend +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# frontend executable behavior + +## Intent + +- outcome: Hold the executable Gherkin behavior Specs migrated from the frontend test corpus. diff --git a/specs/behavior/frontend/admin/add-stock.examples/s-001-add-stock-successfully.sdp.md b/specs/behavior/frontend/admin/add-stock.examples/s-001-add-stock-successfully.sdp.md new file mode 100644 index 00000000..3f108dc7 --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.examples/s-001-add-stock-successfully.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.frontend.admin.add-stock.add-stock-successfully +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.add-stock + verifies: spec:behavior.frontend.admin.add-stock +--- +# Add stock successfully + +## Intent + +- outcome: Show that adding stock to a selected product increases available units after the command succeeds. + +```gwt +Given a product "Stock Test Widget" with SKU "STW-001" exists +And I am on the admin products page +When I switch to the "Add Stock" tab and I select the product "Stock Test Widget" and I enter quantity 50 and I click "Add Stock" +Then I should see a success message containing "Stock added successfully" +And eventually the product "Stock Test Widget" should show 50 units in stock +``` diff --git a/specs/behavior/frontend/admin/add-stock.examples/s-002-add-stock-with-reason.sdp.md b/specs/behavior/frontend/admin/add-stock.examples/s-002-add-stock-with-reason.sdp.md new file mode 100644 index 00000000..e3065fd1 --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.examples/s-002-add-stock-with-reason.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.admin.add-stock.add-stock-with-reason +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.add-stock + verifies: spec:behavior.frontend.admin.add-stock +--- +# Add stock with reason + +## Intent + +- outcome: Show that adding stock can include a restock reason on the same submit. + +```gwt +Given a product "Stock Test Widget" with SKU "STW-001" exists +And I am on the admin products page +When I switch to the "Add Stock" tab and I select the product "Stock Test Widget" and I enter quantity 25 and I enter reason "Restocking from supplier shipment" and I click "Add Stock" +Then I should see a success message containing "Stock added successfully" +``` diff --git a/specs/behavior/frontend/admin/add-stock.examples/s-003-cannot-add-stock-without-selecting-product.sdp.md b/specs/behavior/frontend/admin/add-stock.examples/s-003-cannot-add-stock-without-selecting-product.sdp.md new file mode 100644 index 00000000..48280040 --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.examples/s-003-cannot-add-stock-without-selecting-product.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.admin.add-stock.cannot-add-stock-without-selecting-product +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.add-stock + verifies: spec:behavior.frontend.admin.add-stock +--- +# Cannot add stock without selecting product + +## Intent + +- outcome: Show that add-stock is rejected when no product is selected. + +```gwt +Given a product "Stock Test Widget" with SKU "STW-001" exists +And I am on the admin products page +When I switch to the "Add Stock" tab and I enter quantity 50 and I click "Add Stock" +Then I should see validation error "Please select a product" +``` diff --git a/specs/behavior/frontend/admin/add-stock.examples/s-004-cannot-add-zero-quantity.sdp.md b/specs/behavior/frontend/admin/add-stock.examples/s-004-cannot-add-zero-quantity.sdp.md new file mode 100644 index 00000000..fc2acb71 --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.examples/s-004-cannot-add-zero-quantity.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.admin.add-stock.cannot-add-zero-quantity +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.add-stock + verifies: spec:behavior.frontend.admin.add-stock +--- +# Cannot add zero quantity + +## Intent + +- outcome: Show that add-stock is rejected when the quantity is zero. + +```gwt +Given a product "Stock Test Widget" with SKU "STW-001" exists +And I am on the admin products page +When I switch to the "Add Stock" tab and I select the product "Stock Test Widget" and I enter quantity 0 and I click "Add Stock" +Then I should see validation error "Quantity must be at least 1" +``` diff --git a/specs/behavior/frontend/admin/add-stock.examples/s-005-cannot-add-stock-without-quantity.sdp.md b/specs/behavior/frontend/admin/add-stock.examples/s-005-cannot-add-stock-without-quantity.sdp.md new file mode 100644 index 00000000..53c19fab --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.examples/s-005-cannot-add-stock-without-quantity.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.admin.add-stock.cannot-add-stock-without-quantity +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.add-stock + verifies: spec:behavior.frontend.admin.add-stock +--- +# Cannot add stock without quantity + +## Intent + +- outcome: Show that add-stock is rejected when quantity is omitted. + +```gwt +Given a product "Stock Test Widget" with SKU "STW-001" exists +And I am on the admin products page +When I switch to the "Add Stock" tab and I select the product "Stock Test Widget" and I click "Add Stock" +Then I should see validation error "Quantity is required" +``` diff --git a/specs/behavior/frontend/admin/add-stock.sdp.md b/specs/behavior/frontend/admin/add-stock.sdp.md new file mode 100644 index 00000000..06d11a3c --- /dev/null +++ b/specs/behavior/frontend/admin/add-stock.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.frontend.admin.add-stock +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Add Stock (Integration) + +## Intent + +- actor: an inventory manager +- outcome: Add stock to existing products so those products are available for sale. diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-001-view-agents-dashboard-with-pending-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-001-view-agents-dashboard-with-pending-approvals.sdp.md new file mode 100644 index 00000000..f7d48b24 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-001-view-agents-dashboard-with-pending-approvals.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-agents-dashboard-with-pending-approvals +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View agents dashboard with pending approvals + +## Intent + +- outcome: Show that the agents dashboard displays pending-approval, active-agent, and events-processed counts. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are pending agent approvals in the system +When I view the agents dashboard +Then I should see the pending approvals count +And I should see the active agents count +And I should see the total events processed count +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-002-view-agents-dashboard-with-no-pending-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-002-view-agents-dashboard-with-no-pending-approvals.sdp.md new file mode 100644 index 00000000..f1f0d013 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-002-view-agents-dashboard-with-no-pending-approvals.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-agents-dashboard-with-no-pending-approvals +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View agents dashboard with no pending approvals + +## Intent + +- outcome: Show that the agents dashboard reports zero pending approvals and hides the pending badge. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are no pending approvals +When I view the agents dashboard +Then I should see the pending approvals count as "0" +And the "Pending Approvals" tab should not show a badge +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-003-navigate-to-approval-detail-from-dashboard.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-003-navigate-to-approval-detail-from-dashboard.sdp.md new file mode 100644 index 00000000..f298505c --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-003-navigate-to-approval-detail-from-dashboard.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.navigate-to-approval-detail-from-dashboard +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Navigate to approval detail from dashboard + +## Intent + +- outcome: Show that clicking an approval card from the dashboard opens that approval's detail page. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestCustomerOutreach" from "churn-risk-agent" +When I click on the approval card +Then I should be navigated to the approval detail page +And I should see the action type "SuggestCustomerOutreach" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-004-view-approval-list-with-pending-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-004-view-approval-list-with-pending-approvals.sdp.md new file mode 100644 index 00000000..684b5445 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-004-view-approval-list-with-pending-approvals.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-approval-list-with-pending-approvals +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View approval list with pending approvals + +## Intent + +- outcome: Show that the pending-approvals tab lists cards with action type, agent, confidence text, and expiration. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are multiple pending approvals +When I view the "Pending Approvals" tab +Then I should see approval cards in a grid layout +And each card should display the action type +And each card should display the agent ID +And each card should display the confidence level with text label +And each card should display the expiration time +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-005-filter-approvals-by-status.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-005-filter-approvals-by-status.sdp.md new file mode 100644 index 00000000..bb8dd708 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-005-filter-approvals-by-status.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.filter-approvals-by-status +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Filter approvals by status + +## Intent + +- outcome: Show that filtering approvals by approved status shows only approved badges. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are approvals with mixed statuses +When I filter approvals by "approved" status +Then I should only see approvals with "Approved" status badge +And the count should match the filter +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-006-click-approval-card-to-navigate-to-detail.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-006-click-approval-card-to-navigate-to-detail.sdp.md new file mode 100644 index 00000000..34a868ed --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-006-click-approval-card-to-navigate-to-detail.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.click-approval-card-to-navigate-to-detail +kind: example +altitude: story +readiness: scoped +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Click approval card to navigate to detail + +## Intent + +- outcome: Show that clicking an approval card navigates to that approval's detail route. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval +When I click on an approval card +Then I should be navigated to "/admin/agents/approvals/{approvalId}" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-007-view-pending-approval-detail.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-007-view-pending-approval-detail.sdp.md new file mode 100644 index 00000000..036d6466 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-007-view-pending-approval-detail.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-pending-approval-detail +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View pending approval detail + +## Intent + +- outcome: Show that a pending approval detail includes action, agent, confidence text, payload, and expiration. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval with confidence 0.75 +When I view the approval detail +Then I should see the action type +And I should see the agent ID +And I should see the confidence badge showing "Medium: 75%" +And I should see the reason/analysis text +And I should see the action payload in JSON format +And I should see the triggering event IDs +And I should see the creation time +And I should see the expiration countdown +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-008-view-already-approved-approval.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-008-view-already-approved-approval.sdp.md new file mode 100644 index 00000000..4d7f639d --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-008-view-already-approved-approval.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-already-approved-approval +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View already approved approval + +## Intent + +- outcome: Show that an already-approved approval shows reviewer details and hides the action panel. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is an approved approval with reviewer "admin-001" +When I view the approval detail +Then I should see the "Approved" status badge +And I should see the reviewer ID "admin-001" +And I should see the review timestamp +And I should see the review note if present +And I should not see the action panel +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-009-view-already-rejected-approval.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-009-view-already-rejected-approval.sdp.md new file mode 100644 index 00000000..33dace9d --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-009-view-already-rejected-approval.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-already-rejected-approval +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View already rejected approval + +## Intent + +- outcome: Show that an already-rejected approval shows rejected status and hides the action panel. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a rejected approval +When I view the approval detail +Then I should see the "Rejected" status badge +And I should see the reviewer information +And I should not see the action panel +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-010-view-expired-approval.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-010-view-expired-approval.sdp.md new file mode 100644 index 00000000..df4807db --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-010-view-expired-approval.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-expired-approval +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View expired approval + +## Intent + +- outcome: Show that an expired approval shows expired status and blocks further action. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is an expired approval +When I view the approval detail +Then I should see the "Expired" status badge +And I should not see the action panel +And I should see a visual indicator that no action can be taken +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-011-confidence-conveyed-via-text-label-wcag-1-4-1.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-011-confidence-conveyed-via-text-label-wcag-1-4-1.sdp.md new file mode 100644 index 00000000..b34d8fcc --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-011-confidence-conveyed-via-text-label-wcag-1-4-1.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.confidence-conveyed-via-text-label-wcag-1-4-1 +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Confidence conveyed via text label (WCAG 1.4.1) + +## Intent + +- outcome: Show that confidence is conveyed as a text label such as Low: 55%, not color alone. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval with confidence 0.55 +When I view the approval detail +Then the confidence badge should show "Low: 55%" +And the confidence level should be conveyed through text, not color alone +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-012-approve-pending-action-with-note.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-012-approve-pending-action-with-note.sdp.md new file mode 100644 index 00000000..d9d61411 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-012-approve-pending-action-with-note.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approve-pending-action-with-note +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approve pending action with note + +## Intent + +- outcome: Show that approving a pending action with a note disables the buttons and returns to the list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval that I can act on +When I enter a review note "Verified customer history, proceeding with outreach" and I click "Approve" +Then I should see the button text change to "Approving..." +And both action buttons should be disabled +And I should be redirected to the approvals list +And I should see a success indication +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-013-reject-pending-action-with-note.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-013-reject-pending-action-with-note.sdp.md new file mode 100644 index 00000000..d1049e45 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-013-reject-pending-action-with-note.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.reject-pending-action-with-note +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Reject pending action with note + +## Intent + +- outcome: Show that rejecting a pending action with a note returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval that I can act on +When I enter a review note "False positive - customer already retained" and I click "Reject" +Then I should see the button text change to "Rejecting..." +And I should be redirected to the approvals list +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-014-approve-without-note.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-014-approve-without-note.sdp.md new file mode 100644 index 00000000..6c8efaf8 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-014-approve-without-note.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approve-without-note +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approve without note + +## Intent + +- outcome: Show that approving without a note still succeeds and records an empty review note. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval +When I click "Approve" without entering a note +Then the action should still succeed +And the review note should be empty in the audit record +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-015-error-during-approve-action.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-015-error-during-approve-action.sdp.md new file mode 100644 index 00000000..293fb6ec --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-015-error-during-approve-action.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.error-during-approve-action +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Error during approve action + +## Intent + +- outcome: Show that an approve error surfaces an alert and re-enables the action buttons. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval +And the backend will return an error +When I click "Approve" +Then I should see an error alert +And the alert should have role="alert" for screen reader announcement +And the buttons should become enabled again +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-016-cannot-act-on-expired-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-016-cannot-act-on-expired-approvals.sdp.md new file mode 100644 index 00000000..65b234d7 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-016-cannot-act-on-expired-approvals.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.cannot-act-on-expired-approvals +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Cannot act on expired approvals + +## Intent + +- outcome: Show that an expired approval detail hides the take-action panel. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is an approval that just expired +When I view the approval detail +Then I should not see the "Take Action" panel +And I should see the "Expired" status +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-017-view-active-agents-in-monitoring-tab.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-017-view-active-agents-in-monitoring-tab.sdp.md new file mode 100644 index 00000000..4bfe3bab --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-017-view-active-agents-in-monitoring-tab.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-active-agents-in-monitoring-tab +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View active agents in monitoring tab + +## Intent + +- outcome: Show that the monitoring tab lists active agent checkpoint cards. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are active agents processing events +When I click the "Monitoring" tab +Then I should see agent checkpoint cards +And each card should display the agent ID +And each card should display events processed count +And each card should display last processed position +And each card should display status badge +And each card should display last updated time +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-018-view-agent-checkpoint-details.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-018-view-agent-checkpoint-details.sdp.md new file mode 100644 index 00000000..f05a2b37 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-018-view-agent-checkpoint-details.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-agent-checkpoint-details +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View agent checkpoint details + +## Intent + +- outcome: Show that a checkpoint card reports events processed and active status for the named agent. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is an agent "churn-risk-agent" with 1247 events processed +When I view the monitoring tab +Then I should see "churn-risk-agent" card +And the events processed should show "1,247" +And the status should show "Active" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-019-no-active-agents.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-019-no-active-agents.sdp.md new file mode 100644 index 00000000..6e42f5d8 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-019-no-active-agents.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.no-active-agents +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# No active agents + +## Intent + +- outcome: Show that the monitoring tab shows an empty state when no agents have checkpoints. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are no agent checkpoints +When I view the monitoring tab +Then I should see an empty state message +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-020-view-agent-decision-history.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-020-view-agent-decision-history.sdp.md new file mode 100644 index 00000000..1ee5b48d --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-020-view-agent-decision-history.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-agent-decision-history +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View agent decision history + +## Intent + +- outcome: Show that decision history lists past agent decisions with type, time, confidence, and action. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the agent has made decisions in the past +When I click the "Decision History" tab +Then I should see a list of past agent decisions +And each decision should display the event type +And each decision should display the timestamp +And each decision should display the confidence level +And each decision should display the action taken +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-021-view-decision-detail-with-reasoning.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-021-view-decision-detail-with-reasoning.sdp.md new file mode 100644 index 00000000..fe4c3a62 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-021-view-decision-detail-with-reasoning.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-decision-detail-with-reasoning +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View decision detail with reasoning + +## Intent + +- outcome: Show that opening a history decision reveals reasoning, triggering events, and approval need. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the agent has made a decision with ID "dec_123" +When I click on the decision in the history list +Then I should see the full reasoning text +And I should see the triggering event IDs +And I should see whether approval was required +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-022-empty-decision-history.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-022-empty-decision-history.sdp.md new file mode 100644 index 00000000..57fa7cdf --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-022-empty-decision-history.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.empty-decision-history +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Empty decision history + +## Intent + +- outcome: Show that empty decision history explains what will appear when the agent decides. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the agent has not made any decisions yet +When I view the "Decision History" tab +Then I should see an empty state message +And the message should explain what will appear here +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-023-view-customers-approaching-churn-threshold.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-023-view-customers-approaching-churn-threshold.sdp.md new file mode 100644 index 00000000..e49b51c9 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-023-view-customers-approaching-churn-threshold.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-customers-approaching-churn-threshold +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View customers approaching churn threshold + +## Intent + +- outcome: Show that risk preview lists customers approaching the churn-cancellation threshold. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And customers exist with the following cancellation counts: +When I view the "Risk Preview" section +Then I should see customers ordered by proximity to threshold +And I should see "cust_alice" with progress "2/3" +And I should see "cust_bob" with progress "1/3" +And I should not see "cust_charlie" (no cancellations) +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-024-customer-risk-progress-indicator.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-024-customer-risk-progress-indicator.sdp.md new file mode 100644 index 00000000..ce94102e --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-024-customer-risk-progress-indicator.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.customer-risk-progress-indicator +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Customer risk progress indicator + +## Intent + +- outcome: Show that a customer risk progress indicator is accessible and not color-only. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And customer "cust_at_risk" has 2 of 3 cancellations +When I view the risk preview +Then the progress bar for "cust_at_risk" should show approximately 66% +And the progress should be accessible (not color-only per WCAG 1.4.1) +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-025-no-customers-approaching-threshold.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-025-no-customers-approaching-threshold.sdp.md new file mode 100644 index 00000000..2867b56b --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-025-no-customers-approaching-threshold.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.no-customers-approaching-threshold +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# No customers approaching threshold + +## Intent + +- outcome: Show that risk preview explains when no customers are approaching the threshold. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And no customers have any cancellations +When I view the risk preview +Then I should see a message indicating no customers are at risk +And the message should explain what will appear here +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-026-navigate-to-low-stock-restock-approval-detail.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-026-navigate-to-low-stock-restock-approval-detail.sdp.md new file mode 100644 index 00000000..be5f5ba6 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-026-navigate-to-low-stock-restock-approval-detail.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.navigate-to-low-stock-restock-approval-detail +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Navigate to low stock restock approval detail + +## Intent + +- outcome: Show that a SuggestRestock approval card opens detail with product and restock quantity. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestRestock" from "low-stock-alert-agent" +When I click on the approval card +Then I should be navigated to the approval detail page +And I should see the action type "SuggestRestock" +And I should see the product ID in the payload +And I should see the recommended restock quantity +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-027-view-low-stock-alert-approval-with-product-context.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-027-view-low-stock-alert-approval-with-product-context.sdp.md new file mode 100644 index 00000000..dcb6fe22 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-027-view-low-stock-alert-approval-with-product-context.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-low-stock-alert-approval-with-product-context +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View low stock alert approval with product context + +## Intent + +- outcome: Show that a low-stock approval detail includes product quantity, threshold, and high confidence text. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestRestock" with confidence 0.85 +When I view the approval detail +Then I should see the action type "SuggestRestock" +And I should see the agent ID "low-stock-alert-agent" +And I should see the confidence badge showing "High: 85%" +And I should see the reason explaining low stock detected +And the payload should include "productId" +And the payload should include "currentQuantity" +And the payload should include "recommendedQuantity" +And the payload should include "threshold" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-028-approve-low-stock-restock-suggestion.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-028-approve-low-stock-restock-suggestion.sdp.md new file mode 100644 index 00000000..f078674e --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-028-approve-low-stock-restock-suggestion.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approve-low-stock-restock-suggestion +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approve low stock restock suggestion + +## Intent + +- outcome: Show that approving a restock suggestion returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestRestock" that I can act on +When I enter a review note "Approved - ordering 50 units from supplier" and I click "Approve" +Then I should see the button text change to "Approving..." +And I should be redirected to the approvals list +And I should see a success indication +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-029-reject-low-stock-restock-suggestion.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-029-reject-low-stock-restock-suggestion.sdp.md new file mode 100644 index 00000000..6a309d21 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-029-reject-low-stock-restock-suggestion.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.reject-low-stock-restock-suggestion +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Reject low stock restock suggestion + +## Intent + +- outcome: Show that rejecting a restock suggestion returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestRestock" that I can act on +When I enter a review note "Product being discontinued - no restock needed" and I click "Reject" +Then I should see the button text change to "Rejecting..." +And I should be redirected to the approvals list +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-030-navigate-to-high-value-order-vip-review-approval-detail.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-030-navigate-to-high-value-order-vip-review-approval-detail.sdp.md new file mode 100644 index 00000000..b3e2f07a --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-030-navigate-to-high-value-order-vip-review-approval-detail.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.navigate-to-high-value-order-vip-review-approval-detail +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Navigate to high-value order VIP review approval detail + +## Intent + +- outcome: Show that a FlagForVIPReview approval card opens detail with order id and total. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "FlagForVIPReview" from "high-value-order-agent" +When I click on the approval card +Then I should be navigated to the approval detail page +And I should see the action type "FlagForVIPReview" +And I should see the order ID in the payload +And I should see the order total amount +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-031-view-high-value-order-approval-with-order-context.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-031-view-high-value-order-approval-with-order-context.sdp.md new file mode 100644 index 00000000..1c94361c --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-031-view-high-value-order-approval-with-order-context.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-high-value-order-approval-with-order-context +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View high-value order approval with order context + +## Intent + +- outcome: Show that a high-value order approval detail includes order total, threshold, and high confidence text. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "FlagForVIPReview" with confidence 0.95 +When I view the approval detail +Then I should see the action type "FlagForVIPReview" +And I should see the agent ID "high-value-order-agent" +And I should see the confidence badge showing "High: 95%" +And I should see the reason explaining high-value order detected +And the payload should include "orderId" +And the payload should include "customerId" +And the payload should include "totalAmount" +And the payload should include "threshold" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-032-approve-vip-review-for-high-value-order.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-032-approve-vip-review-for-high-value-order.sdp.md new file mode 100644 index 00000000..3d710988 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-032-approve-vip-review-for-high-value-order.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approve-vip-review-for-high-value-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approve VIP review for high-value order + +## Intent + +- outcome: Show that approving a VIP review flag returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "FlagForVIPReview" that I can act on +When I enter a review note "VIP customer - expediting order processing" and I click "Approve" +Then I should see the button text change to "Approving..." +And I should be redirected to the approvals list +And I should see a success indication +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-033-reject-vip-review-flag.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-033-reject-vip-review-flag.sdp.md new file mode 100644 index 00000000..fb9fa24a --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-033-reject-vip-review-flag.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.reject-vip-review-flag +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Reject VIP review flag + +## Intent + +- outcome: Show that rejecting a VIP review flag returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "FlagForVIPReview" that I can act on +When I enter a review note "Standard processing sufficient - not a VIP account" and I click "Reject" +Then I should see the button text change to "Rejecting..." +And I should be redirected to the approvals list +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-034-navigate-to-order-consolidation-suggestion-approval-detail.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-034-navigate-to-order-consolidation-suggestion-approval-detail.sdp.md new file mode 100644 index 00000000..8b8bdc23 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-034-navigate-to-order-consolidation-suggestion-approval-detail.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.navigate-to-order-consolidation-suggestion-approval-detail +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Navigate to order consolidation suggestion approval detail + +## Intent + +- outcome: Show that a consolidation approval card opens detail with customer and order ids. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestOrderConsolidation" from "order-consolidation-agent" +When I click on the approval card +Then I should be navigated to the approval detail page +And I should see the action type "SuggestOrderConsolidation" +And I should see the customer ID in the payload +And I should see the list of order IDs to consolidate +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-035-view-order-consolidation-approval-with-order-list.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-035-view-order-consolidation-approval-with-order-list.sdp.md new file mode 100644 index 00000000..ef83e0c1 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-035-view-order-consolidation-approval-with-order-list.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-order-consolidation-approval-with-order-list +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View order consolidation approval with order list + +## Intent + +- outcome: Show that a consolidation approval detail includes order count, window, and potential savings. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestOrderConsolidation" with confidence 0.80 +When I view the approval detail +Then I should see the action type "SuggestOrderConsolidation" +And I should see the agent ID "order-consolidation-agent" +And I should see the confidence badge showing "High: 80%" +And I should see the reason explaining multiple recent orders detected +And the payload should include "customerId" +And the payload should include "orderIds" +And the payload should include "orderCount" +And the payload should include "windowHours" +And the payload should include "potentialSavings" +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-036-approve-order-consolidation-suggestion.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-036-approve-order-consolidation-suggestion.sdp.md new file mode 100644 index 00000000..8e28ccc6 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-036-approve-order-consolidation-suggestion.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approve-order-consolidation-suggestion +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approve order consolidation suggestion + +## Intent + +- outcome: Show that approving a consolidation suggestion returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestOrderConsolidation" that I can act on +When I enter a review note "Customer contacted - consolidating orders for single shipment" and I click "Approve" +Then I should see the button text change to "Approving..." +And I should be redirected to the approvals list +And I should see a success indication +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-037-reject-order-consolidation-suggestion.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-037-reject-order-consolidation-suggestion.sdp.md new file mode 100644 index 00000000..cab1d404 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-037-reject-order-consolidation-suggestion.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.reject-order-consolidation-suggestion +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Reject order consolidation suggestion + +## Intent + +- outcome: Show that rejecting a consolidation suggestion returns the admin to the approvals list. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there is a pending approval "SuggestOrderConsolidation" that I can act on +When I enter a review note "Customer requested separate deliveries to different addresses" and I click "Reject" +Then I should see the button text change to "Rejecting..." +And I should be redirected to the approvals list +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-038-view-decision-history-filtered-by-agent-type.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-038-view-decision-history-filtered-by-agent-type.sdp.md new file mode 100644 index 00000000..88149982 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-038-view-decision-history-filtered-by-agent-type.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-decision-history-filtered-by-agent-type +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View decision history filtered by agent type + +## Intent + +- outcome: Show that decision history can list and filter decisions from every agent type. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And decisions exist from multiple agents: +When I click the "Decision History" tab +Then I should see decisions from all agent types +And I should be able to filter by agent ID +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-039-view-low-stock-agent-decision-in-history.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-039-view-low-stock-agent-decision-in-history.sdp.md new file mode 100644 index 00000000..8e3c2a10 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-039-view-low-stock-agent-decision-in-history.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-low-stock-agent-decision-in-history +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View low stock agent decision in history + +## Intent + +- outcome: Show that a SuggestRestock history decision includes product id and whether approval was required. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the "low-stock-alert-agent" has made a decision +When I click the "Decision History" tab and I click on the "SuggestRestock" decision +Then I should see the full reasoning text +And I should see the product ID that triggered the alert +And I should see whether approval was required +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-040-view-high-value-order-agent-decision-in-history.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-040-view-high-value-order-agent-decision-in-history.sdp.md new file mode 100644 index 00000000..895e8297 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-040-view-high-value-order-agent-decision-in-history.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-high-value-order-agent-decision-in-history +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View high-value order agent decision in history + +## Intent + +- outcome: Show that a FlagForVIPReview history decision includes the triggering order total. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the "high-value-order-agent" has made a decision +When I click the "Decision History" tab and I click on the "FlagForVIPReview" decision +Then I should see the full reasoning text +And I should see the order total that triggered the flag +And I should see whether approval was required +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-041-view-order-consolidation-agent-decision-in-history.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-041-view-order-consolidation-agent-decision-in-history.sdp.md new file mode 100644 index 00000000..ffce62fd --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-041-view-order-consolidation-agent-decision-in-history.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-order-consolidation-agent-decision-in-history +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View order consolidation agent decision in history + +## Intent + +- outcome: Show that a SuggestOrderConsolidation history decision includes the order count in the window. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the "order-consolidation-agent" has made a decision +When I click the "Decision History" tab and I click on the "SuggestOrderConsolidation" decision +Then I should see the full reasoning text +And I should see the number of orders in the consolidation window +And I should see whether approval was required +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-042-view-products-approaching-low-stock-threshold.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-042-view-products-approaching-low-stock-threshold.sdp.md new file mode 100644 index 00000000..9449e2e5 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-042-view-products-approaching-low-stock-threshold.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.view-products-approaching-low-stock-threshold +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# View products approaching low stock threshold + +## Intent + +- outcome: Show that stock preview lists products approaching the low-stock threshold. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And products exist with the following stock levels: +When I view the "Stock Preview" section +Then I should see products ordered by proximity to threshold +And I should see "prod_widget" with status "Critical (3/5)" +And I should see "prod_gadget" with status "Warning (8/5)" +And I should not see "prod_gizmo" (well above threshold) +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-043-stock-level-progress-indicator.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-043-stock-level-progress-indicator.sdp.md new file mode 100644 index 00000000..83c564a8 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-043-stock-level-progress-indicator.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.stock-level-progress-indicator +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Stock level progress indicator + +## Intent + +- outcome: Show that a stock-level progress indicator is accessible and not color-only. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And product "prod_at_risk" has 2 of 5 stock threshold +When I view the stock preview +Then the progress bar for "prod_at_risk" should show critical level +And the progress should be accessible (not color-only per WCAG 1.4.1) +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-044-approval-card-is-keyboard-accessible.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-044-approval-card-is-keyboard-accessible.sdp.md new file mode 100644 index 00000000..adb63f2f --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-044-approval-card-is-keyboard-accessible.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.approval-card-is-keyboard-accessible +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Approval card is keyboard accessible + +## Intent + +- outcome: Show that an approval card is reachable by keyboard with visible focus. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are pending approvals +When I focus on an approval card using Tab key +Then the card should have visible focus indicator +And I should be able to activate it with Enter key +And I should be able to activate it with Space key +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-045-screen-reader-announces-action-status-changes.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-045-screen-reader-announces-action-status-changes.sdp.md new file mode 100644 index 00000000..899be8be --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-045-screen-reader-announces-action-status-changes.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.screen-reader-announces-action-status-changes +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Screen reader announces action status changes + +## Intent + +- outcome: Show that a screen reader announces approve progress on the approval detail page. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And I am on an approval detail page +When I click "Approve" +Then the screen reader should announce "Approving action..." +And when the action completes, appropriate feedback should be provided +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-046-confidence-level-conveyed-via-text-not-just-color.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-046-confidence-level-conveyed-via-text-not-just-color.sdp.md new file mode 100644 index 00000000..b6265597 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-046-confidence-level-conveyed-via-text-not-just-color.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.confidence-level-conveyed-via-text-not-just-color +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Confidence level conveyed via text not just color + +## Intent + +- outcome: Show that confidence badges include High, Medium, or Low text rather than color alone. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And there are approvals with different confidence levels +When I view the approval cards +Then each confidence badge should include text "High", "Medium", or "Low" +And the text should be readable without relying on color perception +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-047-focus-trap-in-action-buttons.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-047-focus-trap-in-action-buttons.sdp.md new file mode 100644 index 00000000..565e4a54 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-047-focus-trap-in-action-buttons.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.focus-trap-in-action-buttons +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Focus trap in action buttons + +## Intent + +- outcome: Show that tabbing the action panel moves through note, Reject, and Approve. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And I am on an approval detail page with action panel +When I Tab through the page +Then focus should move through the review note textarea +And focus should move to the Reject button +And focus should move to the Approve button +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-048-handle-approval-not-found.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-048-handle-approval-not-found.sdp.md new file mode 100644 index 00000000..512afd83 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-048-handle-approval-not-found.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.handle-approval-not-found +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Handle approval not found + +## Intent + +- outcome: Show that a missing approval route shows an approval-not-found message with a back link. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And I navigate to an approval that does not exist +When the page loads +Then I should see "Approval not found" message +And I should see a link to go back to the approvals list +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-049-handle-network-error-loading-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-049-handle-network-error-loading-approvals.sdp.md new file mode 100644 index 00000000..6cfe59d6 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-049-handle-network-error-loading-approvals.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.handle-network-error-loading-approvals +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Handle network error loading approvals + +## Intent + +- outcome: Show that a network error on the approvals list offers retry and recovers when the backend returns. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the backend is temporarily unavailable +When I try to load the approvals list and I click "Retry" and the backend recovers +Then I should see an error message +And I should see a "Retry" button +And the approvals should load successfully +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.examples/s-050-route-level-error-boundary.sdp.md b/specs/behavior/frontend/admin/agent-approvals.examples/s-050-route-level-error-boundary.sdp.md new file mode 100644 index 00000000..c160c12e --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.examples/s-050-route-level-error-boundary.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals.route-level-error-boundary +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.agent-approvals + verifies: spec:behavior.frontend.admin.agent-approvals +--- +# Route-level error boundary + +## Intent + +- outcome: Show that a route-level error boundary shows a user-friendly message and a way back. + +```gwt +Given I am logged in as an admin +And I am on the agents admin page +And the approval detail page encounters an unexpected error +When the error is caught by the error boundary +Then I should see a user-friendly error message +And I should see a way to navigate back or retry +``` diff --git a/specs/behavior/frontend/admin/agent-approvals.sdp.md b/specs/behavior/frontend/admin/agent-approvals.sdp.md new file mode 100644 index 00000000..164a59e8 --- /dev/null +++ b/specs/behavior/frontend/admin/agent-approvals.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.frontend.admin.agent-approvals +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Agent Approval Workflow + +## Intent + +- actor: an admin user +- outcome: Review and act on AI agent recommendations so automated actions require human oversight before execution. diff --git a/specs/behavior/frontend/admin/create-product.examples/s-001-create-product-successfully.sdp.md b/specs/behavior/frontend/admin/create-product.examples/s-001-create-product-successfully.sdp.md new file mode 100644 index 00000000..82e78665 --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.examples/s-001-create-product-successfully.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.admin.create-product.create-product-successfully +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.create-product + verifies: spec:behavior.frontend.admin.create-product +--- +# Create product successfully + +## Intent + +- outcome: Show that filling valid product details creates the product and lists it in inventory. + +```gwt +Given I am on the admin products page +When I fill in the product name "Test Widget" and I fill in the SKU "WDG-001" and I fill in the price "49.99" and I click "Create Product" +Then I should see a success message containing "created successfully" +And eventually the product "Test Widget" should appear in the inventory list +``` diff --git a/specs/behavior/frontend/admin/create-product.examples/s-002-validation-errors-on-empty-form.sdp.md b/specs/behavior/frontend/admin/create-product.examples/s-002-validation-errors-on-empty-form.sdp.md new file mode 100644 index 00000000..8aa11dea --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.examples/s-002-validation-errors-on-empty-form.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.frontend.admin.create-product.validation-errors-on-empty-form +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.create-product + verifies: spec:behavior.frontend.admin.create-product +--- +# Validation errors on empty form + +## Intent + +- outcome: Show that creating a product with an empty form reports name, SKU, and unit-price errors. + +```gwt +Given I am on the admin products page +When I click "Create Product" without filling the form +Then I should see validation error "Product name is required" +And I should see validation error "SKU is required" +And I should see validation error "Unit price is required" +``` diff --git a/specs/behavior/frontend/admin/create-product.examples/s-003-invalid-sku-format.sdp.md b/specs/behavior/frontend/admin/create-product.examples/s-003-invalid-sku-format.sdp.md new file mode 100644 index 00000000..17a21550 --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.examples/s-003-invalid-sku-format.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.admin.create-product.invalid-sku-format +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.create-product + verifies: spec:behavior.frontend.admin.create-product +--- +# Invalid SKU format + +## Intent + +- outcome: Show that a SKU with spaces or punctuation is rejected. + +```gwt +Given I am on the admin products page +When I fill in the product name "Invalid SKU Product" and I fill in the SKU "invalid sku!" and I fill in the price "29.99" and I click "Create Product" +Then I should see validation error "SKU should contain only letters, numbers, and hyphens" +``` diff --git a/specs/behavior/frontend/admin/create-product.examples/s-004-invalid-price-zero-value.sdp.md b/specs/behavior/frontend/admin/create-product.examples/s-004-invalid-price-zero-value.sdp.md new file mode 100644 index 00000000..85ed3610 --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.examples/s-004-invalid-price-zero-value.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.admin.create-product.invalid-price-zero-value +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.create-product + verifies: spec:behavior.frontend.admin.create-product +--- +# Invalid price - zero value + +## Intent + +- outcome: Show that a zero unit price is rejected. + +```gwt +Given I am on the admin products page +When I fill in the product name "Zero Price Product" and I fill in the SKU "ZPP-001" and I fill in the price "0" and I click "Create Product" +Then I should see validation error "Unit price must be a positive number" +``` diff --git a/specs/behavior/frontend/admin/create-product.examples/s-005-invalid-price-exceeds-maximum.sdp.md b/specs/behavior/frontend/admin/create-product.examples/s-005-invalid-price-exceeds-maximum.sdp.md new file mode 100644 index 00000000..b625597d --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.examples/s-005-invalid-price-exceeds-maximum.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.admin.create-product.invalid-price-exceeds-maximum +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.admin.create-product + verifies: spec:behavior.frontend.admin.create-product +--- +# Invalid price - exceeds maximum + +## Intent + +- outcome: Show that a unit price above the catalog maximum is rejected. + +```gwt +Given I am on the admin products page +When I fill in the product name "Expensive Product" and I fill in the SKU "EXP-001" and I fill in the price "100000" and I click "Create Product" +Then I should see validation error "Unit price cannot exceed $99,999.99" +``` diff --git a/specs/behavior/frontend/admin/create-product.sdp.md b/specs/behavior/frontend/admin/create-product.sdp.md new file mode 100644 index 00000000..0378724b --- /dev/null +++ b/specs/behavior/frontend/admin/create-product.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.frontend.admin.create-product +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Create Product (Integration) + +## Intent + +- actor: an inventory manager +- outcome: Create new products in the catalog so they can be sold and tracked. diff --git a/specs/behavior/frontend/dashboard/dashboard.examples/s-001-view-dashboard-stats.sdp.md b/specs/behavior/frontend/dashboard/dashboard.examples/s-001-view-dashboard-stats.sdp.md new file mode 100644 index 00000000..fcf2652c --- /dev/null +++ b/specs/behavior/frontend/dashboard/dashboard.examples/s-001-view-dashboard-stats.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.frontend.dashboard.dashboard.view-dashboard-stats +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.dashboard.dashboard + verifies: spec:behavior.frontend.dashboard.dashboard +--- +# View dashboard stats + +## Intent + +- outcome: Show that the dashboard displays product, order, and pending-order counts. + +```gwt +Given products and orders exist in the system +When I navigate to the dashboard +Then I should see the product count +And I should see the order count +And I should see the pending orders count +``` diff --git a/specs/behavior/frontend/dashboard/dashboard.examples/s-002-show-low-stock-warning.sdp.md b/specs/behavior/frontend/dashboard/dashboard.examples/s-002-show-low-stock-warning.sdp.md new file mode 100644 index 00000000..2df072d9 --- /dev/null +++ b/specs/behavior/frontend/dashboard/dashboard.examples/s-002-show-low-stock-warning.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.dashboard.dashboard.show-low-stock-warning +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.dashboard.dashboard + verifies: spec:behavior.frontend.dashboard.dashboard +--- +# Show low stock warning + +## Intent + +- outcome: Show that the dashboard warns when a product has low stock. + +```gwt +Given a product with low stock exists +When I navigate to the dashboard +Then I should see the low stock warning +``` diff --git a/specs/behavior/frontend/dashboard/dashboard.examples/s-003-quick-action-navigates-to-create-order.sdp.md b/specs/behavior/frontend/dashboard/dashboard.examples/s-003-quick-action-navigates-to-create-order.sdp.md new file mode 100644 index 00000000..73ba52f6 --- /dev/null +++ b/specs/behavior/frontend/dashboard/dashboard.examples/s-003-quick-action-navigates-to-create-order.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.dashboard.dashboard.quick-action-navigates-to-create-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.dashboard.dashboard + verifies: spec:behavior.frontend.dashboard.dashboard +--- +# Quick action navigates to create order + +## Intent + +- outcome: Show that the dashboard New Order action opens the create-order page. + +```gwt +Given the feature fixture is in place +When I am on the dashboard and I click the "New Order" quick action +Then I should be on the create order page +``` diff --git a/specs/behavior/frontend/dashboard/dashboard.sdp.md b/specs/behavior/frontend/dashboard/dashboard.sdp.md new file mode 100644 index 00000000..cda648f1 --- /dev/null +++ b/specs/behavior/frontend/dashboard/dashboard.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.frontend.dashboard.dashboard +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Dashboard + +## Intent + +- actor: a user +- outcome: Show a system overview with product, order, and pending-order counts. diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-001-complete-flow-product-creation-to-order-confirmation.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-001-complete-flow-product-creation-to-order-confirmation.sdp.md new file mode 100644 index 00000000..15caba1a --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-001-complete-flow-product-creation-to-order-confirmation.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.complete-flow-product-creation-to-order-confirmation +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Complete flow - Product creation to order confirmation + +## Intent + +- outcome: Show that creating a product, stocking it, and submitting an order confirms the order and reduces stock. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Journey Widget" and I enter quantity 100 and I click "Add Stock" and I navigate to the products page and I navigate to the create order page and I add "Journey Widget" to the cart with quantity 5 and I submit the order and I navigate to the products page +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added successfully" +And eventually I should see "Journey Widget" in the product list +And the product "Journey Widget" should show "100" units in stock +And the cart should show 5 items +And the cart total should be "$499.95" +And I should be redirected to the order detail page +And the order status should be "submitted" +And eventually the order status should be "confirmed" +And eventually the reservation status should be "Stock Reserved" +And eventually the product "Journey Widget" should show "95" units in stock +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-002-order-fails-due-to-insufficient-stock-saga-compensation.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-002-order-fails-due-to-insufficient-stock-saga-compensation.sdp.md new file mode 100644 index 00000000..e616f248 --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-002-order-fails-due-to-insufficient-stock-saga-compensation.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.order-fails-due-to-insufficient-stock-saga-compensation +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Order fails due to insufficient stock - Saga compensation + +## Intent + +- outcome: Show that ordering more units than available cancels the order and leaves stock unchanged. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Limited Item" and I enter quantity 3 and I click "Add Stock" and I navigate to the create order page and I add "Limited Item" to the cart with quantity 10 and I submit the order and I navigate to the products page +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added successfully" +And I should be redirected to the order detail page +And eventually the order status should be "cancelled" +And eventually the reservation status should be "Reservation Failed" +And the product "Limited Item" should show "3" units in stock +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-003-order-with-multiple-items.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-003-order-with-multiple-items.sdp.md new file mode 100644 index 00000000..7017b5c9 --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-003-order-with-multiple-items.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.order-with-multiple-items +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Order with multiple items + +## Intent + +- outcome: Show that a multi-product order confirms and reduces stock for every line. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Product A" and I enter quantity 50 and I click "Add Stock" and I switch to the "Create Product" tab and I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Product B" and I enter quantity 30 and I click "Add Stock" and I navigate to the create order page and I add "Product A" to the cart with quantity 2 and I add "Product B" to the cart with quantity 3 and I submit the order and I navigate to the products page +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And eventually the product "Product B" should show "30" units in Current Inventory +And the cart should show 5 items +And the cart total should be "$155.00" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually the product "Product A" should show "48" units in stock +And the product "Product B" should show "27" units in stock +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-004-multi-product-order-rejected-atomically-when-one-product-lacks-stock-dcb.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-004-multi-product-order-rejected-atomically-when-one-product-lacks-stock-dcb.sdp.md new file mode 100644 index 00000000..c135358a --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-004-multi-product-order-rejected-atomically-when-one-product-lacks-stock-dcb.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.multi-product-order-rejected-atomically-when-one-product-lacks-stock-dcb +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Multi-product order rejected atomically when one product lacks stock (DCB) + +## Intent + +- outcome: Show that a multi-product order is rejected atomically when one line lacks stock. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "DCB Product High" and I enter quantity 100 and I click "Add Stock" and I switch to the "Create Product" tab and I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "DCB Product Low" and I enter quantity 5 and I click "Add Stock" and I navigate to the create order page and I add "DCB Product High" to the cart with quantity 10 and I add "DCB Product Low" to the cart with quantity 10 and I submit the order and I navigate to the products page +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And eventually the product "DCB Product Low" should show "5" units in Current Inventory +And I should be redirected to the order detail page +And eventually the order status should be "cancelled" +And the product "DCB Product High" should show "100" units in stock +And the product "DCB Product Low" should show "5" units in stock +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-005-full-agent-trigger-journey-churn-risk-detection.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-005-full-agent-trigger-journey-churn-risk-detection.sdp.md new file mode 100644 index 00000000..8831be79 --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-005-full-agent-trigger-journey-churn-risk-detection.sdp.md @@ -0,0 +1,38 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.full-agent-trigger-journey-churn-risk-detection +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Full agent trigger journey - Churn risk detection + +## Intent + +- outcome: Show that repeated cancellations create a SuggestCustomerOutreach approval that an admin can accept. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Agent Test Widget" and I enter quantity 100 and I click "Add Stock" and I navigate to the create order page and I add "Agent Test Widget" to the cart with quantity 1 and I submit the order and I click "Cancel Order" and I confirm the cancellation in the dialog and I navigate to the create order page and I add "Agent Test Widget" to the cart with quantity 1 and I submit the order and I click "Cancel Order" and I confirm the cancellation in the dialog and I navigate to the create order page and I add "Agent Test Widget" to the cart with quantity 1 and I submit the order and I click "Cancel Order" and I confirm the cancellation in the dialog and I navigate to the agents admin page and I click on the pending approval and I enter review note "Verified customer history - proceeding with outreach" and I click "Approve" and I click the "Decision History" tab +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually the order status should be "cancelled" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually the order status should be "cancelled" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually the order status should be "cancelled" +And eventually I should see a pending approval +And the approval should be for "SuggestCustomerOutreach" +And the confidence should be displayed +And I should see a success indication +And I should be redirected to the approvals list +And I should see the approved decision in the history +And the decision should show action "SuggestCustomerOutreach" +And the decision should show status "approved" +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-006-full-agent-trigger-journey-low-stock-alert-detection.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-006-full-agent-trigger-journey-low-stock-alert-detection.sdp.md new file mode 100644 index 00000000..15dea69f --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-006-full-agent-trigger-journey-low-stock-alert-detection.sdp.md @@ -0,0 +1,33 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.full-agent-trigger-journey-low-stock-alert-detection +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Full agent trigger journey - Low stock alert detection + +## Intent + +- outcome: Show that orders that drop stock below the threshold create a SuggestRestock approval. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Low Stock Test Item" and I enter quantity 10 and I click "Add Stock" and I navigate to the create order page and I add "Low Stock Test Item" to the cart with quantity 3 and I submit the order and I navigate to the create order page and I add "Low Stock Test Item" to the cart with quantity 3 and I submit the order and I navigate to the agents admin page and I click on the pending approval and I enter review note "Low stock confirmed - ordering 20 units from supplier" and I click "Approve" and I click the "Decision History" tab +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually I should see a pending approval +And the approval should be for "SuggestRestock" +And the confidence should be displayed +And I should see a success indication +And I should be redirected to the approvals list +And I should see the approved decision in the history +And the decision should show action "SuggestRestock" +And the decision should show status "approved" +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-007-full-agent-trigger-journey-high-value-order-detection.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-007-full-agent-trigger-journey-high-value-order-detection.sdp.md new file mode 100644 index 00000000..3f6863fa --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-007-full-agent-trigger-journey-high-value-order-detection.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.full-agent-trigger-journey-high-value-order-detection +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Full agent trigger journey - High-value order detection + +## Intent + +- outcome: Show that a high-value order creates a FlagForVIPReview approval that an admin can accept. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Premium VIP Widget" and I enter quantity 50 and I click "Add Stock" and I navigate to the create order page and I add "Premium VIP Widget" to the cart with quantity 6 and I submit the order and I navigate to the agents admin page and I click on the pending approval and I enter review note "VIP customer - priority handling approved" and I click "Approve" and I click the "Decision History" tab +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And the cart total should be "$600.00" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually I should see a pending approval +And the approval should be for "FlagForVIPReview" +And the confidence should be displayed +And I should see a success indication +And I should be redirected to the approvals list +And I should see the approved decision in the history +And the decision should show action "FlagForVIPReview" +And the decision should show status "approved" +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-008-full-agent-trigger-journey-order-consolidation-suggestion.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-008-full-agent-trigger-journey-order-consolidation-suggestion.sdp.md new file mode 100644 index 00000000..c85c52ba --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.examples/s-008-full-agent-trigger-journey-order-consolidation-suggestion.sdp.md @@ -0,0 +1,35 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey.full-agent-trigger-journey-order-consolidation-suggestion +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.e2e-journeys.full-order-journey + verifies: spec:behavior.frontend.e2e-journeys.full-order-journey +--- +# Full agent trigger journey - Order consolidation suggestion + +## Intent + +- outcome: Show that several same-customer orders create a SuggestOrderConsolidation approval. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Consolidation Widget" and I enter quantity 100 and I click "Add Stock" and I navigate to the create order page and I add "Consolidation Widget" to the cart with quantity 1 and I submit the order and I navigate to the create order page and I add "Consolidation Widget" to the cart with quantity 2 and I submit the order and I navigate to the create order page and I add "Consolidation Widget" to the cart with quantity 1 and I submit the order and I navigate to the agents admin page and I click on the pending approval and I enter review note "Customer agreed - combining into single shipment" and I click "Approve" and I click the "Decision History" tab +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually I should see a pending approval +And the approval should be for "SuggestOrderConsolidation" +And the confidence should be displayed +And I should see a success indication +And I should be redirected to the approvals list +And I should see the approved decision in the history +And the decision should show action "SuggestOrderConsolidation" +And the decision should show status "approved" +``` diff --git a/specs/behavior/frontend/e2e-journeys/full-order-journey.sdp.md b/specs/behavior/frontend/e2e-journeys/full-order-journey.sdp.md new file mode 100644 index 00000000..c0daed48 --- /dev/null +++ b/specs/behavior/frontend/e2e-journeys/full-order-journey.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.frontend.e2e-journeys.full-order-journey +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Full Order Journey + +## Intent + +- outcome: Walk the catalog from product creation through order confirmation, including stock, saga compensation, and agent triggers. diff --git a/specs/behavior/frontend/orders/create-order.examples/s-001-create-and-submit-order-successfully.sdp.md b/specs/behavior/frontend/orders/create-order.examples/s-001-create-and-submit-order-successfully.sdp.md new file mode 100644 index 00000000..b2677c64 --- /dev/null +++ b/specs/behavior/frontend/orders/create-order.examples/s-001-create-and-submit-order-successfully.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.orders.create-order.create-and-submit-order-successfully +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.create-order + verifies: spec:behavior.frontend.orders.create-order +--- +# Create and submit order successfully + +## Intent + +- outcome: Show that a stocked cart can be submitted and the order becomes confirmed. + +```gwt +Given products exist with stock +When I navigate to the create order page and I add "Test Product" to cart with quantity 2 and I click "Create Order" +Then the cart total should be correct +And I should be redirected to order detail +And the order status should be "submitted" +And eventually the order status should be "confirmed" +``` diff --git a/specs/behavior/frontend/orders/create-order.examples/s-002-cannot-submit-empty-cart.sdp.md b/specs/behavior/frontend/orders/create-order.examples/s-002-cannot-submit-empty-cart.sdp.md new file mode 100644 index 00000000..899bc586 --- /dev/null +++ b/specs/behavior/frontend/orders/create-order.examples/s-002-cannot-submit-empty-cart.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.orders.create-order.cannot-submit-empty-cart +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.create-order + verifies: spec:behavior.frontend.orders.create-order +--- +# Cannot submit empty cart + +## Intent + +- outcome: Show that Create Order stays disabled when the cart is empty. + +```gwt +Given products exist with stock +When I navigate to the create order page +Then the Create Order button should be disabled +``` diff --git a/specs/behavior/frontend/orders/create-order.examples/s-003-update-quantity-in-cart.sdp.md b/specs/behavior/frontend/orders/create-order.examples/s-003-update-quantity-in-cart.sdp.md new file mode 100644 index 00000000..84602483 --- /dev/null +++ b/specs/behavior/frontend/orders/create-order.examples/s-003-update-quantity-in-cart.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.orders.create-order.update-quantity-in-cart +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.create-order + verifies: spec:behavior.frontend.orders.create-order +--- +# Update quantity in cart + +## Intent + +- outcome: Show that changing a cart line quantity updates the cart total. + +```gwt +Given products exist with stock +When I add a product to cart and I change the quantity to 3 +Then the cart total should update +``` diff --git a/specs/behavior/frontend/orders/create-order.examples/s-004-remove-item-from-cart.sdp.md b/specs/behavior/frontend/orders/create-order.examples/s-004-remove-item-from-cart.sdp.md new file mode 100644 index 00000000..28ffa945 --- /dev/null +++ b/specs/behavior/frontend/orders/create-order.examples/s-004-remove-item-from-cart.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.orders.create-order.remove-item-from-cart +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.create-order + verifies: spec:behavior.frontend.orders.create-order +--- +# Remove item from cart + +## Intent + +- outcome: Show that removing one of two cart lines leaves a single product. + +```gwt +Given products exist with stock +When I add two products to cart and I remove one product +Then only one product should remain +``` diff --git a/specs/behavior/frontend/orders/create-order.sdp.md b/specs/behavior/frontend/orders/create-order.sdp.md new file mode 100644 index 00000000..c57d456c --- /dev/null +++ b/specs/behavior/frontend/orders/create-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.frontend.orders.create-order +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Create Order (Integration) + +## Intent + +- actor: a customer +- outcome: Create new orders from a stocked cart so the customer can purchase products. diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-001-view-confirmed-order.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-001-view-confirmed-order.sdp.md new file mode 100644 index 00000000..70fb8ae1 --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-001-view-confirmed-order.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.orders.order-detail.view-confirmed-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# View confirmed order + +## Intent + +- outcome: Show that a confirmed order detail page reports confirmed status and reserved stock. + +```gwt +Given a confirmed order exists +When I navigate to that order +Then I should see status "confirmed" +And I should see "Stock Reserved" badge +``` diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-002-view-cancelled-order.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-002-view-cancelled-order.sdp.md new file mode 100644 index 00000000..8ae392e0 --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-002-view-cancelled-order.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.orders.order-detail.view-cancelled-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# View cancelled order + +## Intent + +- outcome: Show that a cancelled order detail page reports cancelled status and the cancellation reason. + +```gwt +Given a cancelled order exists +When I navigate to that order +Then I should see status "cancelled" +And I should see the cancellation reason +``` diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-003-order-detail-shows-instant-status-updates-via-reactive-projection.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-003-order-detail-shows-instant-status-updates-via-reactive-projection.sdp.md new file mode 100644 index 00000000..7a63824c --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-003-order-detail-shows-instant-status-updates-via-reactive-projection.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.frontend.orders.order-detail.order-detail-shows-instant-status-updates-via-reactive-projection +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# Order detail shows instant status updates via reactive projection + +## Intent + +- outcome: Show that order detail moves from submitted to confirmed through the reactive projection. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Reactive Widget" and I enter quantity 50 and I click "Add Stock" and I navigate to the create order page and I add "Reactive Widget" to the cart with quantity 2 and I submit the order and I navigate to the products page +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And the order status should be "submitted" +And eventually the order status should be "confirmed" +And eventually the reservation status should be "Stock Reserved" +And eventually the product "Reactive Widget" should show "48" units in stock +``` diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-004-cancel-a-submitted-order.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-004-cancel-a-submitted-order.sdp.md new file mode 100644 index 00000000..e93d0e78 --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-004-cancel-a-submitted-order.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.frontend.orders.order-detail.cancel-a-submitted-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# Cancel a submitted order + +## Intent + +- outcome: Show that confirming Cancel Order moves a submitted order to cancelled. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Cancel Widget" and I enter quantity 20 and I click "Add Stock" and I navigate to the create order page and I add "Cancel Widget" to the cart with quantity 1 and I submit the order and I click "Cancel Order" and I confirm the cancellation in the dialog +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And eventually the order status should be "cancelled" +And I should see the cancellation banner +``` diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-005-cancel-button-appears-only-for-cancellable-statuses.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-005-cancel-button-appears-only-for-cancellable-statuses.sdp.md new file mode 100644 index 00000000..189e7f1d --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-005-cancel-button-appears-only-for-cancellable-statuses.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.frontend.orders.order-detail.cancel-button-appears-only-for-cancellable-statuses +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# Cancel button appears only for cancellable statuses + +## Intent + +- outcome: Show that confirmed and cancelled orders hide the Cancel Order button. + +```gwt +Given a confirmed order exists +And a cancelled order exists +When I navigate to that order and I navigate to that order +Then I should see status "confirmed" +And I should not see the "Cancel Order" button +And I should see status "cancelled" +And I should not see the "Cancel Order" button +``` diff --git a/specs/behavior/frontend/orders/order-detail.examples/s-006-cancel-confirmation-dialog-prevents-accidental-cancellation.sdp.md b/specs/behavior/frontend/orders/order-detail.examples/s-006-cancel-confirmation-dialog-prevents-accidental-cancellation.sdp.md new file mode 100644 index 00000000..8979c0bf --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.examples/s-006-cancel-confirmation-dialog-prevents-accidental-cancellation.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.frontend.orders.order-detail.cancel-confirmation-dialog-prevents-accidental-cancellation +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.order-detail + verifies: spec:behavior.frontend.orders.order-detail +--- +# Cancel confirmation dialog prevents accidental cancellation + +## Intent + +- outcome: Show that dismissing the cancel dialog leaves the order confirmed. + +```gwt +Given I am on the admin products page +When I fill in product details: and I click "Create Product" and I switch to the "Add Stock" tab and I select the product "Dialog Widget" and I enter quantity 10 and I click "Add Stock" and I navigate to the create order page and I add "Dialog Widget" to the cart with quantity 1 and I submit the order and I click "Cancel Order" and I click "Keep Order" in the dialog +Then I should see a success message containing "created successfully" +And I should see a success message containing "Stock added" +And I should be redirected to the order detail page +And eventually the order status should be "confirmed" +And I should see a confirmation dialog +And the dialog should warn that cancellation cannot be undone +And the dialog should close +And the order status should still be "confirmed" +``` diff --git a/specs/behavior/frontend/orders/order-detail.sdp.md b/specs/behavior/frontend/orders/order-detail.sdp.md new file mode 100644 index 00000000..3113465e --- /dev/null +++ b/specs/behavior/frontend/orders/order-detail.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.frontend.orders.order-detail +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Order Detail + +## Intent + +- outcome: Show an order's status and allow cancellation only while the order is still cancellable. diff --git a/specs/behavior/frontend/orders/view-orders.examples/s-001-view-all-orders.sdp.md b/specs/behavior/frontend/orders/view-orders.examples/s-001-view-all-orders.sdp.md new file mode 100644 index 00000000..f43047a8 --- /dev/null +++ b/specs/behavior/frontend/orders/view-orders.examples/s-001-view-all-orders.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.orders.view-orders.view-all-orders +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.view-orders + verifies: spec:behavior.frontend.orders.view-orders +--- +# View all orders + +## Intent + +- outcome: Show that the orders page lists every order with its status badge. + +```gwt +Given orders exist with different statuses +When I navigate to the orders page +Then I should see all orders +And each order should show its status badge +``` diff --git a/specs/behavior/frontend/orders/view-orders.examples/s-002-navigate-to-create-order.sdp.md b/specs/behavior/frontend/orders/view-orders.examples/s-002-navigate-to-create-order.sdp.md new file mode 100644 index 00000000..e5ae6b04 --- /dev/null +++ b/specs/behavior/frontend/orders/view-orders.examples/s-002-navigate-to-create-order.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.frontend.orders.view-orders.navigate-to-create-order +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.orders.view-orders + verifies: spec:behavior.frontend.orders.view-orders +--- +# Navigate to create order + +## Intent + +- outcome: Show that New Order on the orders page opens the create-order page. + +```gwt +Given the feature fixture is in place +When I am on the orders page and I click "New Order" +Then I should be on the create order page +``` diff --git a/specs/behavior/frontend/orders/view-orders.sdp.md b/specs/behavior/frontend/orders/view-orders.sdp.md new file mode 100644 index 00000000..4f3bb954 --- /dev/null +++ b/specs/behavior/frontend/orders/view-orders.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.frontend.orders.view-orders +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# View Orders List + +## Intent + +- outcome: Show the orders list with a status badge for every order. diff --git a/specs/behavior/frontend/products/browse-products.examples/s-001-view-products-with-stock-levels.sdp.md b/specs/behavior/frontend/products/browse-products.examples/s-001-view-products-with-stock-levels.sdp.md new file mode 100644 index 00000000..b0cab5f4 --- /dev/null +++ b/specs/behavior/frontend/products/browse-products.examples/s-001-view-products-with-stock-levels.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.frontend.products.browse-products.view-products-with-stock-levels +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.products.browse-products + verifies: spec:behavior.frontend.products.browse-products +--- +# View products with stock levels + +## Intent + +- outcome: Show that the product catalog displays stock badges for in-stock, low-stock, and out-of-stock products. + +```gwt +Given products exist with various stock levels +When I navigate to the products page +Then I should see products with their stock badges +And in-stock products should show green badge +And low-stock products should show yellow badge +And out-of-stock products should show red badge +``` diff --git a/specs/behavior/frontend/products/browse-products.examples/s-002-loading-state.sdp.md b/specs/behavior/frontend/products/browse-products.examples/s-002-loading-state.sdp.md new file mode 100644 index 00000000..93da4f98 --- /dev/null +++ b/specs/behavior/frontend/products/browse-products.examples/s-002-loading-state.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.frontend.products.browse-products.loading-state +kind: example +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend.products.browse-products + verifies: spec:behavior.frontend.products.browse-products +--- +# Loading state + +## Intent + +- outcome: Show that the products page shows loading skeletons until the catalog appears. + +```gwt +Given the feature fixture is in place +When I navigate to the products page +Then I should see loading skeletons +And eventually products should appear +``` diff --git a/specs/behavior/frontend/products/browse-products.sdp.md b/specs/behavior/frontend/products/browse-products.sdp.md new file mode 100644 index 00000000..3e5bfd11 --- /dev/null +++ b/specs/behavior/frontend/products/browse-products.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.frontend.products.browse-products +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.frontend +--- +# Browse Product Catalog + +## Intent + +- outcome: Browse the product catalog so stock levels are visible before ordering. + +## Example space + +```gwt-vocabulary +Given products exist with various stock levels +And the feature fixture is in place +When I navigate to the products page +Then I should see products with their stock badges +And in-stock products should show green badge +And low-stock products should show yellow badge +And out-of-stock products should show red badge +And I should see loading skeletons +And eventually products should appear +``` diff --git a/specs/behavior/order-management/_epic.sdp.md b/specs/behavior/order-management/_epic.sdp.md new file mode 100644 index 00000000..00356ff1 --- /dev/null +++ b/specs/behavior/order-management/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:behavior.order-management +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# order-management executable behavior + +## Intent + +- outcome: The order-management example app holds the executable Gherkin behavior Specs migrated from its test corpus. diff --git a/specs/behavior/order-management/agent/on-complete.sdp.md b/specs/behavior/order-management/agent/on-complete.sdp.md new file mode 100644 index 00000000..96d4b41b --- /dev/null +++ b/specs/behavior/order-management/agent/on-complete.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.order-management.agent.on-complete +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Agent onComplete Handler + +## Intent + +- actor: a system operator +- outcome: Agent failures create dead letters for retry so that no events are silently lost during processing. + +## Behavior + +- rule: Successful and canceled results do not create dead letters +- rule: Failed results create dead letters with error details +- rule: Repeated failures increment attempt count +- rule: Terminal dead letters are not updated +- rule: Approvals expire after configured timeout +- rule: Emitted commands create real domain records diff --git a/specs/behavior/order-management/deciders/add-order-item-decider.sdp.md b/specs/behavior/order-management/deciders/add-order-item-decider.sdp.md new file mode 100644 index 00000000..904e5a7c --- /dev/null +++ b/specs/behavior/order-management/deciders/add-order-item-decider.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.add-order-item-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Add Order Item Decider + +## Intent + +- outcome: The AddOrderItem decider validates draft status and quantity, then emits OrderItemAdded. diff --git a/specs/behavior/order-management/deciders/add-stock-decider.sdp.md b/specs/behavior/order-management/deciders/add-stock-decider.sdp.md new file mode 100644 index 00000000..3bd16f0c --- /dev/null +++ b/specs/behavior/order-management/deciders/add-stock-decider.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.add-stock-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Add Stock Decider + +## Intent + +- outcome: The AddStock decider validates a positive quantity and emits StockAdded. diff --git a/specs/behavior/order-management/deciders/cancel-order-decider.sdp.md b/specs/behavior/order-management/deciders/cancel-order-decider.sdp.md new file mode 100644 index 00000000..e1a32952 --- /dev/null +++ b/specs/behavior/order-management/deciders/cancel-order-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.cancel-order-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Cancel Order Decider + +## Intent + +- outcome: The CancelOrder decider validates cancellable status and emits OrderCancelled. + +## Example space + +```gwt-vocabulary +Given a decider context +And an order state: +When I decide to cancel the order with reason {reason:string} +Then the decision should be "success" +And the event type should be "OrderCancelled" +And the state update should set status to "cancelled" +And the data should contain reason {reason:string} +And the decision should be "rejected" +And the rejection code should be "ORDER_ALREADY_CANCELLED" +``` diff --git a/specs/behavior/order-management/deciders/confirm-order-decider.sdp.md b/specs/behavior/order-management/deciders/confirm-order-decider.sdp.md new file mode 100644 index 00000000..4416be2a --- /dev/null +++ b/specs/behavior/order-management/deciders/confirm-order-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.confirm-order-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Confirm Order Decider + +## Intent + +- outcome: The ConfirmOrder decider validates submitted status and emits OrderConfirmed. + +## Example space + +```gwt-vocabulary +Given a decider context with timestamp 1704067200000 +And an order state: +When I decide to confirm the order +Then the decision should be "success" +And the event type should be "OrderConfirmed" +And the event payload should contain "confirmedAt" with value 1704067200000 +And the state update should set status to "confirmed" +And the decision should be "rejected" +And the rejection code should be "ORDER_NOT_SUBMITTED" +``` diff --git a/specs/behavior/order-management/deciders/confirm-reservation-decider.sdp.md b/specs/behavior/order-management/deciders/confirm-reservation-decider.sdp.md new file mode 100644 index 00000000..5b11d986 --- /dev/null +++ b/specs/behavior/order-management/deciders/confirm-reservation-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.confirm-reservation-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Confirm Reservation Decider + +## Intent + +- outcome: The ConfirmReservation decider validates pending unexpired status and emits ReservationConfirmed. + +## Example space + +```gwt-vocabulary +Given a decider context +And a reservation state: +When I decide to confirm the reservation +Then the decision should be "success" +And the event type should be "ReservationConfirmed" +And the state update should have status "confirmed" +And the decision should be "rejected" +And the rejection code should be "RESERVATION_NOT_PENDING" +And the rejection code should be "RESERVATION_EXPIRED" +``` diff --git a/specs/behavior/order-management/deciders/create-order-decider.sdp.md b/specs/behavior/order-management/deciders/create-order-decider.sdp.md new file mode 100644 index 00000000..611e0e8d --- /dev/null +++ b/specs/behavior/order-management/deciders/create-order-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.create-order-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Order Decider + +## Intent + +- outcome: The CreateOrder decider validates that no order with the same ID exists, then emits OrderCreated. + +## Example space + +```gwt-vocabulary +Given a decider context +And no existing order state +And an existing order state with orderId {orderId:string} +When I decide to create order with orderId {orderId:string} and customerId {customerId:string} +Then the decision should be "success" +And the event type should be "OrderCreated" +And the data should contain orderId {orderId:string} +And the decision should be "rejected" +And the rejection code should be "ORDER_ALREADY_EXISTS" +``` diff --git a/specs/behavior/order-management/deciders/create-product-decider.sdp.md b/specs/behavior/order-management/deciders/create-product-decider.sdp.md new file mode 100644 index 00000000..f131a80c --- /dev/null +++ b/specs/behavior/order-management/deciders/create-product-decider.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.order-management.deciders.create-product-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Product Decider + +## Intent + +- outcome: The CreateProduct decider validates uniqueness, name, SKU, and positive price, then emits ProductCreated. + +## Example space + +```gwt-vocabulary +Given a decider context +And no existing inventory state +And an existing inventory state with productId "prod_existing" +When I decide to create product with: +Then the decision should be "success" +And the event type should be "ProductCreated" +And the data should contain productId "prod_new_001" +And the decision should be "rejected" +And the rejection code should be "PRODUCT_ALREADY_EXISTS" +And the rejection code should be "INVALID_PRODUCT_NAME" +And the rejection code should be "INVALID_SKU" +And the rejection code should be "INVALID_UNIT_PRICE" +``` diff --git a/specs/behavior/order-management/deciders/expire-reservation-decider.sdp.md b/specs/behavior/order-management/deciders/expire-reservation-decider.sdp.md new file mode 100644 index 00000000..f2e573ef --- /dev/null +++ b/specs/behavior/order-management/deciders/expire-reservation-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.expire-reservation-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Expire Reservation Decider + +## Intent + +- outcome: The ExpireReservation decider validates pending status and elapsed TTL, then emits ReservationExpired. + +## Example space + +```gwt-vocabulary +Given a decider context +And a reservation state: +When I decide to expire the reservation +Then the decision should be "success" +And the event type should be "ReservationExpired" +And the state update should have status "expired" +And the decision should be "rejected" +And the rejection code should be "RESERVATION_NOT_EXPIRED" +And the rejection code should be "RESERVATION_NOT_PENDING" +``` diff --git a/specs/behavior/order-management/deciders/inventory-evolve.sdp.md b/specs/behavior/order-management/deciders/inventory-evolve.sdp.md new file mode 100644 index 00000000..fab7cdbc --- /dev/null +++ b/specs/behavior/order-management/deciders/inventory-evolve.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.inventory-evolve +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Inventory Evolve Functions + +## Intent + +- outcome: Evolve inventory state from domain events without side effects. diff --git a/specs/behavior/order-management/deciders/order-evolve.sdp.md b/specs/behavior/order-management/deciders/order-evolve.sdp.md new file mode 100644 index 00000000..bfb2fbf0 --- /dev/null +++ b/specs/behavior/order-management/deciders/order-evolve.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.order-evolve +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Order State Evolution + +## Intent + +- outcome: Evolve order state from domain events without side effects. diff --git a/specs/behavior/order-management/deciders/release-reservation-decider.sdp.md b/specs/behavior/order-management/deciders/release-reservation-decider.sdp.md new file mode 100644 index 00000000..84ccce15 --- /dev/null +++ b/specs/behavior/order-management/deciders/release-reservation-decider.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.deciders.release-reservation-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Release Reservation Decider + +## Intent + +- outcome: The ReleaseReservation decider validates pending or confirmed status and emits ReservationReleased. + +## Example space + +```gwt-vocabulary +Given a decider context +And a reservation state: +When I decide to release the reservation with reason {reason:string} +Then the decision should be "success" +And the event type should be "ReservationReleased" +And the event payload should have reason {reason:string} +And the state update should have status "released" +And the decision should be "rejected" +And the rejection code should be "RESERVATION_NOT_PENDING" +``` diff --git a/specs/behavior/order-management/deciders/remove-order-item-decider.sdp.md b/specs/behavior/order-management/deciders/remove-order-item-decider.sdp.md new file mode 100644 index 00000000..2171feb0 --- /dev/null +++ b/specs/behavior/order-management/deciders/remove-order-item-decider.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.order-management.deciders.remove-order-item-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Remove Order Item Decider + +## Intent + +- outcome: The RemoveOrderItem decider validates draft status and item presence, then emits OrderItemRemoved. + +## Example space + +```gwt-vocabulary +Given a decider context +And an order state with item: +And an order state: +When I decide to remove item with productId {productId:string} +Then the decision should be "success" +And the event type should be "OrderItemRemoved" +And the data should have itemCount 0 +And the data should have totalAmount "0.0" +And the decision should be "rejected" +And the rejection code should be "ORDER_NOT_IN_DRAFT" +And the rejection code should be "ITEM_NOT_FOUND" +``` diff --git a/specs/behavior/order-management/deciders/reservation-evolve.sdp.md b/specs/behavior/order-management/deciders/reservation-evolve.sdp.md new file mode 100644 index 00000000..cabd7924 --- /dev/null +++ b/specs/behavior/order-management/deciders/reservation-evolve.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.reservation-evolve +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reservation Evolve Functions + +## Intent + +- outcome: Evolve reservation state from domain events without side effects. diff --git a/specs/behavior/order-management/deciders/reserve-stock-decider.sdp.md b/specs/behavior/order-management/deciders/reserve-stock-decider.sdp.md new file mode 100644 index 00000000..344649ff --- /dev/null +++ b/specs/behavior/order-management/deciders/reserve-stock-decider.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.deciders.reserve-stock-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reserve Stock Decider + +## Intent + +- outcome: The ReserveStock decider validates product availability and emits StockReserved or ReservationFailed. diff --git a/specs/behavior/order-management/deciders/submit-order-decider.sdp.md b/specs/behavior/order-management/deciders/submit-order-decider.sdp.md new file mode 100644 index 00000000..b0360848 --- /dev/null +++ b/specs/behavior/order-management/deciders/submit-order-decider.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.order-management.deciders.submit-order-decider +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Submit Order Decider + +## Intent + +- outcome: The SubmitOrder decider validates draft status and item presence, then emits OrderSubmitted. + +## Example space + +```gwt-vocabulary +Given a decider context with timestamp 1704067200000 +And an order state: +When I decide to submit the order +Then the decision should be "success" +And the event type should be "OrderSubmitted" +And the event payload should contain "submittedAt" with value 1704067200000 +And the state update should set status to "submitted" +And the decision should be "rejected" +And the rejection code should be "ORDER_NOT_IN_DRAFT" +And the rejection code should be "ORDER_HAS_NO_ITEMS" +``` diff --git a/specs/behavior/order-management/inventory/add-stock.sdp.md b/specs/behavior/order-management/inventory/add-stock.sdp.md new file mode 100644 index 00000000..85d5517d --- /dev/null +++ b/specs/behavior/order-management/inventory/add-stock.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.inventory.add-stock +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Add Stock + +## Intent + +- actor: an inventory manager +- outcome: An inventory manager adds stock to existing products so that products are available for sale. diff --git a/specs/behavior/order-management/inventory/confirm-reservation.sdp.md b/specs/behavior/order-management/inventory/confirm-reservation.sdp.md new file mode 100644 index 00000000..05db2d8f --- /dev/null +++ b/specs/behavior/order-management/inventory/confirm-reservation.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.inventory.confirm-reservation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Confirm Reservation + +## Intent + +- outcome: Stock reservations are confirmed so that reserved stock is permanently allocated to orders. diff --git a/specs/behavior/order-management/inventory/create-product.sdp.md b/specs/behavior/order-management/inventory/create-product.sdp.md new file mode 100644 index 00000000..2264747c --- /dev/null +++ b/specs/behavior/order-management/inventory/create-product.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.inventory.create-product +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Product + +## Intent + +- actor: an inventory manager +- outcome: An inventory manager creates new products in the catalog so that they can be sold and tracked. diff --git a/specs/behavior/order-management/inventory/inventory-domain.sdp.md b/specs/behavior/order-management/inventory/inventory-domain.sdp.md new file mode 100644 index 00000000..f5e8b151 --- /dev/null +++ b/specs/behavior/order-management/inventory/inventory-domain.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.inventory.inventory-domain +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Inventory Domain Functions + +## Intent + +- actor: a developer working with the Inventory bounded context +- outcome: Pure domain functions calculate, initialize, and upcast inventory state reliably. + +## Behavior + +- rule: calculateTotalQuantity returns the sum of available and reserved quantities +- rule: createInitialInventoryCMS produces a correctly initialized CMS record +- rule: upcastInventoryCMS migrates older CMS versions to the current version +- rule: upcastInventoryCMS rejects future CMS versions diff --git a/specs/behavior/order-management/inventory/product-invariants.sdp.md b/specs/behavior/order-management/inventory/product-invariants.sdp.md new file mode 100644 index 00000000..a96b825b --- /dev/null +++ b/specs/behavior/order-management/inventory/product-invariants.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.order-management.inventory.product-invariants +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Product Invariants + +## Intent + +- actor: a developer working with the Inventory aggregate +- outcome: Pure invariant functions validate product state so that invalid transitions are prevented with structured errors. + +## Behavior + +- rule: assertProductExists validates that a product reference is not null or undefined +- rule: assertProductDoesNotExist validates that a product reference is null or undefined +- rule: assertValidSku validates that a SKU string is non-empty +- rule: assertValidProductName validates that a product name is non-empty +- rule: assertPositiveQuantity validates that a quantity is a positive integer diff --git a/specs/behavior/order-management/inventory/release-reservation.sdp.md b/specs/behavior/order-management/inventory/release-reservation.sdp.md new file mode 100644 index 00000000..5ad5d1d0 --- /dev/null +++ b/specs/behavior/order-management/inventory/release-reservation.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.inventory.release-reservation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Release Reservation + +## Intent + +- outcome: Stock reservations are released so that stock returns to available when orders are cancelled. diff --git a/specs/behavior/order-management/inventory/reservation-domain.sdp.md b/specs/behavior/order-management/inventory/reservation-domain.sdp.md new file mode 100644 index 00000000..590468ae --- /dev/null +++ b/specs/behavior/order-management/inventory/reservation-domain.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.order-management.inventory.reservation-domain +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reservation Domain Functions + +## Intent + +- actor: a developer working with the inventory context +- outcome: Pure reservation domain functions manage reservation CMS state reliably. + +## Behavior + +- rule: calculateReservationItemCount returns the number of line items +- rule: calculateTotalReservedQuantity sums all item quantities +- rule: createInitialReservationCMS produces a valid initial state +- rule: isReservationExpired checks pending reservations against current time +- rule: upcastReservationCMS migrates old CMS versions to current diff --git a/specs/behavior/order-management/inventory/reservation-invariants.sdp.md b/specs/behavior/order-management/inventory/reservation-invariants.sdp.md new file mode 100644 index 00000000..04ac64a1 --- /dev/null +++ b/specs/behavior/order-management/inventory/reservation-invariants.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.order-management.inventory.reservation-invariants +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reservation Invariants + +## Intent + +- actor: a developer working with the inventory context +- outcome: Reservation invariant functions enforce domain rules so that invalid reservation state is rejected consistently. + +## Behavior + +- rule: assertReservationExists throws when reservation is null or undefined +- rule: assertReservationDoesNotExist throws when reservation already exists +- rule: assertReservationHasItems throws when items array is empty +- rule: validateReservationItem validates individual item data via Zod schema +- rule: validateReservationItems validates the full items array +- rule: InventoryInvariantError carries structured error information +- rule: reservationIsPending validates that reservation status is pending +- rule: reservationNotExpired validates that a pending reservation has not passed its expiry +- rule: reservationHasExpired validates that a reservation has passed its expiry time +- rule: confirmReservationInvariants validates pending + not expired for confirmation +- rule: expireReservationInvariants validates pending + has expired for expiration processing diff --git a/specs/behavior/order-management/inventory/reserve-stock.sdp.md b/specs/behavior/order-management/inventory/reserve-stock.sdp.md new file mode 100644 index 00000000..7a4cc134 --- /dev/null +++ b/specs/behavior/order-management/inventory/reserve-stock.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.inventory.reserve-stock +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reserve Stock + +## Intent + +- outcome: Stock is reserved for orders so that it is held until the order is confirmed or cancelled. diff --git a/specs/behavior/order-management/inventory/stock-invariants.sdp.md b/specs/behavior/order-management/inventory/stock-invariants.sdp.md new file mode 100644 index 00000000..91351e8e --- /dev/null +++ b/specs/behavior/order-management/inventory/stock-invariants.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.order-management.inventory.stock-invariants +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Stock Invariants + +## Intent + +- actor: a developer working with the Inventory bounded context +- outcome: Pure stock invariant functions validate quantity constraints so that over-allocation is prevented with structured errors. + +## Behavior + +- rule: assertSufficientStock ensures requested quantity does not exceed available stock +- rule: checkStockAvailability returns availability status with optional deficit diff --git a/specs/behavior/order-management/modernization/dcb-multi-product-reservation.sdp.md b/specs/behavior/order-management/modernization/dcb-multi-product-reservation.sdp.md new file mode 100644 index 00000000..bfa34f3e --- /dev/null +++ b/specs/behavior/order-management/modernization/dcb-multi-product-reservation.sdp.md @@ -0,0 +1,18 @@ +--- +id: spec:behavior.order-management.modernization.dcb-multi-product-reservation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# DCB Multi-Product Reservation + +## Intent + +- actor: a platform developer +- outcome: Order submission demonstrates DCB so that developers can see how to use executeWithDCB for multi-entity operations. + +## Behavior + +- rule: Order submission uses DCB for atomic multi-product reservation diff --git a/specs/behavior/order-management/modernization/fat-events-order-submitted.sdp.md b/specs/behavior/order-management/modernization/fat-events-order-submitted.sdp.md new file mode 100644 index 00000000..7a5a1b4a --- /dev/null +++ b/specs/behavior/order-management/modernization/fat-events-order-submitted.sdp.md @@ -0,0 +1,18 @@ +--- +id: spec:behavior.order-management.modernization.fat-events-order-submitted +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Fat Events - Enriched OrderSubmitted + +## Intent + +- actor: an event consumer +- outcome: OrderSubmitted events include customer snapshots so that consumers can process orders without additional customer queries. + +## Behavior + +- rule: OrderSubmitted event includes customer snapshot diff --git a/specs/behavior/order-management/modernization/reactive-order-detail.sdp.md b/specs/behavior/order-management/modernization/reactive-order-detail.sdp.md new file mode 100644 index 00000000..ad4b6ed4 --- /dev/null +++ b/specs/behavior/order-management/modernization/reactive-order-detail.sdp.md @@ -0,0 +1,18 @@ +--- +id: spec:behavior.order-management.modernization.reactive-order-detail +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reactive Order Detail View + +## Intent + +- actor: a frontend developer +- outcome: Order detail demonstrates useReactiveProjection so that developers can build instant-updating UI components. + +## Behavior + +- rule: Order detail view uses reactive projection for instant updates diff --git a/specs/behavior/order-management/modernization/reference-documentation.sdp.md b/specs/behavior/order-management/modernization/reference-documentation.sdp.md new file mode 100644 index 00000000..f072d03e --- /dev/null +++ b/specs/behavior/order-management/modernization/reference-documentation.sdp.md @@ -0,0 +1,18 @@ +--- +id: spec:behavior.order-management.modernization.reference-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reference Implementation Documentation + +## Intent + +- actor: a platform user +- outcome: Documentation designates this app as a reference implementation so that users understand its purpose and how to learn from it. + +## Behavior + +- rule: README documents the app as a Reference Implementation diff --git a/specs/behavior/order-management/orders/add-items.sdp.md b/specs/behavior/order-management/orders/add-items.sdp.md new file mode 100644 index 00000000..7f4d9b6e --- /dev/null +++ b/specs/behavior/order-management/orders/add-items.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.orders.add-items +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Add Items to Order + +## Intent + +- actor: a customer +- outcome: A customer adds items to an order so that they can purchase multiple products. diff --git a/specs/behavior/order-management/orders/cancel-order.sdp.md b/specs/behavior/order-management/orders/cancel-order.sdp.md new file mode 100644 index 00000000..8e21e99e --- /dev/null +++ b/specs/behavior/order-management/orders/cancel-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.orders.cancel-order +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Cancel Order + +## Intent + +- actor: a customer +- outcome: A customer cancels an order so that they do not have to complete the purchase. diff --git a/specs/behavior/order-management/orders/confirm-order.sdp.md b/specs/behavior/order-management/orders/confirm-order.sdp.md new file mode 100644 index 00000000..85d10798 --- /dev/null +++ b/specs/behavior/order-management/orders/confirm-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.orders.confirm-order +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Confirm Order + +## Intent + +- actor: a system administrator +- outcome: A system administrator confirms submitted orders so that they can be marked as confirmed. diff --git a/specs/behavior/order-management/orders/create-order.sdp.md b/specs/behavior/order-management/orders/create-order.sdp.md new file mode 100644 index 00000000..c519db33 --- /dev/null +++ b/specs/behavior/order-management/orders/create-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.orders.create-order +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Order + +## Intent + +- actor: a customer +- outcome: A customer creates a new order so that they can add items and submit it later. diff --git a/specs/behavior/order-management/orders/order-domain.sdp.md b/specs/behavior/order-management/orders/order-domain.sdp.md new file mode 100644 index 00000000..9b5a052c --- /dev/null +++ b/specs/behavior/order-management/orders/order-domain.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.orders.order-domain +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Order Domain Functions + +## Intent + +- actor: a developer working with the Order aggregate +- outcome: Pure domain functions compute order totals, initialize CMS, and upcast state without side effects. + +## Behavior + +- rule: calculateTotalAmount computes the sum of quantity * unitPrice for all items +- rule: createInitialOrderCMS produces a draft order with correct defaults +- rule: upcastOrderCMS migrates older CMS versions to current version diff --git a/specs/behavior/order-management/orders/order-invariant-sets.sdp.md b/specs/behavior/order-management/orders/order-invariant-sets.sdp.md new file mode 100644 index 00000000..a51f05a2 --- /dev/null +++ b/specs/behavior/order-management/orders/order-invariant-sets.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.orders.order-invariant-sets +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Order Invariant Sets + +## Intent + +- actor: a developer working with composed invariant sets +- outcome: checkAll, assertAll, and validateAll enforce multiple invariants together so command handlers get fail-fast or collect-all validation. + +## Behavior + +- rule: orderSubmitInvariants composes orderIsDraft and orderHasItems for order submission +- rule: orderAddItemInvariants composes orderIsDraft and orderCanAddItem for adding items +- rule: orderCancelInvariants composes orderNotConfirmed and orderNotCancelled for cancellation diff --git a/specs/behavior/order-management/orders/order-invariants.sdp.md b/specs/behavior/order-management/orders/order-invariants.sdp.md new file mode 100644 index 00000000..10c02bb2 --- /dev/null +++ b/specs/behavior/order-management/orders/order-invariants.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.order-management.orders.order-invariants +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Order Invariants + +## Intent + +- actor: a developer working with the Order aggregate +- outcome: Pure invariant functions validate order state so that invalid transitions are prevented with structured errors. + +## Behavior + +- rule: assertOrderExists validates that an order reference is not null or undefined +- rule: assertOrderDoesNotExist validates that an order reference is null or undefined +- rule: orderIsDraft checks whether an order is in draft status +- rule: orderIsSubmitted checks whether an order is in submitted status +- rule: orderNotCancelled checks whether an order has not been cancelled +- rule: orderNotConfirmed checks whether an order has not been confirmed +- rule: orderHasItems checks whether an order contains at least one item +- rule: orderCanAddItem checks whether an order has room for more items +- rule: assertItemExists validates that a product exists in the order items +- rule: validateItem validates item data integrity +- rule: OrderInvariantError carries structured error information diff --git a/specs/behavior/order-management/orders/remove-order-item.sdp.md b/specs/behavior/order-management/orders/remove-order-item.sdp.md new file mode 100644 index 00000000..69b0809c --- /dev/null +++ b/specs/behavior/order-management/orders/remove-order-item.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.orders.remove-order-item +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Remove Items from Order + +## Intent + +- actor: a customer +- outcome: A customer removes items from an order so that they can adjust the purchase before submitting. diff --git a/specs/behavior/order-management/orders/submit-order.examples/s-001-successfully-submit-order-with-items.sdp.md b/specs/behavior/order-management/orders/submit-order.examples/s-001-successfully-submit-order-with-items.sdp.md new file mode 100644 index 00000000..9b343d91 --- /dev/null +++ b/specs/behavior/order-management/orders/submit-order.examples/s-001-successfully-submit-order-with-items.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.order-management.orders.submit-order.successfully-submit-order-with-items +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.orders.submit-order + refines: spec:behavior.order-management.orders.submit-order +--- +# Successfully submit order with items + +## Intent + +- outcome: Show that an order with items is submitted. + +```gwt +Given the system is ready +And an order {orderId: "ord_submit_001"} exists with status {status: "draft"} +And the order has the following items: +When I send a SubmitOrder command for {orderId: "ord_submit_001"} +Then the command should succeed +And the order {orderId: "ord_submit_001"} status should be {status: "submitted"} +And the order total should be {total: 45} +``` diff --git a/specs/behavior/order-management/orders/submit-order.examples/s-002-cannot-submit-empty-order.sdp.md b/specs/behavior/order-management/orders/submit-order.examples/s-002-cannot-submit-empty-order.sdp.md new file mode 100644 index 00000000..3396cddd --- /dev/null +++ b/specs/behavior/order-management/orders/submit-order.examples/s-002-cannot-submit-empty-order.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.order-management.orders.submit-order.cannot-submit-empty-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.orders.submit-order + refines: spec:behavior.order-management.orders.submit-order +--- +# Cannot submit empty order + +## Intent + +- outcome: Show that an empty order cannot be submitted. + +```gwt +Given the system is ready +And an order {orderId: "ord_empty_001"} exists with status {status: "draft"} +And the order has no items +When I send a SubmitOrder command for {orderId: "ord_empty_001"} +Then the command should be rejected with code {rejectionCode: "ORDER_HAS_NO_ITEMS"} +And the order {orderId: "ord_empty_001"} status should remain {status: "draft"} +``` diff --git a/specs/behavior/order-management/orders/submit-order.sdp.md b/specs/behavior/order-management/orders/submit-order.sdp.md new file mode 100644 index 00000000..f4380607 --- /dev/null +++ b/specs/behavior/order-management/orders/submit-order.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.order-management.orders.submit-order +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Submit Order + +## Intent + +- actor: a customer +- outcome: A customer submits an order so that it can be processed for fulfillment. + +## Example space + +```gwt-vocabulary +Given the system is ready +And an order {orderId:string} exists with status {status:string} +And the order has the following items: +And the order has no items +When I send a SubmitOrder command for {orderId:string} +Then the command should succeed +And the order {orderId:string} status should be {status:string} +And the order total should be {total:number} +And the command should be rejected with code {rejectionCode:string} +And the order {orderId:string} status should remain {status:string} +``` diff --git a/specs/behavior/order-management/roadmap/projection-categories.sdp.md b/specs/behavior/order-management/roadmap/projection-categories.sdp.md new file mode 100644 index 00000000..cae34235 --- /dev/null +++ b/specs/behavior/order-management/roadmap/projection-categories.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.roadmap.projection-categories +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Projection Categories + +## Intent + +- outcome: Formalize projection taxonomy with explicit Logic, View, Reporting, and Integration categories. diff --git a/specs/behavior/order-management/sagas/admin.sdp.md b/specs/behavior/order-management/sagas/admin.sdp.md new file mode 100644 index 00000000..25d44622 --- /dev/null +++ b/specs/behavior/order-management/sagas/admin.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.order-management.sagas.admin +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Saga Admin Operations + +## Intent + +- actor: a system administrator +- outcome: A system administrator queries and manages saga instances so they can monitor and recover from saga failures. + +## Behavior + +- rule: getSagaStats returns status counts for a saga type +- rule: getStuckSagas returns running sagas older than a threshold +- rule: getFailedSagas returns only failed sagas of a given type +- rule: markSagaFailed validates state transitions before marking a saga as failed +- rule: markSagaCompensated validates state transitions before marking a saga as compensated +- rule: retrySaga validates state transitions before retrying a saga diff --git a/specs/behavior/order-management/testing-infrastructure/data-table-parsing.sdp.md b/specs/behavior/order-management/testing-infrastructure/data-table-parsing.sdp.md new file mode 100644 index 00000000..bf2d72e3 --- /dev/null +++ b/specs/behavior/order-management/testing-infrastructure/data-table-parsing.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.testing-infrastructure.data-table-parsing +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Gherkin DataTable Parsing Utilities + +## Intent + +- actor: a BDD test author +- outcome: DataTable parsing helpers extract structured data from Gherkin tables. diff --git a/specs/behavior/order-management/testing-infrastructure/decider-assertions.sdp.md b/specs/behavior/order-management/testing-infrastructure/decider-assertions.sdp.md new file mode 100644 index 00000000..b7fb9368 --- /dev/null +++ b/specs/behavior/order-management/testing-infrastructure/decider-assertions.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.testing-infrastructure.decider-assertions +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Decider Testing Assertions + +## Intent + +- actor: a developer testing deciders +- outcome: Assertion helpers for DeciderOutput results support clear, consistent test assertions. diff --git a/specs/behavior/order-management/testing-infrastructure/fsm-assertions.sdp.md b/specs/behavior/order-management/testing-infrastructure/fsm-assertions.sdp.md new file mode 100644 index 00000000..e756b913 --- /dev/null +++ b/specs/behavior/order-management/testing-infrastructure/fsm-assertions.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.testing-infrastructure.fsm-assertions +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# FSM Testing Assertions + +## Intent + +- actor: a developer testing finite state machines +- outcome: FSM-specific assertion helpers verify transition validity concisely. diff --git a/specs/behavior/order-management/testing-infrastructure/test-isolation.sdp.md b/specs/behavior/order-management/testing-infrastructure/test-isolation.sdp.md new file mode 100644 index 00000000..43d2fdc2 --- /dev/null +++ b/specs/behavior/order-management/testing-infrastructure/test-isolation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.testing-infrastructure.test-isolation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Test Isolation via Namespace Prefixing + +## Intent + +- actor: a test author +- outcome: Automatic namespace isolation for test data keeps tests from interfering with each other. diff --git a/specs/behavior/order-management/tests/integration-features/durability/durable-commands.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/durable-commands.sdp.md new file mode 100644 index 00000000..b6b3a9cf --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/durable-commands.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.durable-commands +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Durable Command Execution (App Integration) + +## Intent + +- actor: a developer using event sourcing +- outcome: Commands are tracked with intent and completion bracketing so that crashed or hung commands can be detected and recovered. + +## Behavior + +- rule: Intent is recorded before command execution +- rule: Failed commands are tracked +- rule: Intent stats are queryable diff --git a/specs/behavior/order-management/tests/integration-features/durability/durable-publication.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/durable-publication.sdp.md new file mode 100644 index 00000000..72fa2eb9 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/durable-publication.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.durable-publication +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Durable Cross-Context Event Publication + +## Intent + +- outcome: Cross-context events are published durably so each target context can be tracked independently. diff --git a/specs/behavior/order-management/tests/integration-features/durability/event-replay.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/event-replay.sdp.md new file mode 100644 index 00000000..4953d5d7 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/event-replay.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.event-replay +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Event Replay Infrastructure (App Integration) + +## Intent + +- actor: a developer maintaining projections +- outcome: Projections are rebuilt from event history so that operators can recover from bugs or add new projections. + +## Behavior + +- rule: Checkpoints track replay progress +- rule: Concurrent replays are prevented +- rule: Replay status can be queried diff --git a/specs/behavior/order-management/tests/integration-features/durability/idempotent-append.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/idempotent-append.sdp.md new file mode 100644 index 00000000..f8e0ba4d --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/idempotent-append.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.idempotent-append +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Idempotent Event Append + +## Intent + +- outcome: Event append is idempotent so duplicate writes do not create duplicate events. diff --git a/specs/behavior/order-management/tests/integration-features/durability/orphan-detection.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/orphan-detection.sdp.md new file mode 100644 index 00000000..0a9f4380 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/orphan-detection.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.orphan-detection +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Orphan Intent Detection (App Integration) + +## Intent + +- actor: a developer using event sourcing +- outcome: Orphaned intents are detected and flagged so that stuck commands can be investigated and recovered. + +## Behavior + +- rule: Pending intents exceeding timeout are detected +- rule: Completed intents are never flagged +- rule: Abandoned intents are queryable +- rule: Scheduled timeout handler marks orphan diff --git a/specs/behavior/order-management/tests/integration-features/durability/poison-event.sdp.md b/specs/behavior/order-management/tests/integration-features/durability/poison-event.sdp.md new file mode 100644 index 00000000..0d2e9ae9 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durability/poison-event.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durability.poison-event +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Poison Event Handling + +## Intent + +- outcome: Events that repeatedly fail processing are quarantined so projections can continue. diff --git a/specs/behavior/order-management/tests/integration-features/durable-adapters/dcb-retry.sdp.md b/specs/behavior/order-management/tests/integration-features/durable-adapters/dcb-retry.sdp.md new file mode 100644 index 00000000..eac3f256 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durable-adapters/dcb-retry.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durable-adapters.dcb-retry +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# DCB Retry Adapter (App Integration) + +## Intent + +- actor: a developer using the order-management app +- outcome: DCB operations automatically retry on OCC conflicts so concurrent modifications are handled without manual retry logic. + +## Behavior + +- rule: DCB operations succeed without retry when no conflict +- rule: OCC conflicts return retry scheduling metadata +- rule: Backoff uses exponential increase with jitter +- rule: Scope-aware scheduling metadata stays stable across retries diff --git a/specs/behavior/order-management/tests/integration-features/durable-adapters/rate-limiting.sdp.md b/specs/behavior/order-management/tests/integration-features/durable-adapters/rate-limiting.sdp.md new file mode 100644 index 00000000..5b634bae --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/durable-adapters/rate-limiting.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.tests.integration-features.durable-adapters.rate-limiting +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Rate Limiting - API Protection + +## Intent + +- actor: a platform developer +- outcome: Commands and admin operations are rate limited so that the system is protected from abuse and overload. + +## Behavior + +- rule: Rate limiting protects command dispatch +- rule: Admin operations have separate rate limits +- rule: Rate limiter adapter integrates with middleware diff --git a/specs/behavior/order-management/tests/integration-features/inventory/add-stock.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/add-stock.sdp.md new file mode 100644 index 00000000..45bf8e33 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/add-stock.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.add-stock +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Add Stock (Integration) + +## Intent + +- actor: an inventory manager +- outcome: Stock is added to existing products so that products are available for sale. diff --git a/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-001-confirm-pending-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-001-confirm-pending-reservation.sdp.md new file mode 100644 index 00000000..4ccbcf2b --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-001-confirm-pending-reservation.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation.confirm-pending-reservation +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation + refines: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation +--- +# Confirm pending reservation + +## Intent + +- outcome: Show that a pending reservation is confirmed. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-conf-int-01"} exists with {stock: 20} available stock +And a pending reservation {reservationId: "res-conf-int-01"} exists for order {orderId: "ord-conf-int-01"} with: +When I confirm the reservation {reservationId: "res-conf-int-01"} +Then the command should succeed +And I wait for projections to process +And the reservation {reservationId: "res-conf-int-01"} should have status {status: "confirmed"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-002-reject-confirming-already-confirmed-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-002-reject-confirming-already-confirmed-reservation.sdp.md new file mode 100644 index 00000000..a5f375de --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-002-reject-confirming-already-confirmed-reservation.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation.reject-confirming-already-confirmed-reservation +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation + refines: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation +--- +# Reject confirming already confirmed reservation + +## Intent + +- outcome: Show that confirming an already confirmed reservation is rejected. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-conf-int-02"} exists with {stock: 20} available stock +And a confirmed reservation {reservationId: "res-conf-int-02"} exists for order {orderId: "ord-conf-int-02"} with: +When I confirm the reservation {reservationId: "res-conf-int-02"} +Then the command should be rejected with code {rejectionCode: "RESERVATION_NOT_PENDING"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-003-reject-confirming-non-existent-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-003-reject-confirming-non-existent-reservation.sdp.md new file mode 100644 index 00000000..b63de9e2 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.examples/s-003-reject-confirming-non-existent-reservation.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation.reject-confirming-non-existent-reservation +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation + refines: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation +--- +# Reject confirming non-existent reservation + +## Intent + +- outcome: Show that confirming a non-existent reservation is rejected. + +```gwt +Given the backend is running and clean +When I confirm the reservation {reservationId: "res-nonexistent-01"} +Then the command should be rejected with code {rejectionCode: "RESERVATION_NOT_FOUND"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.sdp.md new file mode 100644 index 00000000..adc02df0 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/confirm-reservation.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.confirm-reservation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Confirm Reservation (Integration) + +## Intent + +- outcome: A pending reservation is confirmed so that reserved stock becomes committed to the order. + +## Example space + +```gwt-vocabulary +Given the backend is running and clean +And a product {productId:string} exists with {stock:number} available stock +And a pending reservation {reservationId:string} exists for order {orderId:string} with: +And a confirmed reservation {reservationId:string} exists for order {orderId:string} with: +When I confirm the reservation {reservationId:string} +Then the command should succeed +And I wait for projections to process +And the reservation {reservationId:string} should have status {status:string} +And the command should be rejected with code {rejectionCode:string} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/create-product.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/create-product.sdp.md new file mode 100644 index 00000000..44a5fa46 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/create-product.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.create-product +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Product (Integration) + +## Intent + +- actor: an inventory manager +- outcome: New products are created in the catalog so that they can be sold and tracked. diff --git a/specs/behavior/order-management/tests/integration-features/inventory/query-inventory.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/query-inventory.sdp.md new file mode 100644 index 00000000..fb451050 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/query-inventory.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.query-inventory +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Query Inventory (Integration) + +## Intent + +- actor: a user +- outcome: Inventory information can be queried so that users can view product availability and reservations. diff --git a/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-001-release-pending-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-001-release-pending-reservation.sdp.md new file mode 100644 index 00000000..3b9595f0 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-001-release-pending-reservation.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.release-reservation.release-pending-reservation +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.inventory.release-reservation + refines: spec:behavior.order-management.tests.integration-features.inventory.release-reservation +--- +# Release pending reservation + +## Intent + +- outcome: Show that a pending reservation is released. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-rel-int-01"} exists with {stock: 20} available stock +And a pending reservation {reservationId: "res-rel-int-01"} exists for order {orderId: "ord-rel-int-01"} with: +When I release the reservation {reservationId: "res-rel-int-01"} with reason {reason: "Order cancelled"} +Then the command should succeed +And I wait for projections to process +And the reservation {reservationId: "res-rel-int-01"} should have status {status: "released"} +And the product {productId: "prod-rel-int-01"} should have {available: 20} available and {reserved: 0} reserved stock +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-002-reject-releasing-non-pending-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-002-reject-releasing-non-pending-reservation.sdp.md new file mode 100644 index 00000000..95222334 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.examples/s-002-reject-releasing-non-pending-reservation.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.release-reservation.reject-releasing-non-pending-reservation +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.inventory.release-reservation + refines: spec:behavior.order-management.tests.integration-features.inventory.release-reservation +--- +# Reject releasing non-pending reservation + +## Intent + +- outcome: Show that releasing a non-pending reservation is rejected. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-rel-int-02"} exists with {stock: 20} available stock +And a confirmed reservation {reservationId: "res-rel-int-02"} exists for order {orderId: "ord-rel-int-02"} with: +When I release the reservation {reservationId: "res-rel-int-02"} with reason {reason: "Testing"} +Then the command should be rejected with code {rejectionCode: "RESERVATION_NOT_PENDING"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.sdp.md new file mode 100644 index 00000000..0dbd6ee1 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/release-reservation.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.release-reservation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Release Reservation (Integration) + +## Intent + +- outcome: Stock reservations are released so that reserved stock becomes available again when orders are cancelled. + +## Example space + +```gwt-vocabulary +Given the backend is running and clean +And a product {productId:string} exists with {stock:number} available stock +And a pending reservation {reservationId:string} exists for order {orderId:string} with: +And a confirmed reservation {reservationId:string} exists for order {orderId:string} with: +When I release the reservation {reservationId:string} with reason {reason:string} +Then the command should succeed +And I wait for projections to process +And the reservation {reservationId:string} should have status {status:string} +And the product {productId:string} should have {available:number} available and {reserved:number} reserved stock +And the command should be rejected with code {rejectionCode:string} +``` diff --git a/specs/behavior/order-management/tests/integration-features/inventory/reservation-expiration.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/reservation-expiration.sdp.md new file mode 100644 index 00000000..e804f473 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/reservation-expiration.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.reservation-expiration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reservation Expiration (Integration) + +## Intent + +- outcome: Expired reservations are automatically released so that reserved stock becomes available again when orders are not completed in time. diff --git a/specs/behavior/order-management/tests/integration-features/inventory/reserve-stock.sdp.md b/specs/behavior/order-management/tests/integration-features/inventory/reserve-stock.sdp.md new file mode 100644 index 00000000..2c958234 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/inventory/reserve-stock.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.tests.integration-features.inventory.reserve-stock +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reserve Stock (Integration) + +## Intent + +- outcome: Stock is reserved for orders so that it is held until the order is confirmed or cancelled. diff --git a/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-001-add-item-to-draft-order-and-verify-projection.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-001-add-item-to-draft-order-and-verify-projection.sdp.md new file mode 100644 index 00000000..fb5c4746 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-001-add-item-to-draft-order-and-verify-projection.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.add-order-item.add-item-to-draft-order-and-verify-projection +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.orders.add-order-item + refines: spec:behavior.order-management.tests.integration-features.orders.add-order-item +--- +# Add item to draft order and verify projection + +## Intent + +- outcome: Show that adding an item to a draft order updates the projection. + +```gwt +Given the backend is running and clean +And an order {orderId: "ord-add-item-01"} exists in draft status +When I add an item to order {orderId: "ord-add-item-01"}: +Then the command should succeed +And I wait for projections to process +And the order {orderId: "ord-add-item-01"} should have {itemCount: 1} items +And the order {orderId: "ord-add-item-01"} total should be {total: 30} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-002-reject-adding-item-to-submitted-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-002-reject-adding-item-to-submitted-order.sdp.md new file mode 100644 index 00000000..dcc48008 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.examples/s-002-reject-adding-item-to-submitted-order.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.add-order-item.reject-adding-item-to-submitted-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.orders.add-order-item + refines: spec:behavior.order-management.tests.integration-features.orders.add-order-item +--- +# Reject adding item to submitted order + +## Intent + +- outcome: Show that adding an item to a submitted order is rejected. + +```gwt +Given the backend is running and clean +And a submitted order {orderId: "ord-add-item-02"} exists with items: +When I add an item to order {orderId: "ord-add-item-02"}: +Then the command should be rejected with code {rejectionCode: "ORDER_NOT_IN_DRAFT"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/add-order-item.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.sdp.md new file mode 100644 index 00000000..552fc7ff --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/add-order-item.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.add-order-item +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Add Order Item (Integration) + +## Intent + +- actor: a customer +- outcome: A customer adds items to an order so that they can purchase multiple products. + +## Example space + +```gwt-vocabulary +Given the backend is running and clean +And an order {orderId:string} exists in draft status +And a submitted order {orderId:string} exists with items: +When I add an item to order {orderId:string}: +Then the command should succeed +And I wait for projections to process +And the order {orderId:string} should have {itemCount:number} items +And the order {orderId:string} total should be {total:number} +And the command should be rejected with code {rejectionCode:string} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/batch-operations.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/batch-operations.sdp.md new file mode 100644 index 00000000..f7cc8598 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/batch-operations.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.batch-operations +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Order Batch Operations (Integration) + +## Intent + +- actor: an order operator +- outcome: Multiple items can be added or removed from an order in a single batch so that order contents can be managed efficiently. diff --git a/specs/behavior/order-management/tests/integration-features/orders/cancel-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/cancel-order.sdp.md new file mode 100644 index 00000000..98659227 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/cancel-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.cancel-order +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Cancel Order (Integration) + +## Intent + +- actor: a customer +- outcome: A customer cancels an order so that they do not have to complete the purchase. diff --git a/specs/behavior/order-management/tests/integration-features/orders/create-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/create-order.sdp.md new file mode 100644 index 00000000..00f20125 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/create-order.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.create-order +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Create Order (Integration) + +## Intent + +- actor: a customer +- outcome: A customer creates new orders so that they can purchase products. diff --git a/specs/behavior/order-management/tests/integration-features/orders/query-orders.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/query-orders.sdp.md new file mode 100644 index 00000000..662f9993 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/query-orders.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.query-orders +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Query Orders (Integration) + +## Intent + +- actor: a user +- outcome: Orders can be queried by various criteria so that users can find and view order information. diff --git a/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-001-submit-order-with-items-and-verify-projection.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-001-submit-order-with-items-and-verify-projection.sdp.md new file mode 100644 index 00000000..75b992d8 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-001-submit-order-with-items-and-verify-projection.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.submit-order.submit-order-with-items-and-verify-projection +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.orders.submit-order + refines: spec:behavior.order-management.tests.integration-features.orders.submit-order +--- +# Submit order with items and verify projection + +## Intent + +- outcome: Show that submitting an order with items updates the projection. + +```gwt +Given the backend is running and clean +And a draft order {orderId: "ord-submit-01"} exists with items: +When I submit order {orderId: "ord-submit-01"} +Then the command should succeed +And I wait for projections to process +And the order {orderId: "ord-submit-01"} should exist with status {status: "submitted"} +And the order {orderId: "ord-submit-01"} total should be {total: 45} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-002-reject-submitting-empty-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-002-reject-submitting-empty-order.sdp.md new file mode 100644 index 00000000..ec68ba85 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-002-reject-submitting-empty-order.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.submit-order.reject-submitting-empty-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.orders.submit-order + refines: spec:behavior.order-management.tests.integration-features.orders.submit-order +--- +# Reject submitting empty order + +## Intent + +- outcome: Show that submitting an empty order is rejected. + +```gwt +Given the backend is running and clean +And an empty draft order {orderId: "ord-submit-02"} exists +When I submit order {orderId: "ord-submit-02"} +Then the command should be rejected with code {rejectionCode: "ORDER_HAS_NO_ITEMS"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-003-reject-submitting-already-submitted-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-003-reject-submitting-already-submitted-order.sdp.md new file mode 100644 index 00000000..3567d8da --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/submit-order.examples/s-003-reject-submitting-already-submitted-order.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.submit-order.reject-submitting-already-submitted-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.orders.submit-order + refines: spec:behavior.order-management.tests.integration-features.orders.submit-order +--- +# Reject submitting already submitted order + +## Intent + +- outcome: Show that submitting an already submitted order is rejected. + +```gwt +Given the backend is running and clean +And a submitted order {orderId: "ord-submit-03"} exists with items: +When I submit order {orderId: "ord-submit-03"} +Then the command should be rejected with code {rejectionCode: "ORDER_NOT_IN_DRAFT"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/orders/submit-order.sdp.md b/specs/behavior/order-management/tests/integration-features/orders/submit-order.sdp.md new file mode 100644 index 00000000..5a42a33b --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/orders/submit-order.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.order-management.tests.integration-features.orders.submit-order +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Submit Order (Integration) + +## Intent + +- actor: a customer +- outcome: A customer submits an order so that it can be processed for fulfillment. + +## Example space + +```gwt-vocabulary +Given the backend is running and clean +And a draft order {orderId:string} exists with items: +And an empty draft order {orderId:string} exists +And a submitted order {orderId:string} exists with items: +When I submit order {orderId:string} +Then the command should succeed +And I wait for projections to process +And the order {orderId:string} should exist with status {status:string} +And the order {orderId:string} total should be {total:number} +And the command should be rejected with code {rejectionCode:string} +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-001-complete-saga-when-stock-is-available-for-single-item-order.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-001-complete-saga-when-stock-is-available-for-single-item-order.sdp.md new file mode 100644 index 00000000..4584e0bf --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-001-complete-saga-when-stock-is-available-for-single-item-order.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.complete-saga-when-stock-is-available-for-single-item-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Complete saga when stock is available for single item order + +## Intent + +- outcome: Show that the saga completes when stock is available for a single-item order. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-01"} exists with {stock: 100} available stock +And a draft order {orderId: "order-saga-01"} exists with items: +When I submit order {orderId: "order-saga-01"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the order {orderId: "order-saga-01"} should have status {status: "confirmed"} +And the reservation for order {orderId: "order-saga-01"} should have status {status: "confirmed"} +And the product {productId: "prod-saga-01"} should have less than {stock: 100} available stock +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-002-complete-saga-when-stock-is-available-for-multi-item-order.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-002-complete-saga-when-stock-is-available-for-multi-item-order.sdp.md new file mode 100644 index 00000000..8c9e3850 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-002-complete-saga-when-stock-is-available-for-multi-item-order.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.complete-saga-when-stock-is-available-for-multi-item-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Complete saga when stock is available for multi-item order + +## Intent + +- outcome: Show that the saga completes when stock is available for a multi-item order. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-02a"} exists with {stock: 50} available stock +And a product {productId: "prod-saga-02b"} exists with {stock: 30} available stock +And a draft order {orderId: "order-saga-02"} exists with items: +When I submit order {orderId: "order-saga-02"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the order {orderId: "order-saga-02"} should have status {status: "confirmed"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-003-cancel-order-when-insufficient-stock-for-single-item.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-003-cancel-order-when-insufficient-stock-for-single-item.sdp.md new file mode 100644 index 00000000..7a54eaa4 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-003-cancel-order-when-insufficient-stock-for-single-item.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.cancel-order-when-insufficient-stock-for-single-item +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Cancel order when insufficient stock for single item + +## Intent + +- outcome: Show that the order is cancelled when stock is insufficient for a single item. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-03"} exists with {stock: 3} available stock +And a draft order {orderId: "order-saga-03"} exists with items: +When I submit order {orderId: "order-saga-03"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the order {orderId: "order-saga-03"} should have status {status: "cancelled"} +And the product {productId: "prod-saga-03"} should have {available: 3} available and {reserved: 0} reserved stock +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-004-cancel-order-when-one-item-in-multi-item-order-has-insufficient-stock.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-004-cancel-order-when-one-item-in-multi-item-order-has-insufficient-stock.sdp.md new file mode 100644 index 00000000..09845a6b --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-004-cancel-order-when-one-item-in-multi-item-order-has-insufficient-stock.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.cancel-order-when-one-item-in-multi-item-order-has-insufficient-stock +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Cancel order when one item in multi-item order has insufficient stock + +## Intent + +- outcome: Show that the order is cancelled when one item in a multi-item order has insufficient stock. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-04a"} exists with {stock: 100} available stock +And a product {productId: "prod-saga-04b"} exists with {stock: 2} available stock +And a draft order {orderId: "order-saga-04"} exists with items: +When I submit order {orderId: "order-saga-04"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the order {orderId: "order-saga-04"} should have status {status: "cancelled"} +And the product {productId: "prod-saga-04a"} should have {available: 100} available and {reserved: 0} reserved stock +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-005-saga-runs-only-once-per-order.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-005-saga-runs-only-once-per-order.sdp.md new file mode 100644 index 00000000..3d5fdfcc --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-005-saga-runs-only-once-per-order.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.saga-runs-only-once-per-order +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Saga runs only once per order + +## Intent + +- outcome: Show that the saga runs only once per order. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-05"} exists with {stock: 100} available stock +And a draft order {orderId: "order-saga-05"} exists with items: +When I submit order {orderId: "order-saga-05"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And only one saga should exist for order {orderId: "order-saga-05"} +And the reservation for order {orderId: "order-saga-05"} should have status {status: "confirmed"} +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-008-saga-has-completed-at-timestamp-after-completion.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-008-saga-has-completed-at-timestamp-after-completion.sdp.md new file mode 100644 index 00000000..6cf73dd2 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.examples/s-008-saga-has-completed-at-timestamp-after-completion.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment.saga-has-completed-at-timestamp-after-completion +kind: example +altitude: story +readiness: defined +relations: + verifies: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment + refines: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +--- +# Saga has completedAt timestamp after completion + +## Intent + +- outcome: Show that the saga has a completedAt timestamp after completion. + +```gwt +Given the backend is running and clean +And a product {productId: "prod-saga-08"} exists with {stock: 100} available stock +And a draft order {orderId: "order-saga-08"} exists with items: +When I submit order {orderId: "order-saga-08"} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the saga should have a completedAt timestamp +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.sdp.md new file mode 100644 index 00000000..76e1d56f --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/order-fulfillment.sdp.md @@ -0,0 +1,33 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.order-fulfillment +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.order-management +--- +# Order Fulfillment Saga (Integration) + +## Intent + +- actor: an order management system +- outcome: The system coordinates order fulfillment across bounded contexts so that orders are confirmed when stock is available and cancelled when not. + +## Example space + +```gwt-vocabulary +Given the backend is running and clean +And a product {productId:string} exists with {stock:number} available stock +And a draft order {orderId:string} exists with items: +When I submit order {orderId:string} +Then the command should succeed +And I wait for the saga to complete with timeout 60000 +And the saga status should be "completed" +And the order {orderId:string} should have status {status:string} +And the reservation for order {orderId:string} should have status {status:string} +And the product {productId:string} should have less than {stock:number} available stock +And the product {productId:string} should have {available:number} available and {reserved:number} reserved stock +And only one saga should exist for order {orderId:string} +And the saga should have a workflow ID +And the saga should have a completedAt timestamp +``` diff --git a/specs/behavior/order-management/tests/integration-features/sagas/saga-admin.sdp.md b/specs/behavior/order-management/tests/integration-features/sagas/saga-admin.sdp.md new file mode 100644 index 00000000..1ac64407 --- /dev/null +++ b/specs/behavior/order-management/tests/integration-features/sagas/saga-admin.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.order-management.tests.integration-features.sagas.saga-admin +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Saga Admin Operations (Integration) + +## Intent + +- actor: a system administrator +- outcome: Administrators manage and monitor sagas so they can troubleshoot and maintain saga workflows. diff --git a/specs/behavior/order-management/timeline/phase-00-initialization.sdp.md b/specs/behavior/order-management/timeline/phase-00-initialization.sdp.md new file mode 100644 index 00000000..29eef98f --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-00-initialization.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-00-initialization +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Project Initialization + +## Intent + +- outcome: Set up repository structure and development tooling. diff --git a/specs/behavior/order-management/timeline/phase-01-core-infrastructure.sdp.md b/specs/behavior/order-management/timeline/phase-01-core-infrastructure.sdp.md new file mode 100644 index 00000000..01221f6d --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-01-core-infrastructure.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-01-core-infrastructure +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Core Infrastructure + +## Intent + +- outcome: Build shared types, schemas, and utilities for the event sourcing platform. diff --git a/specs/behavior/order-management/timeline/phase-02-event-store-orchestration.sdp.md b/specs/behavior/order-management/timeline/phase-02-event-store-orchestration.sdp.md new file mode 100644 index 00000000..7ac72919 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-02-event-store-orchestration.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-02-event-store-orchestration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Event Store and Orchestration Infrastructure + +## Intent + +- outcome: Provide centralized event storage with orchestration infrastructure for reliable projections. diff --git a/specs/behavior/order-management/timeline/phase-03-command-bus.sdp.md b/specs/behavior/order-management/timeline/phase-03-command-bus.sdp.md new file mode 100644 index 00000000..6834ac42 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-03-command-bus.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-03-command-bus +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Command Bus Component + +## Intent + +- outcome: Provide centralized command routing with middleware and idempotency. diff --git a/specs/behavior/order-management/timeline/phase-04-orders-bc.sdp.md b/specs/behavior/order-management/timeline/phase-04-orders-bc.sdp.md new file mode 100644 index 00000000..f89c6770 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-04-orders-bc.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-04-orders-bc +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Orders Bounded Context + +## Intent + +- outcome: Deliver a complete Orders bounded context demonstrating DDD, event sourcing, and CQRS patterns. diff --git a/specs/behavior/order-management/timeline/phase-05-inventory-bc.sdp.md b/specs/behavior/order-management/timeline/phase-05-inventory-bc.sdp.md new file mode 100644 index 00000000..11c68b4b --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-05-inventory-bc.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-05-inventory-bc +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Inventory Bounded Context + +## Intent + +- outcome: Deliver multi-aggregate inventory management with stock tracking and reservations. diff --git a/specs/behavior/order-management/timeline/phase-06-cross-context-integration.sdp.md b/specs/behavior/order-management/timeline/phase-06-cross-context-integration.sdp.md new file mode 100644 index 00000000..d15836eb --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-06-cross-context-integration.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-06-cross-context-integration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Cross-Context Integration + +## Intent + +- outcome: Coordinate Orders and Inventory bounded contexts through saga-based workflows. diff --git a/specs/behavior/order-management/timeline/phase-07-projection-engine.sdp.md b/specs/behavior/order-management/timeline/phase-07-projection-engine.sdp.md new file mode 100644 index 00000000..0fcb43a9 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-07-projection-engine.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-07-projection-engine +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Projection Engine (Deferred) + +## Intent + +- outcome: Record that a dedicated projection engine was evaluated and deferred in favor of Workpool. diff --git a/specs/behavior/order-management/timeline/phase-08-documentation-polish.sdp.md b/specs/behavior/order-management/timeline/phase-08-documentation-polish.sdp.md new file mode 100644 index 00000000..fd6c6a91 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-08-documentation-polish.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-08-documentation-polish +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Documentation & Knowledge Infrastructure + +## Intent + +- outcome: Deliver knowledge management systems and a frontend MVP with comprehensive testing. diff --git a/specs/behavior/order-management/timeline/phase-09-event-system.sdp.md b/specs/behavior/order-management/timeline/phase-09-event-system.sdp.md new file mode 100644 index 00000000..98af55fb --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-09-event-system.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-09-event-system +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Event System Enhancement + +## Intent + +- outcome: Provide advanced event categorization, upcasting, and correlation tracking. diff --git a/specs/behavior/order-management/timeline/phase-10-command-system.sdp.md b/specs/behavior/order-management/timeline/phase-10-command-system.sdp.md new file mode 100644 index 00000000..5f587780 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-10-command-system.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-10-command-system +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Command System Enhancement + +## Intent + +- outcome: Provide command categorization, registry, middleware pipeline, and batch execution. diff --git a/specs/behavior/order-management/timeline/phase-11-bc-formalization.sdp.md b/specs/behavior/order-management/timeline/phase-11-bc-formalization.sdp.md new file mode 100644 index 00000000..5d2a426c --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-11-bc-formalization.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-11-bc-formalization +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Bounded Context Formalization + +## Intent + +- outcome: Deliver contract-based bounded context infrastructure with declarative invariants. diff --git a/specs/behavior/order-management/timeline/phase-12-repository-read-model.sdp.md b/specs/behavior/order-management/timeline/phase-12-repository-read-model.sdp.md new file mode 100644 index 00000000..062f757a --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-12-repository-read-model.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-12-repository-read-model +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Repository & Read Model Infrastructure + +## Intent + +- outcome: Deliver projection registry, lifecycle management, and a query abstraction layer. diff --git a/specs/behavior/order-management/timeline/phase-13-process-manager.sdp.md b/specs/behavior/order-management/timeline/phase-13-process-manager.sdp.md new file mode 100644 index 00000000..ab6c5e29 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-13-process-manager.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-13-process-manager +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Process Manager Abstraction + +## Intent + +- outcome: Provide event-triggered process managers with idempotent processing and logging. diff --git a/specs/behavior/order-management/timeline/phase-14-decider-formalization.sdp.md b/specs/behavior/order-management/timeline/phase-14-decider-formalization.sdp.md new file mode 100644 index 00000000..1d912a90 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-14-decider-formalization.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-14-decider-formalization +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Decider Formalization + +## Intent + +- outcome: Extract pure decide functions from command handlers for testable domain logic. diff --git a/specs/behavior/order-management/timeline/phase-15-projection-categories.sdp.md b/specs/behavior/order-management/timeline/phase-15-projection-categories.sdp.md new file mode 100644 index 00000000..76515934 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-15-projection-categories.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-15-projection-categories +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Projection Categories + +## Intent + +- outcome: Formalize projection taxonomy with explicit Logic, View, Reporting, and Integration categories. diff --git a/specs/behavior/order-management/timeline/phase-16-dcb.sdp.md b/specs/behavior/order-management/timeline/phase-16-dcb.sdp.md new file mode 100644 index 00000000..000cbc65 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-16-dcb.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-16-dcb +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Dynamic Consistency Boundaries + +## Intent + +- outcome: Enable cross-entity invariants within bounded contexts via scope-based optimistic concurrency. diff --git a/specs/behavior/order-management/timeline/phase-17-reactive-projections.sdp.md b/specs/behavior/order-management/timeline/phase-17-reactive-projections.sdp.md new file mode 100644 index 00000000..0de6c709 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-17-reactive-projections.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-17-reactive-projections +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Reactive Projections + +## Intent + +- outcome: Combine Workpool with a reactive model so UI updates arrive in 10-50ms without polling. diff --git a/specs/behavior/order-management/timeline/phase-18-production-hardening.sdp.md b/specs/behavior/order-management/timeline/phase-18-production-hardening.sdp.md new file mode 100644 index 00000000..f73b682c --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-18-production-hardening.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-18-production-hardening +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Production Hardening + +## Intent + +- outcome: Provide production-ready observability, monitoring, and operational tooling. diff --git a/specs/behavior/order-management/timeline/phase-19-testing-infrastructure.sdp.md b/specs/behavior/order-management/timeline/phase-19-testing-infrastructure.sdp.md new file mode 100644 index 00000000..ea36ad32 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-19-testing-infrastructure.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-19-testing-infrastructure +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Testing Infrastructure + +## Intent + +- outcome: Complete BDD migration with Gherkin feature files for all domain logic. diff --git a/specs/behavior/order-management/timeline/phase-20-service-independence.sdp.md b/specs/behavior/order-management/timeline/phase-20-service-independence.sdp.md new file mode 100644 index 00000000..28e00df1 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-20-service-independence.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-20-service-independence +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Service Independence + +## Intent + +- outcome: Enable bounded contexts to operate independently via ECST, fat events, and the reservation pattern. diff --git a/specs/behavior/order-management/timeline/phase-21-integration-patterns.sdp.md b/specs/behavior/order-management/timeline/phase-21-integration-patterns.sdp.md new file mode 100644 index 00000000..71f2e816 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-21-integration-patterns.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-21-integration-patterns +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Integration Patterns + +## Intent + +- outcome: Formalize cross-context communication with a context map, published language, and anti-corruption layer. diff --git a/specs/behavior/order-management/timeline/phase-22-agent-as-bc.sdp.md b/specs/behavior/order-management/timeline/phase-22-agent-as-bc.sdp.md new file mode 100644 index 00000000..81185f32 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-22-agent-as-bc.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.order-management.timeline.phase-22-agent-as-bc +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Agent as Bounded Context + +## Intent + +- outcome: Demonstrate an AI agent as an event-reactor bounded context that emits commands autonomously. diff --git a/specs/behavior/order-management/timeline/phase-23-process-setup.sdp.md b/specs/behavior/order-management/timeline/phase-23-process-setup.sdp.md new file mode 100644 index 00000000..e8112933 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-23-process-setup.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-23-process-setup +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Monorepo Process Setup + +## Intent + +- outcome: Wire deliverable DataTables and monorepo docs generators so the existing feature files validate. +- problem: - 23 feature files exist but lack Background: Deliverables DataTables - Schema validation fails on 9 files, warnings on others - Manual documentation in docs/project-management/ not connected to process - No ROADMAP.md, SESSION-CONTEXT.md, REMAINING-WORK.md generators wired - Generator configs exist in package but not exposed at monorepo level +- value: - Add Background: Deliverables DataTables to all 23 existing feature files - Wire existing generator configs to monorepo-level commands - Update root package.json with new docs:* commands - Ensure generators produce expected output with no validation errors diff --git a/specs/behavior/order-management/timeline/phase-24-old-roadmap-porting.sdp.md b/specs/behavior/order-management/timeline/phase-24-old-roadmap-porting.sdp.md new file mode 100644 index 00000000..76a8c423 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-24-old-roadmap-porting.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-24-old-roadmap-porting +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Old Roadmap Porting + +## Intent + +- outcome: Port completed-phase roadmap detail into feature-file DataTables so manual roadmap docs can be deprecated. +- problem: - Rich detail in docs/project-management/roadmap/*.md (23 files) - Tasks, deliverables, verification steps not captured in feature files - Historical context needed for future work and pattern understanding - Manual docs will drift without connection to process +- value: - Extract deliverables from each completed phase's .md file - Populate DataTables with Location, Tests, Release info - Link to CHANGELOG entries for version history - Mark manual roadmap docs as deprecated once ported diff --git a/specs/behavior/order-management/timeline/phase-25-adr-porting.sdp.md b/specs/behavior/order-management/timeline/phase-25-adr-porting.sdp.md new file mode 100644 index 00000000..b63e103e --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-25-adr-porting.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-25-adr-porting +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# ADR Porting to Feature Files + +## Intent + +- outcome: Convert valid ADRs into process-connected feature files and generate a DECISIONS.md index. +- problem: - 33 ADRs exist in docs/architecture/decisions/ as manual .md files - ADRs are disconnected from delivery process - Some ADRs may be outdated or superseded by aggregate-less pivot - No generated DECISIONS.md artifact for architectural overview +- value: - Review each ADR against new aggregate-less roadmap for validity - Convert valid ADRs to .feature files with @architect-decision tag - Archive or supersede outdated ADRs with proper annotation - Wire docs:adrs generator to monorepo-level commands - Generate DECISIONS.md with categorized ADR index diff --git a/specs/behavior/order-management/timeline/phase-26-workflow-configuration.sdp.md b/specs/behavior/order-management/timeline/phase-26-workflow-configuration.sdp.md new file mode 100644 index 00000000..9ce5937e --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-26-workflow-configuration.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-26-workflow-configuration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Workflow Configuration for Planning Sessions + +## Intent + +- outcome: Configure monorepo-specific planning-session workflows and the artifacts each session type should produce. +- problem: - Base process specs (PROCESS_MODEL.md, PROCESS_SETUP.md) define workflows - Monorepo needs customized workflow configuration for planning sessions - Not all sessions produce code - some produce designs, requirements, analysis - Need to define what each workflow type should output +- value: - Review base process specs for default workflows - Configure monorepo-specific workflow phases (Inception, Elaboration, etc.) - Define session types with expected artifacts: - Requirements: Feature files, PRD content - Analysis: Investigation notes, gap identification - Design: ADRs, architecture decisions - Implementation: Code, tests - Validation: DoD verification, acceptance testing - Create reusable session templates for each workflow type diff --git a/specs/behavior/order-management/timeline/phase-27-pattern-annotation-priorities.sdp.md b/specs/behavior/order-management/timeline/phase-27-pattern-annotation-priorities.sdp.md new file mode 100644 index 00000000..793e8884 --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-27-pattern-annotation-priorities.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-27-pattern-annotation-priorities +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Pattern Annotation Prioritization + +## Intent + +- outcome: Prioritize core infrastructure pattern annotations that inform roadmap decisions. +- problem: - PATTERNS.md needs annotations in @convex-es/* packages - New roadmap milestones require understanding core patterns first - Current annotation coverage is sparse - Need strategic prioritization, not exhaustive annotation +- value: - Prioritize core infrastructure patterns that inform roadmap decisions: 1. Middleware (command/event flow) 2. Event Bus (event delivery mechanism) 3. Command Orchestrator (7-step lifecycle) 4. CMS (Command Model State) 5. Handlers (command/event handling) - Annotate foundational patterns before advanced ones - Use @architect-roadmap tag for patterns relevant to planned phases - Progressive annotation: annotate per PR as code is touched diff --git a/specs/behavior/order-management/timeline/phase-28-modular-claude-md.sdp.md b/specs/behavior/order-management/timeline/phase-28-modular-claude-md.sdp.md new file mode 100644 index 00000000..18d0690f --- /dev/null +++ b/specs/behavior/order-management/timeline/phase-28-modular-claude-md.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.order-management.timeline.phase-28-modular-claude-md +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.order-management +--- +# Modular CLAUDE.md with Hybrid Generation + +## Intent + +- outcome: Extract a modular CLAUDE.md build system with generated and manual modules. +- problem: - Current CLAUDE.md is 896 lines of organically accumulated content (2 weeks rapid iteration) - No variation support - same content for all work contexts - Manual maintenance burden - updates lag code changes - Mixed content types: some should be generated, some static - No evidence-based effectiveness tracking - Difficult to compose different "views" for different session types +- value: - Extract CLAUDE.md build system to delivery-process package - Create hybrid architecture: generated + manual modules - Support tag-based variations (patterns, process, security, etc.) - Integrate with @architect annotations for auto-generated pattern docs - Enable session templates as includable prompt content - Add effectiveness tracking for evidence-based content decisions diff --git a/specs/behavior/platform-bc/_epic.sdp.md b/specs/behavior/platform-bc/_epic.sdp.md new file mode 100644 index 00000000..a48bd92e --- /dev/null +++ b/specs/behavior/platform-bc/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:behavior.platform-bc +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-bc executable behavior + +## Intent + +- outcome: Hold the executable Gherkin behavior Specs migrated from the platform-bc test corpus. diff --git a/specs/behavior/platform-bc/bc-contracts.sdp.md b/specs/behavior/platform-bc/bc-contracts.sdp.md new file mode 100644 index 00000000..db5ed481 --- /dev/null +++ b/specs/behavior/platform-bc/bc-contracts.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-bc.bc-contracts +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-bc +--- +# Bounded Context Contract Helper Functions + +## Intent + +- outcome: Preserve literal types on bounded-context contract helpers so registries stay type-safe and category strings can be validated at runtime. +- value: defineCommand, defineEvent, defineProjection, and defineProcessManager keep literal names, and category validators reject invalid strings. diff --git a/specs/behavior/platform-bc/bounded-context-foundation-executable-tests.sdp.md b/specs/behavior/platform-bc/bounded-context-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..976b5ae1 --- /dev/null +++ b/specs/behavior/platform-bc/bounded-context-foundation-executable-tests.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-bc.bounded-context-foundation-executable-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-bc +--- +# BoundedContextFoundation Executable Tests + +## Intent + +- problem: DDD bounded contexts need physically enforced boundaries; without isolation, accidental coupling undermines domain-driven design. +- outcome: Isolate each Convex component database behind a typed component API so a parent app cannot query component tables directly. +- value: DualWriteContextContract and string conversion at the API boundary keep inter-context communication type-safe. + +## Behavior + +- rule: Components have isolated databases that parent cannot query directly +- rule: Sub-transactions are atomic within components +- rule: ctx.auth does not cross component boundaries +- rule: Id inside component becomes string at API boundary +- rule: DualWriteContextContract formalizes the bounded context API diff --git a/specs/behavior/platform-bus/_epic.sdp.md b/specs/behavior/platform-bus/_epic.sdp.md new file mode 100644 index 00000000..fe0bd2cb --- /dev/null +++ b/specs/behavior/platform-bus/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:behavior.platform-bus +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-bus executable behavior + +## Intent + +- outcome: Hold the executable Gherkin behavior Specs migrated from the platform-bus test corpus. diff --git a/specs/behavior/platform-bus/command-bus-foundation-executable-tests.sdp.md b/specs/behavior/platform-bus/command-bus-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..67ca3989 --- /dev/null +++ b/specs/behavior/platform-bus/command-bus-foundation-executable-tests.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-bus.command-bus-foundation-executable-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-bus +--- +# CommandBusFoundation Executable Tests + +## Intent + +- problem: Command execution needs infrastructure-level idempotency, status tracking, and one standardized flow; without that, duplicate requests can corrupt domain state. +- outcome: Record each command by commandId, track pending through executed, rejected, or failed, and run every command through the CommandOrchestrator. +- value: The same commandId returns the same result without re-execution, so retries cannot double-apply domain changes. + +## Behavior + +- rule: Commands are idempotent via commandId deduplication +- rule: Status tracks the complete command lifecycle +- rule: The CommandOrchestrator is the only command execution path +- rule: correlationId links commands, events, and projections +- rule: Middleware provides composable cross-cutting concerns diff --git a/specs/behavior/platform-bus/idempotency.sdp.md b/specs/behavior/platform-bus/idempotency.sdp.md new file mode 100644 index 00000000..41131d6e --- /dev/null +++ b/specs/behavior/platform-bus/idempotency.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-bus.idempotency +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-bus +--- +# Command Bus Idempotency + +## Intent + +- outcome: Detect duplicate command submissions that share a commandId and return the existing status instead of executing twice. +- value: Command dispatch stays reliable in distributed systems where retries may occur. diff --git a/specs/behavior/platform-core/_epic.sdp.md b/specs/behavior/platform-core/_epic.sdp.md new file mode 100644 index 00000000..2426d332 --- /dev/null +++ b/specs/behavior/platform-core/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:behavior.platform-core +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-core executable behavior + +## Intent + +- outcome: Hold the executable Gherkin behavior Specs migrated from the platform-core test corpus. diff --git a/specs/behavior/platform-core/agent/action-handler.sdp.md b/specs/behavior/platform-core/agent/action-handler.sdp.md new file mode 100644 index 00000000..6f9a8300 --- /dev/null +++ b/specs/behavior/platform-core/agent/action-handler.sdp.md @@ -0,0 +1,53 @@ +--- +id: spec:behavior.platform-core.agent.action-handler +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Action Handler + +## Intent + +- outcome: Load agent state, skip already-processed or inactive agents, run the pattern executor, and return an action result without persisting. +- value: Workpool can retry analysis as the ACTION half of the action/mutation split. + +## Behavior + +- rule: Handler returns null when event globalPosition is less than or equal to checkpoint lastProcessedPosition. +- rule: Handler returns null when agent checkpoint status is not active. +- rule: Handler processes normally when checkpoint is null or the event position is ahead of the checkpoint. +- rule: Handler re-throws errors from pattern trigger and loadState so Workpool can retry. +- rule: decisionId is always dec_{agentId}_{globalPosition}. +- rule: Handler invokes the pattern executor and returns the matching patternId, analysisMethod, and decision. + +## Example space + +```gwt-vocabulary +Given an agent config with default test pattern +And an agent config with a throwing pattern {throwMessage:string} +And an agent config with a {patternName:string} pattern that always triggers +And an agent config with a {patternName:string} pattern that has LLM analyze +And an agent config with a pattern that never triggers +And an agent config with a rule-only pattern and a spy runtime +And a checkpoint with lastProcessedPosition {lastProcessedPosition:number} and status {status:"active"|"paused"|"stopped"|"error_recovery"} +And a null checkpoint +And a loadState that rejects with {loadStateError:string} +When I invoke the handler with agentId {agentId:string} and globalPosition {globalPosition:number} +Then the result is null +And the result is not null +And the result analysisMethod is {analysisMethod:"rule-based"|"llm"} +And the result decisionId is {decisionId:string} +And the result llmMetrics is undefined +And the result patternId is {patternId:string} +And the result patternId is undefined +And the decision is not null +And the decision is null +And the decision command is null +And the decision command is {command:string} +And the decision confidence is {confidence:number} +And the error message is {errorMessage:string} +And both results have decisionId {decisionId:string} +And the runtime analyze was not called +``` diff --git a/specs/behavior/platform-core/agent/agent-rate-limiter.sdp.md b/specs/behavior/platform-core/agent/agent-rate-limiter.sdp.md new file mode 100644 index 00000000..2598c7eb --- /dev/null +++ b/specs/behavior/platform-core/agent/agent-rate-limiter.sdp.md @@ -0,0 +1,46 @@ +--- +id: spec:behavior.platform-core.agent.agent-rate-limiter +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Rate Limiter + +## Intent + +- outcome: Guard agent operations behind a rate-limit check so an allowed call executes the wrapped operation once and a denied call skips it and returns retryAfterMs. +- value: Callers receive either the operation result or retry timing, and errors from the operation or checkRateLimit still propagate. + +## Behavior + +- rule: Allowed operations execute and return their result +- rule: Denied operations are skipped with retry information +- rule: Rate limit key is agent-scoped +- rule: Errors propagate correctly +- rule: Logging reflects rate limit outcomes + +## Example space + +```gwt-vocabulary +Given a rate limiter config for agent {agentId:string} that allows requests +And a rate limiter config for agent {agentId:string} that denies with retryAfterMs {retryAfterMs:number} +And a rate limiter config for agent {agentId:string} where checkRateLimit throws {errorMessage:string} +And a rate limiter config with logger for agent {agentId:string} that denies with retryAfterMs {retryAfterMs:number} +And a rate limiter config with logger for agent {agentId:string} that allows requests +And an operation that returns analysis "success" with score 0.95 +And an operation that throws {errorMessage:string} +And a mock operation +And a simple operation +When I call withRateLimit +Then the result indicates allowed is {allowed:boolean} +And the result value has analysis "success" and score 0.95 +And the operation was called 1 time +And the result retryAfterMs is {retryAfterMs:number} +And the operation was not called +And checkRateLimit was called with key "agent:churn-risk-agent" +And the error message is {errorMessage:string} +And the logger warned "Rate limited" with agentId {agentId:string} and retryAfterMs {retryAfterMs:number} +And the logger logged debug "Rate limit passed, executing operation" with agentId {agentId:string} +``` diff --git a/specs/behavior/platform-core/agent/agent-subscription-action.sdp.md b/specs/behavior/platform-core/agent/agent-subscription-action.sdp.md new file mode 100644 index 00000000..168266e8 --- /dev/null +++ b/specs/behavior/platform-core/agent/agent-subscription-action.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.agent.agent-subscription-action +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Subscription - Action Overload + +## Intent + +- outcome: Create an action-typed agent subscription with handlerType action, an onComplete reference, optional retry, default priority 250, agent naming, event filtering, toHandlerArgs, toWorkpoolContext, and a streamId partition key. +- value: Action subscriptions carry the handler and completion references the workpool needs without inventing a second subscription factory. + +## Behavior + +- rule: Action subscription creation sets correct handler type and references +- rule: Retry configuration is passed through to action subscriptions +- rule: toWorkpoolContext produces correct shape +- rule: Default priority is 250 +- rule: Subscription name follows agent naming convention +- rule: Event filtering uses configured event types +- rule: toHandlerArgs transforms event to AgentEventHandlerArgs +- rule: Partition key defaults to streamId diff --git a/specs/behavior/platform-core/agent/agent-subscription.sdp.md b/specs/behavior/platform-core/agent/agent-subscription.sdp.md new file mode 100644 index 00000000..fe2d065f --- /dev/null +++ b/specs/behavior/platform-core/agent/agent-subscription.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.agent.agent-subscription +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Subscription - Mutation Overload + +## Intent + +- outcome: Create mutation EventSubscription objects with naming, priority, event filtering, handler-args transformation, partition keys, batch creation, and agentId memoization, and map PublishedEvent fields through defaultAgentTransform. +- value: Mutation subscriptions and defaultAgentTransform expose a consistent AgentEventHandlerArgs shape, including non-object payload wrapping. + +## Behavior + +- rule: createAgentSubscription produces correct subscription properties +- rule: toHandlerArgs transforms event to AgentEventHandlerArgs +- rule: getPartitionKey extracts correct partition key +- rule: createAgentSubscriptions creates batch subscriptions +- rule: AgentId is memoized across calls +- rule: Event filtering only matches subscribed event types +- rule: defaultAgentTransform handles all PublishedEvent fields diff --git a/specs/behavior/platform-core/agent/approval.sdp.md b/specs/behavior/platform-core/agent/approval.sdp.md new file mode 100644 index 00000000..4240a8d6 --- /dev/null +++ b/specs/behavior/platform-core/agent/approval.sdp.md @@ -0,0 +1,44 @@ +--- +id: spec:behavior.platform-core.agent.approval +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Approval Module + +## Intent + +- outcome: Provide pure functions for the human-in-loop approval workflow covering approval determination, authorization checks, status transitions, factory functions, type guards, Zod schemas, and timeout helpers. + +## Behavior + +- rule: APPROVAL_ERROR_CODES maps each error name to its string value. +- rule: APPROVAL_STATUSES is a readonly 4-element tuple of pending, approved, rejected, and expired. +- rule: isApprovalStatus returns true only for the four valid status strings. +- rule: ApprovalStatusSchema accepts valid statuses and rejects invalid values. +- rule: PendingApprovalSchema accepts well-formed approvals and rejects malformed ones. +- rule: ApprovalAuthContextSchema accepts valid auth contexts, optionally with roles or agentIds. +- rule: parseApprovalTimeout returns milliseconds for valid Nd/Nh/Nm patterns and null otherwise. +- rule: isValidApprovalTimeout returns true for valid duration formats and false otherwise. +- rule: calculateExpirationTime adds the parsed timeout, or the default, to requestedAt. +- rule: shouldRequireApproval returns true when confidence is less than or equal to the threshold. +- rule: Actions in requiresApproval always require approval regardless of confidence. +- rule: Actions in autoApprove skip approval regardless of confidence. +- rule: When an action is in both lists, requiresApproval wins over autoApprove. +- rule: Empty or undefined requiresApproval and autoApprove lists fall through to the confidence check. +- rule: Authorization fails closed when agentIds is set; the list must be non-empty and include approval.agentId. +- rule: Roles are checked after agentIds; empty or undefined roles fail closed. +- rule: The agentIds check fails even when the user has an admin role. +- rule: generateApprovalId produces IDs with an apr_ prefix and a full UUIDv7 suffix. +- rule: createPendingApproval sets status pending and leaves reviewerId, reviewedAt, reviewNote, and rejectionReason undefined. +- rule: Only unexpired pending approvals can be approved; approveAction sets reviewerId, reviewedAt, and an optional reviewNote. +- rule: Only unexpired pending approvals can be rejected; rejectAction sets reviewerId, rejectionReason, and reviewedAt. +- rule: Only pending approvals can be expired; expireAction does not set reviewerId. +- rule: safeApproveAction returns success with an approved approval or failure with an error code. +- rule: safeRejectAction returns success with a rejected approval or failure with an error code. +- rule: Each status type guard returns true only for its matching status. +- rule: getRemainingApprovalTime returns positive milliseconds for an active pending approval and 0 for expired or non-pending. +- rule: formatRemainingApprovalTime formats remaining time as Xh Ym, Xm, or expired. +- rule: validatePendingApproval returns true for a valid PendingApproval and false for invalid shapes. diff --git a/specs/behavior/platform-core/agent/audit-trail.sdp.md b/specs/behavior/platform-core/agent/audit-trail.sdp.md new file mode 100644 index 00000000..3d4c94a4 --- /dev/null +++ b/specs/behavior/platform-core/agent/audit-trail.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.agent.audit-trail +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Agent Audit Trail + +## Intent + +- actor: a platform developer +- outcome: all agent decisions audited as events so that agent behavior is fully traceable + +## Behavior + +- rule: All agent decisions create audit events +- rule: LLM interactions are audited +- rule: Action outcomes are recorded +- rule: Audit trail supports queries diff --git a/specs/behavior/platform-core/agent/audit.sdp.md b/specs/behavior/platform-core/agent/audit.sdp.md new file mode 100644 index 00000000..ede35c22 --- /dev/null +++ b/specs/behavior/platform-core/agent/audit.sdp.md @@ -0,0 +1,38 @@ +--- +id: spec:behavior.platform-core.agent.audit +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Audit Trail + +## Intent + +- outcome: Provide decision ID generation, audit event factories, type guards, and Zod schema validation so agent decisions form an explainable audit trail. +- value: Callers can record and inspect pattern detection, approval, command routing, lifecycle, and analysis-failure events from one typed event catalog. + +## Behavior + +- rule: AGENT_AUDIT_EVENT_TYPES contains all DS-1, DS-4, DS-5, and DS-6 event types. +- rule: isAgentAuditEventType returns true for all canonical event type strings and false for anything else. +- rule: AgentAuditEventTypeSchema accepts all canonical event types and rejects everything else. +- rule: AuditLLMContextSchema accepts valid model, tokens, and duration, and rejects negative or non-integer values. +- rule: AuditActionSchema accepts a valid type plus executionMode, and rejects empty type, invalid mode, or extra fields. +- rule: PatternDetectedPayloadSchema accepts valid payloads with optional nulls for pattern or action, and rejects out-of-range confidence. +- rule: ApprovalGrantedPayloadSchema accepts valid actionId, reviewerId, and reviewedAt with optional reviewNote, and rejects empty actionId. +- rule: ApprovalRejectedPayloadSchema accepts valid actionId, reviewerId, and rejectionReason. +- rule: ApprovalExpiredPayloadSchema accepts valid actionId, requestedAt, and expiredAt, and rejects empty actionId. +- rule: AgentAuditEventSchema accepts a valid event with all required fields and rejects empty agentId or decisionId. +- rule: generateDecisionId produces IDs with a dec_ prefix, a full UUIDv7 payload, and uniqueness across calls. +- rule: createPatternDetectedAudit returns an event with PatternDetected type, a generated decisionId, and all payload fields. +- rule: createApprovalGrantedAudit returns an event with ApprovalGranted type, actionId, reviewerId, reviewedAt, and optional reviewNote. +- rule: createApprovalRejectedAudit returns an event with ApprovalRejected type, actionId, reviewerId, and rejectionReason. +- rule: createApprovalExpiredAudit returns an event with ApprovalExpired type, actionId, requestedAt, and expiredAt. +- rule: createGenericAuditEvent returns an event with the specified type, a generated decisionId, and the given or empty payload. +- rule: isPatternDetectedEvent returns true only for events with eventType PatternDetected. +- rule: isApprovalGrantedEvent returns true only for events with eventType ApprovalGranted. +- rule: isApprovalRejectedEvent returns true only for events with eventType ApprovalRejected. +- rule: validateAgentAuditEvent returns true for factory-created events and false for null, undefined, empty, or invalid objects. +- rule: Factory-created events form valid audit trails with proper timestamps and type guards. diff --git a/specs/behavior/platform-core/agent/checkpoint-extension.sdp.md b/specs/behavior/platform-core/agent/checkpoint-extension.sdp.md new file mode 100644 index 00000000..87e4fe80 --- /dev/null +++ b/specs/behavior/platform-core/agent/checkpoint-extension.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.agent.checkpoint-extension +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Checkpoint Extension + +## Intent + +- outcome: Detect error recovery, resolve effective config with overrides, apply checkpoint updates with config merges, and create initial checkpoints. +- value: Per-agent overrides deep-merge onto base config without dropping fields the update does not mention. + +## Behavior + +- rule: isAgentInErrorRecovery returns true only for error_recovery status +- rule: resolveEffectiveConfig returns base config when no overrides provided +- rule: resolveEffectiveConfig applies partial overrides while preserving other values +- rule: resolveEffectiveConfig deep-merges rateLimits.costBudget +- rule: resolveEffectiveConfig fully overrides all config values +- rule: resolveEffectiveConfig handles edge cases +- rule: applyCheckpointUpdate merges configOverrides correctly +- rule: createInitialAgentCheckpoint produces correct defaults diff --git a/specs/behavior/platform-core/agent/checkpoint.sdp.md b/specs/behavior/platform-core/agent/checkpoint.sdp.md new file mode 100644 index 00000000..7895f027 --- /dev/null +++ b/specs/behavior/platform-core/agent/checkpoint.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.agent.checkpoint +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Checkpoint + +## Intent + +- outcome: Manage agent checkpoints with creation, position tracking, idempotency guards, status helpers, and schema validation. +- value: Agents skip duplicate and out-of-order events and can pause, resume, and recover from a known position. + +## Behavior + +- rule: AGENT_CHECKPOINT_STATUSES is a readonly tuple of four statuses +- rule: AgentCheckpointStatusSchema accepts only valid status strings +- rule: AgentCheckpointSchema validates complete checkpoint objects +- rule: createInitialAgentCheckpoint produces a valid default checkpoint +- rule: applyCheckpointUpdate merges partial updates into an existing checkpoint +- rule: shouldProcessAgentEvent guards against duplicate and out-of-order events +- rule: Status helper functions reflect checkpoint status accurately +- rule: isValidAgentCheckpoint validates arbitrary input against the schema +- rule: Checkpoint lifecycle supports create-process-pause-resume-recover workflows diff --git a/specs/behavior/platform-core/agent/command-bridge.sdp.md b/specs/behavior/platform-core/agent/command-bridge.sdp.md new file mode 100644 index 00000000..3d4c68c2 --- /dev/null +++ b/specs/behavior/platform-core/agent/command-bridge.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.agent.command-bridge +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Command Bridge Handler + +## Intent + +- outcome: Look up the route, validate registry membership, transform args, call the orchestrator, record audit events, and update decision status. +- value: Failures at each stage produce structured audit trails without propagating to the caller. + +## Behavior + +- rule: Happy path routes command through the full pipeline +- rule: Unknown route records routing failure +- rule: Command not in registry records routing failure +- rule: Transform failure records routing failure +- rule: Orchestrator failure records routing failure with error details +- rule: Audit failure does not propagate to caller +- rule: Status update failure does not propagate to caller +- rule: Optional updateStatus is gracefully skipped +- rule: patternId propagation in audit events diff --git a/specs/behavior/platform-core/agent/command-emission.sdp.md b/specs/behavior/platform-core/agent/command-emission.sdp.md new file mode 100644 index 00000000..e69b114f --- /dev/null +++ b/specs/behavior/platform-core/agent/command-emission.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.agent.command-emission +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Command Emission + +## Intent + +- actor: a platform developer +- outcome: Emit agent commands with explainability metadata so that agent actions are traceable and auditable. +- value: Commands reach the Command Bus with required metadata, and LLM failures fall back or retry instead of emitting unexplained commands. + +## Behavior + +- rule: Agents emit commands to Command Bus +- rule: Commands include explainability metadata +- rule: Commands must meet minimum metadata requirements +- rule: Command emission handles LLM failures gracefully +- rule: Different command types for different actions diff --git a/specs/behavior/platform-core/agent/command-router.sdp.md b/specs/behavior/platform-core/agent/command-router.sdp.md new file mode 100644 index 00000000..513c3c37 --- /dev/null +++ b/specs/behavior/platform-core/agent/command-router.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.platform-core.agent.command-router +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Command Router + +## Intent + +- outcome: Look up routes by commandType, validate route-map integrity, and enumerate COMMAND_ROUTING_ERROR_CODES. +- value: Invalid routes fail with a specific code instead of reaching the orchestrator. + +## Behavior + +- rule: getRoute returns matching route or undefined +- rule: validateRoutes produces success or error results per route +- rule: COMMAND_ROUTING_ERROR_CODES contains all expected codes diff --git a/specs/behavior/platform-core/agent/commands.sdp.md b/specs/behavior/platform-core/agent/commands.sdp.md new file mode 100644 index 00000000..6fc76325 --- /dev/null +++ b/specs/behavior/platform-core/agent/commands.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.agent.commands +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Commands Module + +## Intent + +- outcome: Validate agent command emission, create commands via factories, apply type guards, and convert decisions to commands. +- value: Emitted commands carry required explainability fields and reject incomplete arguments before they reach the bus. + +## Behavior + +- rule: COMMAND_EMISSION_ERROR_CODES contains all expected codes +- rule: EmittedAgentCommandMetadataSchema validates metadata +- rule: EmittedAgentCommandSchema validates commands +- rule: validateAgentCommand validates command arguments +- rule: createEmittedAgentCommand factory creates commands +- rule: createCommandFromDecision converts decisions to commands +- rule: isEmittedAgentCommand type guard validates objects +- rule: hasPatternId type guard checks for patternId presence +- rule: hasAnalysisData type guard checks for analysis presence +- rule: End-to-end command creation flow validates and verifies diff --git a/specs/behavior/platform-core/agent/cost-budget.sdp.md b/specs/behavior/platform-core/agent/cost-budget.sdp.md new file mode 100644 index 00000000..4e89787e --- /dev/null +++ b/specs/behavior/platform-core/agent/cost-budget.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.agent.cost-budget +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Cost Budget + +## Intent + +- outcome: Evaluate spend against budget limits, estimate token costs, and look up default per-model pricing. +- value: Agent LLM work is denied when estimated cost would exceed the daily budget and flagged when spend meets the alert threshold. + +## Behavior + +- rule: Budget checks allow or deny based on remaining budget +- rule: Alert threshold flags when spend ratio meets or exceeds threshold +- rule: Cost estimation performs token-cost multiplication +- rule: Default model costs contain expected entries diff --git a/specs/behavior/platform-core/agent/dead-letter.sdp.md b/specs/behavior/platform-core/agent/dead-letter.sdp.md new file mode 100644 index 00000000..66e5567f --- /dev/null +++ b/specs/behavior/platform-core/agent/dead-letter.sdp.md @@ -0,0 +1,34 @@ +--- +id: spec:behavior.platform-core.agent.dead-letter +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Dead Letter Queue + +## Intent + +- outcome: Sanitize and record failed agent event processing so a pending dead letter can be replayed or ignored without leaking stack traces or mixing process-manager semantics. +- value: Operators can investigate, replay, or ignore poisoned agent work from a schema-validated queue with pending-only status transitions. + +## Behavior + +- rule: Error codes are well-defined constants +- rule: Status types enumerate all valid dead letter statuses +- rule: Zod status schema validates status strings +- rule: Zod context schema validates dead letter context objects +- rule: Zod dead letter schema validates complete dead letter objects +- rule: Sanitization removes stack traces from error messages +- rule: Sanitization removes or replaces file paths +- rule: Sanitization truncates at 500 characters +- rule: Sanitization handles different input types +- rule: Sanitization normalizes whitespace +- rule: Factory function creates dead letters with correct defaults +- rule: Increment updates attempt count, error, and timestamp +- rule: Status transition to replayed only from pending +- rule: Status transition to ignored only from pending +- rule: Type guards correctly identify dead letter statuses +- rule: Validation function checks complete dead letter structure +- rule: Dead letter lifecycle supports replay and ignore paths diff --git a/specs/behavior/platform-core/agent/event-subscription.sdp.md b/specs/behavior/platform-core/agent/event-subscription.sdp.md new file mode 100644 index 00000000..8ea1f891 --- /dev/null +++ b/specs/behavior/platform-core/agent/event-subscription.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.agent.event-subscription +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Event Subscription + +## Intent + +- actor: a platform developer +- outcome: Agents subscribe to event streams via EventBus. +- value: Agents can react to business events in real time. + +## Behavior + +- rule: Agents subscribe to specific event types +- rule: Subscriptions support filters +- rule: Events are delivered in order +- rule: Agent checkpoint tracks processing progress +- rule: Subscriptions can be paused and resumed diff --git a/specs/behavior/platform-core/agent/human-in-loop.sdp.md b/specs/behavior/platform-core/agent/human-in-loop.sdp.md new file mode 100644 index 00000000..fd8bede1 --- /dev/null +++ b/specs/behavior/platform-core/agent/human-in-loop.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.agent.human-in-loop +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Human-in-Loop Configuration + +## Intent + +- actor: a platform developer +- outcome: Configure human-in-loop controls so agent actions can be reviewed when appropriate. +- value: Confidence thresholds, approval requirements, and timeouts decide auto-execution versus human review. + +## Behavior + +- rule: Confidence threshold determines execution mode — high confidence auto-executes, low confidence requires review. +- rule: Some actions always require approval — critical actions bypass the confidence threshold. +- rule: Flagged actions create review tasks — human reviewers see pending actions. +- rule: Pending actions expire after timeout — unreviewed actions do not linger indefinitely. diff --git a/specs/behavior/platform-core/agent/init.sdp.md b/specs/behavior/platform-core/agent/init.sdp.md new file mode 100644 index 00000000..a1107a46 --- /dev/null +++ b/specs/behavior/platform-core/agent/init.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.agent.init +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Initialization + +## Intent + +- outcome: Validate agent BC config, transform a published event and correlation chain into handler args, generate agent-scoped subscription IDs, and initialize an agent BC with a success handle or INVALID_CONFIG error. +- value: Callers can bootstrap an agent bounded context from a validated config, resuming an existing checkpoint or creating a fresh one. + +## Behavior + +- rule: validateAgentBCConfig rejects empty, undefined, or whitespace-only id with AGENT_ID_REQUIRED. +- rule: validateAgentBCConfig rejects empty or undefined subscriptions with NO_SUBSCRIPTIONS. +- rule: validateAgentBCConfig rejects a confidence threshold outside [0, 1] with INVALID_CONFIDENCE_THRESHOLD. +- rule: validateAgentBCConfig rejects empty or whitespace-only pattern window duration with INVALID_PATTERN_WINDOW. +- rule: validateAgentBCConfig rejects an action in both requiresApproval and autoApprove with CONFLICTING_APPROVAL_RULES. +- rule: validateAgentBCConfig rejects missing or empty patterns with NO_PATTERNS. +- rule: validateAgentBCConfig accepts a well-formed config, including when optional confidenceThreshold is omitted. +- rule: toAgentHandlerArgs transforms PublishedEvent and CorrelationChain into AgentEventHandlerArgs using the chain correlationId, wrapping non-object payloads in _raw. +- rule: generateSubscriptionId produces IDs that start with sub_, contain the agentId, include a UUIDv7 suffix, and differ when regenerated. +- rule: initializeAgentBC returns a success handle with agentId, config, subscription, and checkpoint for valid config. +- rule: initializeAgentBC returns INVALID_CONFIG for invalid config. +- rule: initializeAgentBC uses existingCheckpoint when provided instead of creating a new one. +- rule: initializeAgentBC creates a fresh checkpoint at lastProcessedPosition -1 with 0 events processed when none is provided. diff --git a/specs/behavior/platform-core/agent/lifecycle-commands.sdp.md b/specs/behavior/platform-core/agent/lifecycle-commands.sdp.md new file mode 100644 index 00000000..a9af6db6 --- /dev/null +++ b/specs/behavior/platform-core/agent/lifecycle-commands.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.agent.lifecycle-commands +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Lifecycle Commands + +## Intent + +- outcome: Export agent lifecycle command types, error codes, result types, and Convex validators for the discriminated-union command model. +- value: Callers construct StartAgent, PauseAgent, ResumeAgent, StopAgent, and ReconfigureAgent variants and success or failure results without extra fields. + +## Behavior + +- rule: Command types construct with correct discriminated union fields +- rule: AgentConfigOverrides allows partial and nested optional fields +- rule: AGENT_LIFECYCLE_ERROR_CODES defines exactly the expected constants +- rule: Result types construct success and failure variants with discrimination +- rule: Convex validators are exported and defined diff --git a/specs/behavior/platform-core/agent/lifecycle-fsm.sdp.md b/specs/behavior/platform-core/agent/lifecycle-fsm.sdp.md new file mode 100644 index 00000000..c80246f4 --- /dev/null +++ b/specs/behavior/platform-core/agent/lifecycle-fsm.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.agent.lifecycle-fsm +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Lifecycle FSM + +## Intent + +- outcome: Provide a pure agent lifecycle state machine with states, events, transitions, classification helpers, and command-to-event mapping. +- value: Transition checks stay out of I/O so handlers can validate start, pause, resume, stop, and reconfigure before writing checkpoint status. + +## Behavior + +- rule: Lifecycle state constants are well-defined +- rule: Lifecycle event constants are well-defined +- rule: All 10 valid transitions produce the correct target state +- rule: isValidAgentTransition returns true for all valid pairs +- rule: transitionAgentState returns null for invalid transitions +- rule: Exhaustive invalid pair coverage via isValidAgentTransition +- rule: Exhaustive invalid pair coverage via transitionAgentState +- rule: assertValidAgentTransition returns next state or throws +- rule: getValidAgentEventsFrom returns correct events per state +- rule: getAllAgentTransitions returns the complete transition table +- rule: isAgentErrorState classifies states correctly +- rule: isAgentProcessingState classifies states correctly +- rule: commandToEvent maps command types to lifecycle events diff --git a/specs/behavior/platform-core/agent/lifecycle-handlers.sdp.md b/specs/behavior/platform-core/agent/lifecycle-handlers.sdp.md new file mode 100644 index 00000000..2cde3afb --- /dev/null +++ b/specs/behavior/platform-core/agent/lifecycle-handlers.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.agent.lifecycle-handlers +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Lifecycle Handlers + +## Intent + +- outcome: Load the checkpoint, validate the FSM transition via a pure decider, and atomically write the new status plus an audit event for each lifecycle command. +- value: createLifecycleHandlers returns the five handler functions that bypass CommandOrchestrator. + +## Behavior + +- rule: handleStartAgent transitions stopped to active with AgentStarted audit +- rule: handlePauseAgent transitions active to paused with AgentPaused audit +- rule: handleResumeAgent transitions paused to active with AgentResumed audit +- rule: handleStopAgent transitions active, paused, or error_recovery to stopped with AgentStopped audit +- rule: handleReconfigureAgent patches config overrides and transitions to active +- rule: createLifecycleHandlers factory returns all 5 handler functions +- rule: Lifecycle handlers use logger correctly diff --git a/specs/behavior/platform-core/agent/oncomplete-handler.sdp.md b/specs/behavior/platform-core/agent/oncomplete-handler.sdp.md new file mode 100644 index 00000000..a5ad8ba3 --- /dev/null +++ b/specs/behavior/platform-core/agent/oncomplete-handler.sdp.md @@ -0,0 +1,76 @@ +--- +id: spec:behavior.platform-core.agent.oncomplete-handler +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent onComplete Handler + +## Intent + +- outcome: Persist canceled, failed, and successful agent action results without throwing, advancing the checkpoint only after successful persistence. +- value: Workpool can treat analysis as done while this mutation persists audit, commands, approvals, and the checkpoint. + +## Behavior + +- rule: A canceled workpool result triggers no mutations. +- rule: Failed results persist a dead letter and AgentAnalysisFailed audit and never advance the checkpoint. +- rule: A null returnValue records no audit, command, or approval side effects but still advances the checkpoint once. +- rule: Persistence for a decision runs loadOrCreate, audit, commands, approvals, then checkpoint update last. +- rule: A decision with a null command records audit and checkpoint but not command or approval. +- rule: Events at or below the checkpoint lastProcessedPosition are skipped. +- rule: The handler never throws; errors produce dead letters and log entries. + +## Example space + +```gwt-vocabulary +Given the module is imported from platform-core +And a handler with default config +And a handler with default config and fake timers at {timerAt:string} +And a handler with approvalTimeoutMs {approvalTimeoutMs:number} and fake timers at {timerAt:string} +And a handler with default config and a logger +And args with a canceled result +And args with a failed result with error {error:string} +And args with a success result with null returnValue +And args with a success result containing a decision with requiresApproval {requiresApproval:boolean} +And args with a success result and context agentId {agentId:string} subscriptionId {subscriptionId:string} eventId {eventId:string} globalPosition {globalPosition:number} +And args with a success result containing a decision with null command and requiresApproval {requiresApproval:boolean} +And args with a success result containing a no-command decision +And args with a success result and context globalPosition {globalPosition:number} +And args with a success result containing a standard decision +And args with a success result containing a decision with command and requiresApproval {requiresApproval:boolean} +And the checkpoint loadOrCreate returns lastProcessedPosition {lastProcessedPosition:number} +And the checkpoint loadOrCreate will throw {loadError:string} +And the audit record will throw {auditError:string} +And the commands record will throw {commandError:string} +And the approvals create will throw {approvalError:string} +And the dead letter record will throw {deadLetterError:string} +When the handler is invoked +Then runMutation is not called +And the dead letter is recorded with agentId {agentId:string} subscriptionId {subscriptionId:string} eventId {eventId:string} globalPosition {globalPosition:number} error {error:string} +And the dead letter is recorded with agentId {agentId:string} eventId {eventId:string} error {error:string} +And the audit is recorded with eventType {eventType:string} and agentId {agentId:string} +And the checkpoint update is not called +And the checkpoint loadOrCreate is not called +And the checkpoint loadOrCreate is called +And the checkpoint update is called +And the audit record is not called +And the commands record is not called +And the approvals create is not called +And the persistence order is loadOrCreate then audit then commands then approvals then checkpoint_update +And the checkpoint update is called with agentId {agentId:string} subscriptionId {subscriptionId:string} lastProcessedPosition {lastProcessedPosition:number} lastEventId {lastEventId:string} incrementEventsProcessed {incrementEventsProcessed:boolean} +And the approval expiresAt equals Date.now() plus {approvalTimeoutMs:number} ms +And the commands record is called +And the audit record is called +And the approvals create is called +And the handler resolves without throwing +And the logger error is called with message {logMessage:string} and agentId {agentId:string} and error {error:string} +And the logger error is called with message {logMessage:string} +And the logger error is called with message {logMessage:string} and agentId {agentId:string} and eventId {eventId:string} +And the dead letter context includes correlationId {correlationId:string} and errorCode {errorCode:string} +And the audit record includes a verification proof for agentId {agentId:string} +And the commands record includes a verification proof for agentId {agentId:string} +And the approvals create includes a verification proof for agentId {agentId:string} +``` diff --git a/specs/behavior/platform-core/agent/pattern-detection.sdp.md b/specs/behavior/platform-core/agent/pattern-detection.sdp.md new file mode 100644 index 00000000..a7c61511 --- /dev/null +++ b/specs/behavior/platform-core/agent/pattern-detection.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.agent.pattern-detection +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Agent Pattern Detection + +## Intent + +- actor: a platform developer +- outcome: Detect patterns across event streams using windowed triggers and optional LLM analysis so business insights can be generated automatically. +- value: Cheap rule-based triggers decide when optional LLM analysis should run. + +## Behavior + +- rule: Patterns are defined with window, trigger, and analysis logic. +- rule: Pattern window constrains event scope so events outside the window are not considered. +- rule: Trigger conditions activate pattern detection from event sequences. +- rule: Complex patterns use LLM analysis for insight, with a rule-based fallback on timeout. diff --git a/specs/behavior/platform-core/agent/pattern-executor.sdp.md b/specs/behavior/platform-core/agent/pattern-executor.sdp.md new file mode 100644 index 00000000..0f442863 --- /dev/null +++ b/specs/behavior/platform-core/agent/pattern-executor.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.agent.pattern-executor +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Pattern Executor + +## Intent + +- outcome: Iterate the agent's pattern array in priority order, call trigger then analyze, short-circuit on the first match, and return an execution summary. +- value: Trigger-only patterns produce rule-based decisions; analyze errors propagate so Workpool can retry. + +## Behavior + +- rule: Empty patterns array yields null matchedPattern, null decision, and rule-based method. +- rule: A pattern whose trigger returns true is matched rule-based; a false trigger is skipped. +- rule: Analyze detected yields an llm decision; not-detected falls through to the next pattern. +- rule: Errors from analyze propagate for Workpool retry. +- rule: After the first matching pattern, remaining patterns are never evaluated. +- rule: Patterns with false triggers are skipped and the next pattern is evaluated. +- rule: Patterns with minEvents greater than available events are skipped without calling trigger. +- rule: Events outside the pattern window duration are excluded before trigger evaluation. +- rule: Command type, payload, confidence, reason, and triggeringEvents are extracted from the analysis result. +- rule: Approval is required when confidence is below threshold or no command is present. +- rule: requiresApproval list forces approval; autoApprove list skips it; requiresApproval takes precedence. +- rule: Trigger-only decisions have null command, empty payload, always require approval, and include pattern name and event IDs. +- rule: Trigger-only confidence is min(0.85, 0.5 + eventCount * 0.1). diff --git a/specs/behavior/platform-core/agent/pattern-registry.sdp.md b/specs/behavior/platform-core/agent/pattern-registry.sdp.md new file mode 100644 index 00000000..7351007c --- /dev/null +++ b/specs/behavior/platform-core/agent/pattern-registry.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.agent.pattern-registry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Pattern Registry + +## Intent + +- outcome: Validate PatternDefinition arrays passed on AgentBCConfig.patterns, rejecting missing names, missing triggers, and duplicate names. +- value: A single agent can pass PatternDefinition[] directly without a global singleton registry. + +## Behavior + +- rule: PATTERN_REGISTRY_ERROR_CODES contains exactly four known error codes with values matching their keys. +- rule: Any array of well-formed patterns with unique names returns valid true. +- rule: An empty array has nothing to validate and returns valid true. +- rule: If two or more patterns share the same name, validation fails with DUPLICATE_PATTERN and mentions the offending name. +- rule: A pattern with an empty or whitespace-only name fails with PATTERN_NAME_REQUIRED. +- rule: A pattern without a trigger function, or with a non-function trigger, fails with TRIGGER_REQUIRED. +- rule: Pattern-level error codes map to their registry-level equivalents; unknown codes map to INVALID_PATTERN. +- rule: The function accepts readonly arrays and the error result conforms to the discriminated union shape. diff --git a/specs/behavior/platform-core/agent/patterns.sdp.md b/specs/behavior/platform-core/agent/patterns.sdp.md new file mode 100644 index 00000000..26ce1ef0 --- /dev/null +++ b/specs/behavior/platform-core/agent/patterns.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.platform-core.agent.patterns +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Pattern Detection Framework + +## Intent + +- outcome: Define, validate, and evaluate agent pattern windows and composable triggers as pure functions. +- value: Agents can detect patterns across event streams against a time and event window. + +## Behavior + +- rule: Error codes are defined as a complete enumeration +- rule: PatternWindowSchema validates window configuration via Zod +- rule: Duration parsing converts duration strings to milliseconds +- rule: isValidDuration checks format validity +- rule: Pattern definition validation catches invalid configurations +- rule: definePattern factory validates and returns definitions +- rule: Window boundary calculation subtracts parsed duration from now +- rule: Event filtering applies time window and optional event limit +- rule: hasMinimumEvents checks count against window minEvents +- rule: countThreshold trigger fires when event count meets threshold +- rule: eventTypePresent trigger checks for specific event types +- rule: multiStreamPresent trigger checks for events from distinct streams +- rule: PatternTriggers.all combines triggers with AND logic +- rule: PatternTriggers.any combines triggers with OR logic +- rule: Complex trigger combinations compose correctly diff --git a/specs/behavior/platform-core/agent/rate-limit.sdp.md b/specs/behavior/platform-core/agent/rate-limit.sdp.md new file mode 100644 index 00000000..6265b141 --- /dev/null +++ b/specs/behavior/platform-core/agent/rate-limit.sdp.md @@ -0,0 +1,31 @@ +--- +id: spec:behavior.platform-core.agent.rate-limit +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Rate Limit Module + +## Intent + +- outcome: Provide schemas, factories, type guards, exponential backoff, and budget helpers for LLM rate limiting. +- value: Agent configuration can be validated and retry decisions can be made from named error codes and a daily cost budget. + +## Behavior + +- rule: Error codes enumerate all rate-limit failure modes +- rule: CostBudgetSchema validates budget configuration +- rule: AgentRateLimitConfigSchema validates rate limit configuration +- rule: validateRateLimitConfig catches invalid configurations +- rule: createDefaultRateLimitConfig produces valid defaults +- rule: createRateLimitConfigWithBudget produces config with cost budget +- rule: createRateLimitError builds structured error objects +- rule: isRateLimitError identifies valid rate limit error objects +- rule: isRetryableError identifies transient errors eligible for retry +- rule: isPermanentError identifies non-retryable errors +- rule: calculateBackoffDelay computes exponential backoff with jitter +- rule: wouldExceedBudget checks if estimated cost would exceed daily budget +- rule: isAtAlertThreshold checks if spend ratio meets or exceeds alert threshold +- rule: getEffectiveRateLimitConfig merges provided config with defaults diff --git a/specs/behavior/platform-core/agent/thread-adapter.sdp.md b/specs/behavior/platform-core/agent/thread-adapter.sdp.md new file mode 100644 index 00000000..17b7d796 --- /dev/null +++ b/specs/behavior/platform-core/agent/thread-adapter.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.agent.thread-adapter +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Thread Adapter + +## Intent + +- outcome: Return an AgentInterface whose analyze and reason methods wrap an injected generateText callback, parse JSON responses, and record model, tokens, timing, and threadId in llmContext. +- value: platform-core stays free of the agent SDK because the application supplies generateText. + +## Behavior + +- rule: A valid JSON analyze response is parsed into structured patterns, confidence, reasoning, and llmContext. +- rule: Non-JSON or malformed analyze responses return empty patterns, zero confidence, and raw text as reasoning. +- rule: Errors from generateText propagate from analyze without being swallowed. +- rule: llmContext.durationMs reflects elapsed time during the generateText call. +- rule: threadId is included in llmContext only when present in the generateText result. +- rule: When usage is absent from the generateText result, tokens defaults to 0. +- rule: reason parses a valid JSON response and returns it as a structured object. +- rule: Non-JSON responses from generateText are returned as raw text from reason. +- rule: Errors from generateText propagate from reason without being swallowed. +- rule: reason logs debug on start and info on completion with agent and model metadata. diff --git a/specs/behavior/platform-core/batch/batch-executor.sdp.md b/specs/behavior/platform-core/batch/batch-executor.sdp.md new file mode 100644 index 00000000..bced1d25 --- /dev/null +++ b/specs/behavior/platform-core/batch/batch-executor.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.batch.batch-executor +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# BatchExecutor + +## Intent + +- actor: a platform developer +- outcome: Execute batch commands in atomic and partial modes so multiple commands are processed with the matching failure semantics. +- value: Atomic mode stops on first failure for a single aggregate; partial mode continues across aggregates and records per-command results, durations, and summary statistics. + +## Behavior + +- rule: Atomic mode executes commands sequentially and stops on first failure +- rule: Partial mode executes all commands regardless of individual failures +- rule: BatchExecutor tracks individual command results with type and index +- rule: BatchExecutor handles executor exceptions gracefully +- rule: Default bounded context filters commands to a single context +- rule: createBatchExecutor factory creates BatchExecutor instances diff --git a/specs/behavior/platform-core/batch/validation.sdp.md b/specs/behavior/platform-core/batch/validation.sdp.md new file mode 100644 index 00000000..596385d6 --- /dev/null +++ b/specs/behavior/platform-core/batch/validation.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.batch.validation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Batch Validation + +## Intent + +- actor: a platform developer +- outcome: Reject invalid batches in pre-flight validation before any command is processed. +- value: Commands are checked for emptiness, size, atomic single-aggregate scope, and bounded-context filters before execution begins. + +## Behavior + +- rule: Empty batches are always rejected +- rule: Partial mode accepts valid commands without cross-aggregate constraints +- rule: Atomic mode without registry requires explicit aggregate options +- rule: Atomic mode with registry enforces single-aggregate scope via metadata +- rule: Bounded context option filters commands to a single context +- rule: extractAggregateId extracts string IDs from command args +- rule: groupByAggregateId groups commands by their aggregate ID field diff --git a/specs/behavior/platform-core/cms/upcaster.sdp.md b/specs/behavior/platform-core/cms/upcaster.sdp.md new file mode 100644 index 00000000..b8991486 --- /dev/null +++ b/specs/behavior/platform-core/cms/upcaster.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.platform-core.cms.upcaster +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# CMS Upcaster Utilities + +## Intent + +- outcome: Provide chain-based CMS schema-evolution utilities so stored CMS state upgrades transparently to the latest schema version. +- value: createUpcaster, upcastIfNeeded, and field-helper migrations migrate documents without rewriting callers. + +## Behavior + +- rule: createUpcaster returns state at current version without migration +- rule: createUpcaster applies a single migration step +- rule: createUpcaster applies multiple migration steps in order +- rule: createUpcaster handles legacy version 0 state +- rule: createUpcaster rejects invalid inputs and configurations +- rule: upcastIfNeeded returns state at current version without migration +- rule: upcastIfNeeded applies migration when state is behind +- rule: upcastIfNeeded supports validation function +- rule: upcastIfNeeded rejects future state versions +- rule: CMSUpcasterError captures error metadata +- rule: createUpcaster supports post-migration validation +- rule: addCMSFieldMigration adds a field with a static or computed default +- rule: renameCMSFieldMigration renames a field in the CMS state +- rule: removeCMSFieldMigration removes a field from the CMS state +- rule: Helper migrations integrate with createUpcaster chain diff --git a/specs/behavior/platform-core/commands/categories.sdp.md b/specs/behavior/platform-core/commands/categories.sdp.md new file mode 100644 index 00000000..06af4aac --- /dev/null +++ b/specs/behavior/platform-core/commands/categories.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.commands.categories +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Category Utilities + +## Intent + +- outcome: Classify and validate command categories at runtime with type-safe taxonomy utilities. +- value: Commands stay correctly classified as aggregate, process, system, or batch. + +## Behavior + +- rule: COMMAND_CATEGORIES contains all four command categories in order +- rule: CommandCategorySchema validates category strings via Zod +- rule: Default command category provides a sensible fallback +- rule: isCommandCategory returns true only for valid category strings +- rule: normalizeCommandCategory returns the category unchanged or falls back to aggregate +- rule: isAggregateCommand returns true only for aggregate category +- rule: isProcessCommand returns true only for process category +- rule: isSystemCommand returns true only for system category +- rule: isBatchCommand returns true only for batch category +- rule: AggregateTargetSchema validates aggregate target objects diff --git a/specs/behavior/platform-core/commands/errors.sdp.md b/specs/behavior/platform-core/commands/errors.sdp.md new file mode 100644 index 00000000..768a990d --- /dev/null +++ b/specs/behavior/platform-core/commands/errors.sdp.md @@ -0,0 +1,40 @@ +--- +id: spec:behavior.platform-core.commands.errors +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Error Categorization and Recovery + +## Intent + +- outcome: Classify command failures with categorized, serializable errors and recovery semantics. +- value: Callers can decide retry delays from error category without inspecting ad-hoc exceptions. + +## Behavior + +- rule: ERROR_CATEGORIES contains all four error categories +- rule: ErrorCategory enum maps to correct string values +- rule: isErrorCategory returns true only for valid category strings +- rule: CommandError constructor creates error with all properties +- rule: CommandError extends Error +- rule: CommandError.from returns CommandError instances unchanged +- rule: CommandError.from wraps non-CommandError values as infrastructure errors +- rule: CommandError.toJSON serializes to a plain object +- rule: CommandErrors.domain creates non-recoverable domain errors +- rule: CommandErrors.validation creates non-recoverable validation errors +- rule: CommandErrors.concurrency creates recoverable concurrency errors +- rule: CommandErrors.infrastructure creates recoverable infrastructure errors +- rule: CommandErrors.notFound creates domain errors with formatted messages +- rule: CommandErrors.alreadyExists creates domain errors with formatted messages +- rule: CommandErrors.invalidState creates domain errors with state info +- rule: CommandErrors.unauthorized creates domain errors for denied actions +- rule: CommandErrors.rateLimited creates recoverable infrastructure errors with retry info +- rule: isCommandErrorOfCategory checks category membership +- rule: isRecoverableError checks recovery semantics +- rule: getRetryDelay returns -1 for non-recoverable errors +- rule: getRetryDelay computes quick backoff for concurrency errors capped at 500ms +- rule: getRetryDelay computes exponential backoff for infrastructure errors capped at 30s +- rule: getRetryDelay treats unknown errors like infrastructure errors diff --git a/specs/behavior/platform-core/commands/factories.sdp.md b/specs/behavior/platform-core/commands/factories.sdp.md new file mode 100644 index 00000000..f3f5a7a5 --- /dev/null +++ b/specs/behavior/platform-core/commands/factories.sdp.md @@ -0,0 +1,34 @@ +--- +id: spec:behavior.platform-core.commands.factories +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Category Factories + +## Intent + +- outcome: Build category-specific command schemas so each command carries the correct category, validated fields, and typed payload. +- value: Factories keep aggregate, process, system, and batch commands consistent at parse time. + +## Behavior + +- rule: createAggregateCommandSchema produces schemas with aggregate category and literal command type +- rule: createAggregateCommandSchema includes aggregate target when provided +- rule: createAggregateCommandSchema makes aggregate target optional when not configured +- rule: createAggregateCommandSchema enforces literal command type +- rule: createAggregateCommandSchema rejects commands missing required base fields +- rule: createProcessCommandSchema produces schemas with process category +- rule: createProcessCommandSchema includes process type when provided +- rule: createProcessCommandSchema makes process type optional when not configured +- rule: createSystemCommandSchema produces schemas with system category +- rule: createSystemCommandSchema defaults requiresIdempotency to false +- rule: createSystemCommandSchema allows overriding requiresIdempotency +- rule: createBatchCommandSchema produces schemas with batch category and items array +- rule: createBatchCommandSchema includes batch config when provided +- rule: createBatchCommandSchema validates items against item schema +- rule: createBatchCommandSchema allows empty items array +- rule: getCommandCategoryFromSchema extracts category from factory-created schemas +- rule: getCommandCategoryFromSchema returns undefined for non-command schemas diff --git a/specs/behavior/platform-core/commands/naming.sdp.md b/specs/behavior/platform-core/commands/naming.sdp.md new file mode 100644 index 00000000..184d70c5 --- /dev/null +++ b/specs/behavior/platform-core/commands/naming.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.commands.naming +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Naming Policy + +## Intent + +- outcome: Enforce Verb+Noun PascalCase command naming at runtime across bounded contexts. +- value: Invalid names produce structured validation results and corrective suggestions. + +## Behavior + +- rule: COMMAND_NAME_PREFIXES contains all recognized verb prefixes +- rule: CREATE pattern matches PascalCase names starting with Create +- rule: ADD pattern matches PascalCase names starting with Add +- rule: UPDATE pattern matches names starting with Update, Change, or Modify +- rule: isValidCommandName returns true only for names matching any recognized prefix pattern +- rule: validateCommandName returns structured validation results with matched prefix +- rule: generateNameSuggestions produces corrective suggestions for invalid names +- rule: getCommandPrefix extracts the matched prefix or returns undefined +- rule: formatCommandName converts various input formats to valid PascalCase command names diff --git a/specs/behavior/platform-core/correlation/chain.sdp.md b/specs/behavior/platform-core/correlation/chain.sdp.md new file mode 100644 index 00000000..c090ab7a --- /dev/null +++ b/specs/behavior/platform-core/correlation/chain.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.correlation.chain +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Correlation Chain - Chain Creation, Derivation, and Relationship Checks + +## Intent + +- outcome: Create, derive, and inspect correlation chains so causation can be traced through command-event flows. +- value: Request-scoped correlationId and causationId survive saga reactions and metadata extraction. + +## Behavior + +- rule: createCorrelationChain with only commandId sets defaults +- rule: createCorrelationChain with options uses provided values +- rule: deriveCorrelationChain basic derivation preserves correlation and sets causation +- rule: deriveCorrelationChain merges context from source and options +- rule: deriveCorrelationChain with options uses provided overrides +- rule: toEventMetadata extracts correlationId and causationId from chain +- rule: isCorrelated compares correlationIds of two chains +- rule: isCausedBy checks if child causationId matches parent commandId +- rule: Correlation chains trace full request flows across command-event boundaries diff --git a/specs/behavior/platform-core/correlation/correlation-service.sdp.md b/specs/behavior/platform-core/correlation/correlation-service.sdp.md new file mode 100644 index 00000000..68fd6c56 --- /dev/null +++ b/specs/behavior/platform-core/correlation/correlation-service.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.platform-core.correlation.correlation-service +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# CorrelationService - Command-Event Correlation Tracking + +## Intent + +- outcome: Track command-to-event relationships so callers can trace which events resulted from which commands. +- value: The service records, merges, queries, and counts correlations by command and bounded context. + +## Behavior + +- rule: recordCorrelation persists a new command-event correlation +- rule: recordCorrelation merges event IDs for duplicate command IDs +- rule: getEventsByCommand returns null for non-existent commands +- rule: getEventsByCommand returns the full correlation for existing commands +- rule: getCorrelationsByContext filters correlations by bounded context +- rule: getCorrelationsByContext throws when boundedContext is missing +- rule: getCorrelationsByContext respects the limit parameter +- rule: hasCorrelation returns true when a correlation exists for the command +- rule: hasCorrelation returns false for non-existent commands +- rule: getEventCount returns the number of events for an existing command +- rule: getEventCount returns 0 for non-existent commands +- rule: createCorrelationService returns a CorrelationService instance diff --git a/specs/behavior/platform-core/dcb/execute.sdp.md b/specs/behavior/platform-core/dcb/execute.sdp.md new file mode 100644 index 00000000..d5ebc417 --- /dev/null +++ b/specs/behavior/platform-core/dcb/execute.sdp.md @@ -0,0 +1,52 @@ +--- +id: spec:behavior.platform-core.dcb.execute +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# DCB Execution with OCC + +## Intent + +- actor: a platform developer +- outcome: executeWithDCB enforces scope-level OCC so cross-entity invariants are protected from concurrent modifications. +- value: Cross-entity invariants stay protected when multiple entities change in one scope. + +## Example space + +```gwt-vocabulary +Given a mock mutation context +And a scope key {scopeKey:string} +And entities with streamIds {streamId1:string} and {streamId2:string} +And a decider that succeeds with event type {eventType:string} +And no scopeOperations are provided +And schemaVersion is {schemaVersion:number} +And eventCategory is {eventCategory:string} +And a decider that rejects with code {rejectionCode:string} and message {rejectionMessage:string} +And a decider that fails with event type {eventType:string} and reason {failureReason:string} +And scopeOperations that return scope with currentVersion {currentVersion:number} +And expectedVersion is {expectedVersion:number} +And a decider that succeeds +And scopeOperations commitScope succeeds with newVersion {newVersion:number} +And scopeOperations that return null scope +And scopeOperations commitScope returns conflict with currentVersion {conflictVersion:number} +And a decider that succeeds with updates to {streamId1:string} and {streamId2:string} +And scopeOperations commitScope is called +And an invalid scope key {invalidScopeKey:string} +And entities where {existingStreamId:string} exists but {missingStreamId:string} does not +When I execute the DCB operation +Then the result status is {status:"success"|"rejected"|"failed"|"conflict"} +And the result contains event type {eventType:string} +And the result scopeVersion is {scopeVersion:number} +And the generated event has schemaVersion {schemaVersion:number} +And the generated event has category {eventCategory:string} +And the rejection code is {rejectionCode:string} +And the rejection reason is {rejectionReason:string} +And the failure reason is {failureReason:string} +And the conflict currentVersion is {conflictVersion:number} +And commitScope was called with streamIds {streamId1:string} and {streamId2:string} +And the rejection code contains {rejectionCodePart:string} +And the rejection reason contains {missingStreamId:string} +``` diff --git a/specs/behavior/platform-core/dcb/scope-key.sdp.md b/specs/behavior/platform-core/dcb/scope-key.sdp.md new file mode 100644 index 00000000..c84533c4 --- /dev/null +++ b/specs/behavior/platform-core/dcb/scope-key.sdp.md @@ -0,0 +1,16 @@ +--- +id: spec:behavior.platform-core.dcb.scope-key +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# DCB Scope Key Utilities + +## Intent + +- actor: a platform developer +- outcome: Standardized scope-key creation and parsing utilities keep DCB operations tenant-isolated. +- value: Tenant isolation can be checked from a single scope-key format. + diff --git a/specs/behavior/platform-core/decider/factory.sdp.md b/specs/behavior/platform-core/decider/factory.sdp.md new file mode 100644 index 00000000..44b16dbb --- /dev/null +++ b/specs/behavior/platform-core/decider/factory.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.decider.factory +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Decider Handler Factory + +## Intent + +- outcome: Factory functions wrap pure decider functions with load, persist, and event building for existing-entity updates and entity creation. +- value: Handlers can apply existing-entity updates and create new entities without embedding infrastructure in the decider. + +## Behavior + +- rule: createDeciderHandler success path loads state, calls decider, applies update, and returns success +- rule: createDeciderHandler rejected path returns rejection without applying update +- rule: createDeciderHandler failed path returns failure with event without applying update +- rule: createDeciderHandler error handling propagates or delegates errors +- rule: createDeciderHandler logging emits debug and error messages +- rule: createDeciderHandler event metadata generates unique IDs and correct fields +- rule: createEntityDeciderHandler entity creation calls tryLoadState and insert for new entities +- rule: createEntityDeciderHandler entity already exists returns rejection +- rule: createEntityDeciderHandler failed path returns failure without insert +- rule: createEntityDeciderHandler error handling propagates or delegates errors +- rule: createEntityDeciderHandler logging emits debug messages +- rule: createEntityDeciderHandler event metadata for entity creation +- rule: createEntityDeciderHandler preValidate hook short-circuits before loading state diff --git a/specs/behavior/platform-core/durable-function-adapters/dcb-conflict-retry.sdp.md b/specs/behavior/platform-core/durable-function-adapters/dcb-conflict-retry.sdp.md new file mode 100644 index 00000000..f326fe8b --- /dev/null +++ b/specs/behavior/platform-core/durable-function-adapters/dcb-conflict-retry.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.durable-function-adapters.dcb-conflict-retry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# DCB Conflict Retry + +## Intent + +- actor: a platform developer +- outcome: DCB OCC conflicts are automatically retried so callers do not implement manual retry logic everywhere. +- value: Workpool-based retry with exponential backoff and jitter covers OCC conflicts. + +## Behavior + +- rule: DCB operations succeed without retry when no conflict +- rule: OCC conflicts trigger automatic retry scheduling via Workpool +- rule: Backoff uses exponential increase with jitter diff --git a/specs/behavior/platform-core/durable-function-adapters/integration-patterns.sdp.md b/specs/behavior/platform-core/durable-function-adapters/integration-patterns.sdp.md new file mode 100644 index 00000000..8e959642 --- /dev/null +++ b/specs/behavior/platform-core/durable-function-adapters/integration-patterns.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.durable-function-adapters.integration-patterns +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Adapter Integration Patterns + +## Intent + +- actor: a platform developer +- outcome: Adapters integrate with existing middleware, Workpool, and Convex components so production patterns can be adopted without refactoring. +- value: Rate limiting and DCB retry plug into current infrastructure without changing caller code. + +## Behavior + +- rule: Rate limit adapter integrates with middleware pipeline +- rule: DCB retry integrates with Workpool infrastructure +- rule: Convex components mount correctly diff --git a/specs/behavior/platform-core/durable-function-adapters/rate-limit-adapter.sdp.md b/specs/behavior/platform-core/durable-function-adapters/rate-limit-adapter.sdp.md new file mode 100644 index 00000000..a70d2914 --- /dev/null +++ b/specs/behavior/platform-core/durable-function-adapters/rate-limit-adapter.sdp.md @@ -0,0 +1,33 @@ +--- +id: spec:behavior.platform-core.durable-function-adapters.rate-limit-adapter +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Rate Limit Adapter + +## Intent + +- actor: a platform developer +- outcome: The middleware rate limiter uses @convex-dev/rate-limiter so rate limiting is production-grade with persistence and sharding. +- value: Rate limits persist across restarts and stay isolated by key. + +## Behavior + +- rule: Adapter implements RateLimitChecker interface +- rule: Rate limits are isolated by key + +## Example space + +```gwt-vocabulary +Given rate limit {limitName:string} is configured with {requestsPerMinute:number} requests per minute +And {requestCount:number} requests have been made for key {key:string} +And user {user:string} has exhausted her rate limit +And user {user:string} has exhausted limit for {commandType:string} +When checking rate limit for key {key:string} +Then the result should have allowed = {allowed:boolean} +And retryAfterMs should be undefined +And retryAfterMs should be greater than 0 +``` diff --git a/specs/behavior/platform-core/ecst/fat-event-builder.sdp.md b/specs/behavior/platform-core/ecst/fat-event-builder.sdp.md new file mode 100644 index 00000000..10509802 --- /dev/null +++ b/specs/behavior/platform-core/ecst/fat-event-builder.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.ecst.fat-event-builder +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Fat Event Builder + +## Intent + +- actor: a platform developer +- outcome: Create fat events with embedded context so downstream consumers have all data needed without back-queries. +- value: createFatEvent, embedEntity, and embedCollection snapshot entity and collection state for Event-Carried State Transfer. + +## Behavior + +- rule: createFatEvent() creates properly structured fat events +- rule: embedEntity() snapshots entity fields into event +- rule: embedCollection() snapshots related collections diff --git a/specs/behavior/platform-core/ecst/fat-vs-thin-selection.sdp.md b/specs/behavior/platform-core/ecst/fat-vs-thin-selection.sdp.md new file mode 100644 index 00000000..0f0da05e --- /dev/null +++ b/specs/behavior/platform-core/ecst/fat-vs-thin-selection.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.ecst.fat-vs-thin-selection +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Fat vs Thin Event Selection + +## Intent + +- actor: a platform developer +- outcome: Choose fat or thin events so payload size and consumer independence are traded off appropriately. +- value: Cross-context and Published Language contracts carry full snapshots; high-frequency same-context events stay thin. + +## Behavior + +- rule: Cross-context integration should use fat events +- rule: High-frequency internal events should prefer thin events +- rule: Published Language contracts require fat events +- rule: Event category can indicate fat/thin preference diff --git a/specs/behavior/platform-core/ecst/privacy-markers.sdp.md b/specs/behavior/platform-core/ecst/privacy-markers.sdp.md new file mode 100644 index 00000000..2b459950 --- /dev/null +++ b/specs/behavior/platform-core/ecst/privacy-markers.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.ecst.privacy-markers +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Privacy Markers (Crypto-Shredding) + +## Intent + +- actor: a platform developer +- outcome: Mark PII fields in fat events for crypto-shredding so GDPR right-to-erasure requests can be handled. +- value: Shred markers identify personal data that can later be replaced with RedactedValue without rewriting history. + +## Behavior + +- rule: PII fields can be marked for crypto-shredding +- rule: Shred markers can be detected in fat events +- rule: Collections can have per-item privacy markers +- rule: Marked fields can be shredded (replaced with RedactedValue) +- rule: Utility functions for shreddable field detection +- rule: Required fields cannot be marked for shredding diff --git a/specs/behavior/platform-core/ecst/schema-versioning.sdp.md b/specs/behavior/platform-core/ecst/schema-versioning.sdp.md new file mode 100644 index 00000000..a5e20b59 --- /dev/null +++ b/specs/behavior/platform-core/ecst/schema-versioning.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.ecst.schema-versioning +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Schema Versioning + +## Intent + +- actor: a platform developer +- outcome: Include schema version information on fat events so consumers can upcast events from older versions. +- value: Validation and migrateEvent keep older payloads readable against the current schema. + +## Behavior + +- rule: Fat events must include schema version +- rule: Fat events are validated against their schema +- rule: Older events can be migrated to newer schema versions +- rule: Version comparison utility works correctly +- rule: needsMigration() detects when migration is required diff --git a/specs/behavior/platform-core/event-replay/replay-progress.sdp.md b/specs/behavior/platform-core/event-replay/replay-progress.sdp.md new file mode 100644 index 00000000..c0b48b4f --- /dev/null +++ b/specs/behavior/platform-core/event-replay/replay-progress.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-replay.replay-progress +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Replay Progress Calculator + +## Intent + +- outcome: Calculate replay percent complete, remaining time, and active or terminal status from checkpoint counts. +- value: Operators can turn replay checkpoint state into dashboard progress without inventing a second calculator. diff --git a/specs/behavior/platform-core/event-store-durability/durable-append.sdp.md b/specs/behavior/platform-core/event-store-durability/durable-append.sdp.md new file mode 100644 index 00000000..b6997c2a --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/durable-append.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.durable-append +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Durable Event Append + +## Intent + +- outcome: Wrap event append in Workpool for automatic retry with exponential backoff so failed async appends are recovered via Workpool actions. +- value: Partition keys, durableAppendEvent, and the action handler keep append retries out of the caller path. diff --git a/specs/behavior/platform-core/event-store-durability/durable-publication.sdp.md b/specs/behavior/platform-core/event-store-durability/durable-publication.sdp.md new file mode 100644 index 00000000..957afeca --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/durable-publication.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.durable-publication +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Durable Cross-Context Event Publication + +## Intent + +- outcome: Publish cross-context events through Workpool-backed delivery with tracking, retry, and dead-letter handling. +- value: Each target context gets a publication record and a retryable delivery action instead of a fire-and-forget emit. diff --git a/specs/behavior/platform-core/event-store-durability/idempotent-append.sdp.md b/specs/behavior/platform-core/event-store-durability/idempotent-append.sdp.md new file mode 100644 index 00000000..6e77418f --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/idempotent-append.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.idempotent-append +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Idempotent Event Append + +## Intent + +- outcome: Append each event only once even when the append operation is retried so duplicate events cannot corrupt projections or double-process downstream. +- value: Command, action, saga-step, and scheduled-job key builders feed one idempotentAppendEvent path that returns appended, duplicate, or conflict. diff --git a/specs/behavior/platform-core/event-store-durability/intent-completion.sdp.md b/specs/behavior/platform-core/event-store-durability/intent-completion.sdp.md new file mode 100644 index 00000000..8f4dabf7 --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/intent-completion.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.intent-completion +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Intent and Completion Bracketing + +## Intent + +- outcome: Record intent before long-running operations and completion after success or failure so timeout detection, reconciliation, and audit remain possible. +- value: Intent keys, timeout checks, and orphaned-intent queries bracket multi-step work without inventing a second ledger. diff --git a/specs/behavior/platform-core/event-store-durability/outbox-handler.sdp.md b/specs/behavior/platform-core/event-store-durability/outbox-handler.sdp.md new file mode 100644 index 00000000..b223a7b5 --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/outbox-handler.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.outbox-handler +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Outbox Handler Pattern + +## Intent + +- outcome: Capture action results as domain events through durable onComplete handlers so external API success and failure are recorded with idempotent append. +- value: PaymentCompleted and PaymentFailed events reuse the same idempotency key so duplicate outbox deliveries stay safe. diff --git a/specs/behavior/platform-core/event-store-durability/poison-event.sdp.md b/specs/behavior/platform-core/event-store-durability/poison-event.sdp.md new file mode 100644 index 00000000..277f80f8 --- /dev/null +++ b/specs/behavior/platform-core/event-store-durability/poison-event.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-core.event-store-durability.poison-event +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Poison Event Handling + +## Intent + +- outcome: Quarantine events that repeatedly fail projection processing after N failures so infinite retry loops cannot stall a projection. +- value: Query, unquarantine, and stats helpers expose quarantined records without re-running the failing handler. diff --git a/specs/behavior/platform-core/eventbus/convex-event-bus.sdp.md b/specs/behavior/platform-core/eventbus/convex-event-bus.sdp.md new file mode 100644 index 00000000..e216635f --- /dev/null +++ b/specs/behavior/platform-core/eventbus/convex-event-bus.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.platform-core.eventbus.convex-event-bus +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# ConvexEventBus + +## Intent + +- actor: a platform developer +- outcome: Route published events to matching subscription handlers via workpool so event-driven communication stays decoupled and reliable. +- value: Priority-ordered enqueue, wildcard matching, and workpool error propagation keep delivery on one bus. + +## Behavior + +- rule: Constructor creates bus with subscriptions sorted by priority +- rule: publish() matches events to subscriptions and enqueues via workpool +- rule: publish() passes transformed args and partition context to workpool +- rule: publish() resolves onComplete from subscription or config default +- rule: hasSubscribersFor() checks event type and wildcard subscriptions +- rule: getAllSubscriptions() returns all registered subscriptions +- rule: getMatchingSubscriptions() filters subscriptions by criteria +- rule: publish() triggers subscriptions in priority order +- rule: publish() propagates workpool errors +- rule: Wildcard subscriptions match events regardless of type +- rule: createEventBus factory creates ConvexEventBus instances diff --git a/specs/behavior/platform-core/eventbus/registry.sdp.md b/specs/behavior/platform-core/eventbus/registry.sdp.md new file mode 100644 index 00000000..77b50ccb --- /dev/null +++ b/specs/behavior/platform-core/eventbus/registry.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.eventbus.registry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# EventBus Registry + +## Intent + +- actor: a platform developer +- outcome: Configure event handlers through a subscription registry with a builder API so handlers match events declaratively. +- value: Combined filters use AND between filter types and OR within each list, and duplicate names are rejected. + +## Behavior + +- rule: SubscriptionBuilder creates subscriptions with sensible defaults +- rule: SubscriptionBuilder fluent API configures event filters +- rule: SubscriptionBuilder configures handler options +- rule: SubscriptionRegistry collects subscriptions and rejects duplicates +- rule: defineSubscriptions helper creates subscription arrays from a configuration callback +- rule: createSubscription creates a standalone builder +- rule: An empty filter matches any event +- rule: matchesEvent filters by eventTypes using OR within the list +- rule: matchesEvent filters by categories using OR within the list +- rule: matchesEvent filters by boundedContexts using OR within the list +- rule: matchesEvent filters by streamTypes using OR within the list +- rule: Combined filters use AND logic between filter types diff --git a/specs/behavior/platform-core/events/builder.sdp.md b/specs/behavior/platform-core/events/builder.sdp.md new file mode 100644 index 00000000..811c7199 --- /dev/null +++ b/specs/behavior/platform-core/events/builder.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.platform-core.events.builder +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Event Data Builder Utilities + +## Intent + +- actor: a platform developer +- outcome: Build event data structures so events are correctly formatted for Event Store persistence. +- value: createEventData generates an eventId; createEventDataWithId uses a pre-generated id and infers boundedContext. + +## Behavior + +- rule: createEventData generates a complete NewEventData with auto-generated eventId +- rule: createEventDataWithId uses a pre-generated eventId and infers boundedContext diff --git a/specs/behavior/platform-core/events/category.sdp.md b/specs/behavior/platform-core/events/category.sdp.md new file mode 100644 index 00000000..97d6a423 --- /dev/null +++ b/specs/behavior/platform-core/events/category.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.events.category +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Event Category Utilities + +## Intent + +- actor: a platform developer +- outcome: Classify events with type-safe category utilities so events are validated at runtime as domain, integration, trigger, or fat. +- value: Type guards and normalizers fall back to domain and schema version 1 instead of accepting unknown labels. + +## Behavior + +- rule: EVENT_CATEGORIES contains all four event categories in order +- rule: EventCategorySchema validates category strings via Zod +- rule: Default constants provide sensible fallbacks +- rule: isEventCategory returns true only for valid category strings +- rule: normalizeCategory returns the category unchanged or falls back to domain +- rule: normalizeSchemaVersion returns valid positive integers or falls back to 1 +- rule: isExternalCategory identifies trigger and fat as external +- rule: isCrossContextCategory identifies integration as cross-context diff --git a/specs/behavior/platform-core/events/schemas.sdp.md b/specs/behavior/platform-core/events/schemas.sdp.md new file mode 100644 index 00000000..ad6e343a --- /dev/null +++ b/specs/behavior/platform-core/events/schemas.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.events.schemas +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Event Schema Factories + +## Intent + +- actor: a platform developer +- outcome: Produce typed Zod event schemas so events are validated at runtime with the correct eventType, category, and payload. +- value: Domain, integration, trigger, and fat factories share metadata rules while each category keeps its own default. + +## Behavior + +- rule: EventMetadataSchema validates required event metadata fields +- rule: EnhancedEventMetadataSchema extends metadata with category and schemaVersion +- rule: createEventSchema creates schemas with literal eventType and typed payload +- rule: createDomainEventSchema creates schemas with category domain +- rule: createIntegrationEventSchema creates schemas with category integration +- rule: createTriggerEventSchema creates schemas with category trigger and minimal payload +- rule: createFatEventSchema creates schemas with category fat and full payload +- rule: DomainEventSchema and EnhancedDomainEventSchema accept any payload diff --git a/specs/behavior/platform-core/events/upcaster.sdp.md b/specs/behavior/platform-core/events/upcaster.sdp.md new file mode 100644 index 00000000..fe08a1b8 --- /dev/null +++ b/specs/behavior/platform-core/events/upcaster.sdp.md @@ -0,0 +1,29 @@ +--- +id: spec:behavior.platform-core.events.upcaster +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Event Upcaster Utilities + +## Intent + +- actor: a platform developer +- outcome: Evolve event schemas with chain-based migration so events can be upgraded to the latest schema version transparently. +- value: createEventUpcaster, the registry, and field migrations keep historical payloads on the current schema without rewriting the store. + +## Behavior + +- rule: createEventUpcaster returns events at current version without migration +- rule: createEventUpcaster applies a single migration step +- rule: createEventUpcaster applies multiple migration steps in order +- rule: createEventUpcaster rejects invalid configurations and future versions +- rule: createEventUpcaster supports post-migration validation +- rule: createUpcasterRegistry tracks upcasters by event type +- rule: createUpcasterRegistry overwrites previously registered upcasters +- rule: createUpcasterRegistry upcasts events using the correct registered upcaster +- rule: addFieldMigration adds a field with a static or computed default +- rule: renameFieldMigration renames a field in the payload +- rule: EventUpcasterError captures error metadata diff --git a/specs/behavior/platform-core/fsm/fsm.sdp.md b/specs/behavior/platform-core/fsm/fsm.sdp.md new file mode 100644 index 00000000..c3b7b6c6 --- /dev/null +++ b/specs/behavior/platform-core/fsm/fsm.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.fsm.fsm +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# FSM Core + +## Intent + +- actor: a platform developer +- outcome: Provide a typed finite state machine with transition validation so that domain state changes are always checked and auditable. +- value: Domain workflows declare allowed paths; invalid transitions fail with FSMTransitionError rather than silent wrong states. + +## Behavior + +- rule: defineFSM creates an FSM with correct initial state and definition +- rule: canTransition returns true only for transitions defined in the FSM +- rule: assertTransition throws FSMTransitionError for invalid transitions +- rule: validTransitions returns the list of allowed target states +- rule: isTerminal identifies states with no outgoing transitions +- rule: isValidState returns true only for states defined in the FSM +- rule: FSMTransitionError has correct error properties diff --git a/specs/behavior/platform-core/handlers/result.sdp.md b/specs/behavior/platform-core/handlers/result.sdp.md new file mode 100644 index 00000000..314984ea --- /dev/null +++ b/specs/behavior/platform-core/handlers/result.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:behavior.platform-core.handlers.result +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Handler Result Helpers + +## Intent + +- outcome: Create typed dual-write command-handler results for success with event data, rejection without events, and failure that still emits an event. +- value: Command handlers can return status, data, and optional event payloads without assembling the result objects by hand. + +## Behavior + +- rule: successResult creates a success result with status, data, version, and event +- rule: rejectedResult creates a rejection result with code, reason, and optional context +- rule: failedResult creates a failure result with event data and optional fields diff --git a/specs/behavior/platform-core/ids/branded.sdp.md b/specs/behavior/platform-core/ids/branded.sdp.md new file mode 100644 index 00000000..73f4c0af --- /dev/null +++ b/specs/behavior/platform-core/ids/branded.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.ids.branded +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Branded ID Types + +## Intent + +- actor: a platform developer +- outcome: Provide branded ID types that give compile-time safety so different ID kinds cannot be accidentally interchanged. +- value: Branded types stay nominally distinct at the type level while remaining plain strings at runtime with zero overhead. + +## Behavior + +- rule: Factory functions create branded IDs from raw strings +- rule: Branded IDs remain fully compatible with string operations +- rule: ID generators produce correctly branded and prefixed IDs +- rule: isValidIdString validates and narrows unknown values to strings +- rule: ID generators produce unique values across repeated calls diff --git a/specs/behavior/platform-core/ids/generator.sdp.md b/specs/behavior/platform-core/ids/generator.sdp.md new file mode 100644 index 00000000..b6e3df99 --- /dev/null +++ b/specs/behavior/platform-core/ids/generator.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.ids.generator +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# ID Generation Utilities + +## Intent + +- actor: a platform developer +- outcome: Generate prefixed IDs with validation so IDs follow a consistent format across bounded contexts. +- value: Pure functions generate and parse generateId, parseId, generateCorrelationId, generateCommandId, generateEventId, and generateIntegrationEventId. + +## Behavior + +- rule: generateId produces IDs in context_type_uuid format +- rule: generateId rejects invalid context and type values +- rule: parseId decomposes valid IDs into context, type, and uuid +- rule: parseId returns null for malformed IDs +- rule: generateCorrelationId produces corr_-prefixed unique IDs +- rule: generateCommandId produces cmd_-prefixed unique IDs +- rule: generateEventId produces context-prefixed event IDs +- rule: generateIntegrationEventId produces int_evt_-prefixed unique IDs +- rule: Generated UUIDs conform to UUID v7 and are time-ordered diff --git a/specs/behavior/platform-core/integration/anti-corruption-layer.sdp.md b/specs/behavior/platform-core/integration/anti-corruption-layer.sdp.md new file mode 100644 index 00000000..2e17aa57 --- /dev/null +++ b/specs/behavior/platform-core/integration/anti-corruption-layer.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.integration.anti-corruption-layer +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Anti-Corruption Layer (ACL) + +## Intent + +- actor: a platform developer +- outcome: Translate external models through ACL utilities so domain code stays clean of foreign concepts. +- value: Each external system gets its own ACL with field mapping, value conversion, and validation. + +## Behavior + +- rule: ACL defines translation interface +- rule: ACL supports bidirectional translation +- rule: ACL validates external input +- rule: Different ACLs for different external systems diff --git a/specs/behavior/platform-core/integration/context-map.sdp.md b/specs/behavior/platform-core/integration/context-map.sdp.md new file mode 100644 index 00000000..aef47c72 --- /dev/null +++ b/specs/behavior/platform-core/integration/context-map.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.integration.context-map +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Context Map Documentation + +## Intent + +- actor: a platform developer +- outcome: Document bounded-context relationships in a Context Map so integration points stay explicit and maintainable. +- value: DDD relationship types, topology queries, and consistency checks keep the map valid. + +## Behavior + +- rule: Context Map supports DDD relationship types +- rule: Context Map enables topology queries +- rule: Context Map validates relationship consistency diff --git a/specs/behavior/platform-core/integration/contract-testing.sdp.md b/specs/behavior/platform-core/integration/contract-testing.sdp.md new file mode 100644 index 00000000..08294283 --- /dev/null +++ b/specs/behavior/platform-core/integration/contract-testing.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.integration.contract-testing +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Contract Testing Utilities + +## Intent + +- actor: a platform developer +- outcome: Test producer-consumer compatibility of integration events with generated samples and recorded violations. +- value: Sample generation, producer tests, consumer tests, and compatibility checks catch schema drift early. + +## Behavior + +- rule: Generate valid contract samples +- rule: Validate producer emits valid events +- rule: Validate consumer handles valid events +- rule: Detect producer-consumer mismatches +- rule: Contract violations are detected and recorded diff --git a/specs/behavior/platform-core/integration/event-versioning.sdp.md b/specs/behavior/platform-core/integration/event-versioning.sdp.md new file mode 100644 index 00000000..946b42db --- /dev/null +++ b/specs/behavior/platform-core/integration/event-versioning.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.integration.event-versioning +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Integration Event Versioning + +## Intent + +- actor: a platform developer +- outcome: Evolve integration event schemas so old consumers keep working when schemas change. +- value: Upcasters, downcasters, registered migrations, and version detection keep historical events loadable. + +## Behavior + +- rule: Upcasters migrate old schemas to new +- rule: Downcasters support old consumers +- rule: Migrations are registered with schema versions +- rule: Event version is detected automatically diff --git a/specs/behavior/platform-core/integration/integration-event-publisher.sdp.md b/specs/behavior/platform-core/integration/integration-event-publisher.sdp.md new file mode 100644 index 00000000..508c033d --- /dev/null +++ b/specs/behavior/platform-core/integration/integration-event-publisher.sdp.md @@ -0,0 +1,38 @@ +--- +id: spec:behavior.platform-core.integration.integration-event-publisher +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# IntegrationEventPublisher - Cross-Context Event Translation and Routing + +## Intent + +- actor: a platform developer +- outcome: Translate domain events into integration events and route them so bounded contexts communicate through published-language contracts. +- value: Unique source routes, correlation metadata, and workpool enqueue keep translation and delivery explicit. + +## Behavior + +- rule: Constructor accepts an empty or populated route list +- rule: Constructor rejects duplicate source event type routes +- rule: hasRouteFor returns true for registered and false for unregistered event types +- rule: getRoutes returns all registered routes +- rule: Publish returns null for unmatched source event types +- rule: Publish translates domain events to integration events +- rule: Publish enqueues all handlers for a matched route +- rule: Integration event includes correct metadata from source event and correlation chain +- rule: Publish propagates userId from the correlation chain when present +- rule: Publish includes onComplete callback in workpool options when configured +- rule: Publish propagates translator errors to the caller +- rule: Publish includes integration context in workpool options +- rule: IntegrationRouteBuilder builds routes with all required fields via fluent API +- rule: IntegrationRouteBuilder version method sets schema version +- rule: IntegrationRouteBuilder notify accepts multiple handlers +- rule: IntegrationRouteBuilder translate sets the translator function +- rule: IntegrationRouteBuilder build rejects incomplete configurations +- rule: defineIntegrationRoute returns a builder for fluent route construction +- rule: createIntegrationPublisher creates a functional publisher instance +- rule: IntegrationRouteError has correct name, code, context, and is instanceof Error diff --git a/specs/behavior/platform-core/integration/published-language.sdp.md b/specs/behavior/platform-core/integration/published-language.sdp.md new file mode 100644 index 00000000..ee21c969 --- /dev/null +++ b/specs/behavior/platform-core/integration/published-language.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.integration.published-language +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Published Language Registry + +## Intent + +- actor: a platform developer +- outcome: Register versioned integration event schemas so cross-BC communication has stable contracts. +- value: toPublishedLanguage converts domain events, and the registry answers schema and version queries. + +## Behavior + +- rule: Schemas are registered with versions +- rule: toPublishedLanguage() converts domain events +- rule: Registry supports schema queries diff --git a/specs/behavior/platform-core/invariants/create-invariant-set.sdp.md b/specs/behavior/platform-core/invariants/create-invariant-set.sdp.md new file mode 100644 index 00000000..e1e3ee2a --- /dev/null +++ b/specs/behavior/platform-core/invariants/create-invariant-set.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.invariants.create-invariant-set +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# createInvariantSet + +## Intent + +- actor: a domain developer +- outcome: Group invariants into a set and validate them together so multiple domain rules can be checked, asserted, or validated in one call. +- value: checkAll, assertAll, and validateAll share the same invariant list while keeping fail-fast versus collect-all semantics. + +## Behavior + +- rule: createInvariantSet creates a set with all invariants accessible and immutable +- rule: checkAll returns true when all invariants pass and false when any fail +- rule: assertAll does not throw when all pass and throws on first failure with fail-fast +- rule: validateAll collects all violations without short-circuiting +- rule: Empty invariant set always passes all operations +- rule: Single invariant set works correctly diff --git a/specs/behavior/platform-core/invariants/create-invariant.sdp.md b/specs/behavior/platform-core/invariants/create-invariant.sdp.md new file mode 100644 index 00000000..88786076 --- /dev/null +++ b/specs/behavior/platform-core/invariants/create-invariant.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.invariants.create-invariant +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# createInvariant + +## Intent + +- actor: a domain developer +- outcome: Create invariants from a specification so domain rules are reusable, composable, and produce structured violations. +- value: check, assert, and validate share one predicate while remaining independently callable. + +## Behavior + +- rule: createInvariant produces an invariant with correct name, code, and methods +- rule: assert does not throw for valid state and throws InvariantError for invalid state +- rule: validate returns structured result without throwing +- rule: Invariant without context function omits context from errors and results +- rule: Parameterized invariants pass extra arguments to check, message, and context +- rule: createInvariant uses the provided error class for thrown errors diff --git a/specs/behavior/platform-core/invariants/invariant-error.sdp.md b/specs/behavior/platform-core/invariants/invariant-error.sdp.md new file mode 100644 index 00000000..f7c087af --- /dev/null +++ b/specs/behavior/platform-core/invariants/invariant-error.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.invariants.invariant-error +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# InvariantError + +## Intent + +- actor: a domain developer +- outcome: Provide a base invariant error class with factory and type guards so domain rule violations are typed, inspectable errors. +- value: Constructor, forContext, isInvariantError, and hasCode give structured codes, context, and instanceof checks. + +## Behavior + +- rule: InvariantError constructor creates a properly structured error +- rule: forContext factory creates context-specific error classes +- rule: isInvariantError type guard identifies InvariantError instances +- rule: hasCode type guard checks error codes diff --git a/specs/behavior/platform-core/logging/commands.sdp.md b/specs/behavior/platform-core/logging/commands.sdp.md new file mode 100644 index 00000000..d3c53679 --- /dev/null +++ b/specs/behavior/platform-core/logging/commands.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.logging.commands +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Logging Helpers + +## Intent + +- actor: a platform developer +- outcome: Log command lifecycle events with consistent field names. +- value: Developers can trace command execution through start, success, rejection, failure, and error. + +## Behavior + +- rule: logCommandStart logs at INFO level with full context. +- rule: logCommandSuccess logs at INFO level with version and eventType. +- rule: logCommandRejected logs at WARN level with rejection details. +- rule: logCommandFailed logs business failures at WARN level. +- rule: logCommandError logs unexpected errors at ERROR level. +- rule: Command lifecycle can be traced through sequential log entries. diff --git a/specs/behavior/platform-core/logging/scoped.sdp.md b/specs/behavior/platform-core/logging/scoped.sdp.md new file mode 100644 index 00000000..b5e94bda --- /dev/null +++ b/specs/behavior/platform-core/logging/scoped.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.logging.scoped +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Scoped Logger + +## Intent + +- actor: a platform developer +- outcome: Prefix scoped logger messages and filter them by log level. +- value: Developers can organize and control logging output per component. + +## Behavior + +- rule: createScopedLogger prefixes messages with the scope name. +- rule: createScopedLogger filters messages below the configured log level. +- rule: createScopedLogger maps each log level to the correct console method. +- rule: Trace level supports console timing via the timing data field. +- rule: createPlatformNoOpLogger produces a logger that discards all output. +- rule: createChildLogger combines parent and child scopes with colon separator. diff --git a/specs/behavior/platform-core/logging/testing.sdp.md b/specs/behavior/platform-core/logging/testing.sdp.md new file mode 100644 index 00000000..20e9a459 --- /dev/null +++ b/specs/behavior/platform-core/logging/testing.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.logging.testing +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Logging Testing Utilities + +## Intent + +- actor: a platform developer +- outcome: Capture log method calls on mock loggers so tests can assert on output. +- value: Tests can assert on log output without real console side effects. + +## Behavior + +- rule: createMockLogger captures all log method calls with metadata. +- rule: clear() resets the captured calls array. +- rule: getCallsAtLevel filters captured calls by log level. +- rule: hasLoggedMessage finds messages by partial text match. +- rule: hasLoggedAt checks both level and message text together. +- rule: getLastCallAt returns the most recent call at a specific level. +- rule: calls property returns consistent array references. +- rule: createFilteredMockLogger only captures logs at or above minimum level. +- rule: Filtered logger helper methods respect the minimum level filter. diff --git a/specs/behavior/platform-core/logging/types.sdp.md b/specs/behavior/platform-core/logging/types.sdp.md new file mode 100644 index 00000000..6176fcff --- /dev/null +++ b/specs/behavior/platform-core/logging/types.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.logging.types +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Logging Types + +## Intent + +- actor: a platform developer +- outcome: Define numeric log-level priorities and filter messages against a configured level. +- value: Developers can control logging verbosity consistently. + +## Behavior + +- rule: LOG_LEVEL_PRIORITY defines numeric ordering for all log levels. +- rule: DEFAULT_LOG_LEVEL is INFO. +- rule: shouldLog returns true when message level >= configured level. diff --git a/specs/behavior/platform-core/middleware/middleware-pipeline.sdp.md b/specs/behavior/platform-core/middleware/middleware-pipeline.sdp.md new file mode 100644 index 00000000..c9ddb9d6 --- /dev/null +++ b/specs/behavior/platform-core/middleware/middleware-pipeline.sdp.md @@ -0,0 +1,34 @@ +--- +id: spec:behavior.platform-core.middleware.middleware-pipeline +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# MiddlewarePipeline orchestration + +## Intent + +- actor: a platform developer +- outcome: Orchestrate middleware execution in registration order so before/after hooks, short-circuiting, and handler errors stay consistent. +- value: Command handlers pick up validation, authorization, and logging without each handler reimplementing those concerns. + +## Behavior + +- rule: use() adds middleware and supports chaining +- rule: remove() removes middleware by name +- rule: has() checks middleware existence +- rule: getMiddlewareNames returns names sorted by order +- rule: execute() runs handler when no middlewares are registered +- rule: Before hooks execute in ascending order +- rule: After hooks execute in reverse order +- rule: Before hook short-circuits on continue false +- rule: Context passes between before hooks +- rule: Before hook errors produce MIDDLEWARE_ERROR rejection +- rule: Handler errors produce HANDLER_ERROR rejection +- rule: After hook errors do not prevent other after hooks or change result +- rule: Short-circuit runs after hooks only for already-executed middlewares +- rule: clear() removes all middlewares +- rule: clone() creates an independent copy +- rule: createMiddlewarePipeline factory creates instances diff --git a/specs/behavior/platform-core/middleware/middlewares.sdp.md b/specs/behavior/platform-core/middleware/middlewares.sdp.md new file mode 100644 index 00000000..ea7a42a3 --- /dev/null +++ b/specs/behavior/platform-core/middleware/middlewares.sdp.md @@ -0,0 +1,31 @@ +--- +id: spec:behavior.platform-core.middleware.middlewares +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Built-in middlewares + +## Intent + +- actor: a platform developer +- outcome: Provide built-in structure, domain, authorization, logging, and rate-limit middlewares at fixed pipeline orders. +- value: Commands get the same validation and policy pipeline without each bounded context writing its own hooks. + +## Behavior + +- rule: Structure validation middleware validates command args against Zod schemas +- rule: Registry validation middleware uses schemas from a command registry +- rule: Domain validation middleware runs async validators and rejects on error messages +- rule: combineDomainValidators runs all validators and returns first error +- rule: CommonValidators provide reusable field-level validation helpers +- rule: Authorization middleware checks permissions and supports skipping +- rule: createRoleBasedChecker creates role-based authorization checkers +- rule: Logging middleware logs command lifecycle events +- rule: createNoOpLogger creates a silent logger +- rule: createJsonLogger outputs structured JSON logs +- rule: Rate limit middleware enforces rate limits and supports skipping +- rule: RateLimitKeys provides key generation strategies +- rule: Middleware ordering constants follow the correct pipeline sequence diff --git a/specs/behavior/platform-core/monitoring/circuit-breaker.sdp.md b/specs/behavior/platform-core/monitoring/circuit-breaker.sdp.md new file mode 100644 index 00000000..11f9ae88 --- /dev/null +++ b/specs/behavior/platform-core/monitoring/circuit-breaker.sdp.md @@ -0,0 +1,28 @@ +--- +id: spec:behavior.platform-core.monitoring.circuit-breaker +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Circuit Breaker + +## Intent + +- actor: a platform developer +- outcome: Provide a circuit breaker for fault isolation so cascading failures are prevented when operations fail repeatedly. +- value: After the failure threshold, open circuits reject subsequent calls immediately instead of repeating the same failure. + +## Behavior + +- rule: A closed circuit executes operations normally +- rule: A closed circuit opens after reaching the failure threshold +- rule: An open circuit transitions to half-open after the timeout elapses +- rule: A half-open circuit closes on a successful probe +- rule: A half-open circuit re-opens on a failed probe +- rule: With successThreshold > 1, multiple consecutive successes are required to close +- rule: getCircuitState returns the current state of a circuit +- rule: resetCircuit clears circuit state back to closed +- rule: Custom configuration overrides default thresholds and timeouts +- rule: A success in closed state resets the failure counter diff --git a/specs/behavior/platform-core/orchestration/command-orchestrator.sdp.md b/specs/behavior/platform-core/orchestration/command-orchestrator.sdp.md new file mode 100644 index 00000000..69a37f38 --- /dev/null +++ b/specs/behavior/platform-core/orchestration/command-orchestrator.sdp.md @@ -0,0 +1,41 @@ +--- +id: spec:behavior.platform-core.orchestration.command-orchestrator +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# CommandOrchestrator partition key structure + +## Intent + +- outcome: The partition context passed to Workpool enqueueMutation uses a structured name and value across primary, secondary, and failed projection paths, and saga routing uses sagaPool. +- value: Workpool enqueue options carry a partition field so projection work stays isolated by key. + +## Behavior + +- rule: Primary projection receives structured partition key +- rule: Secondary projections receive structured partition key +- rule: Failed projection receives structured partition key +- rule: Saga routing uses sagaPool + +## Example space + +```gwt-vocabulary +Given an orchestrator with mock dependencies +And a successful command handler result +And a failed command handler result +And a command config with primary projection {primaryProjection:string} partitioned by "orderId" +And a secondary projection {secondaryProjection:string} partitioned by "orderId" +And a command config with failed projection {failedProjection:string} partitioned by "orderId" +And a command config with saga routing +When I execute the command with orderId {orderId:string} +Then the workpool was called at least 1 time +And the workpool call {callIndex:number} context contains: +And the workpool call {callIndex:number} partition is name "orderId" value {orderId:string} +And the workpool was called at least 2 times +And the primary projection stays on the projection pool +And the saga pool should receive exactly one enqueue call +And the fanout pool should remain unused +``` diff --git a/specs/behavior/platform-core/orchestration/saga-orchestration-executable-tests.sdp.md b/specs/behavior/platform-core/orchestration/saga-orchestration-executable-tests.sdp.md new file mode 100644 index 00000000..f31002e0 --- /dev/null +++ b/specs/behavior/platform-core/orchestration/saga-orchestration-executable-tests.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.orchestration.saga-orchestration-executable-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# SagaOrchestration Executable Tests + +## Intent + +- outcome: Capture SagaOrchestration rule coverage as executable scenarios until the order-management harness wires compensation, durability, and sagaId idempotency. + +## Behavior + +- rule: Sagas orchestrate operations across multiple bounded contexts +- rule: @convex-dev/workflow provides durability across server restarts +- rule: Compensation reverses partial operations on failure +- rule: Saga idempotency prevents duplicate workflows via sagaId +- rule: Saga status is updated via onComplete callback, not inside workflow diff --git a/specs/behavior/platform-core/process-manager/executor.sdp.md b/specs/behavior/platform-core/process-manager/executor.sdp.md new file mode 100644 index 00000000..7353d291 --- /dev/null +++ b/specs/behavior/platform-core/process-manager/executor.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.platform-core.process-manager.executor +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Process Manager Executor + +## Intent + +- actor: a platform developer +- outcome: Route process-manager events to handlers so process managers react to domain events and emit commands. +- value: A subscribed event is processed into commands; unsubscribed events and handler failures stay isolated. + +## Behavior + +- rule: Factory creates executor with correct identity and subscription filtering +- rule: Executor processes subscribed events and emits commands +- rule: Executor skips events it is not subscribed to +- rule: Executor passes custom state from storage to handler +- rule: Default instance ID resolver uses streamId +- rule: Custom instance ID resolver overrides default +- rule: Handler errors produce failed status and dead letters +- rule: Command emitter errors produce failed status and dead letters +- rule: Multi-executor exposes all PM names and finds executors by event type +- rule: processAll routes events through all matching executors +- rule: processAll returns empty for unsubscribed events +- rule: processAll routes to single matching executor +- rule: processAll isolates exceptions across executors +- rule: processAll handles empty executors array gracefully diff --git a/specs/behavior/platform-core/process-manager/lifecycle.sdp.md b/specs/behavior/platform-core/process-manager/lifecycle.sdp.md new file mode 100644 index 00000000..b7735f35 --- /dev/null +++ b/specs/behavior/platform-core/process-manager/lifecycle.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.process-manager.lifecycle +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Process Manager Lifecycle State Machine + +## Intent + +- actor: a platform developer +- outcome: Validate process-manager state transitions through a lifecycle state machine so PM state changes stay auditable. +- value: Allowed events move a PM through idle, processing, completed, and failed without inventing extra transitions. + +## Behavior + +- rule: isPMValidTransition validates allowed transitions from idle state +- rule: isPMValidTransition validates allowed transitions from processing state +- rule: isPMValidTransition validates allowed transitions from completed state +- rule: isPMValidTransition validates allowed transitions from failed state +- rule: pmTransitionState returns the target state for valid transitions and null for invalid +- rule: getPMValidEventsFrom returns the set of valid events for each state +- rule: getAllPMTransitions returns all valid transitions in the state machine +- rule: assertPMValidTransition returns the target state or throws with PM context +- rule: isTerminalState identifies completed as the only terminal state +- rule: isErrorState identifies failed as the only error state +- rule: All non-terminal states can transition and critical paths are reachable +- rule: Typical PM workflows produce the expected state sequences diff --git a/specs/behavior/platform-core/process-manager/registry.sdp.md b/specs/behavior/platform-core/process-manager/registry.sdp.md new file mode 100644 index 00000000..d5e4980a --- /dev/null +++ b/specs/behavior/platform-core/process-manager/registry.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.platform-core.process-manager.registry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Process Manager Registry + +## Intent + +- actor: a platform developer +- outcome: Register, retrieve, and query process managers by event, context, and trigger type. +- value: Event routing and cron setup can enumerate the matching process managers without scanning ad-hoc lists. + +## Behavior + +- rule: register adds a process manager definition to the registry +- rule: get retrieves a process manager by name +- rule: has checks whether a process manager is registered +- rule: list returns all registered process managers +- rule: size returns the count of registered process managers +- rule: getByTriggerEvent finds PMs subscribed to a given event type +- rule: getAllTriggerEvents returns unique sorted event types from all PMs +- rule: getAllEmittedCommands returns unique sorted command types from all PMs +- rule: getByContext filters process managers by bounded context +- rule: getByTriggerType filters process managers by trigger type +- rule: getTimeTriggeredPMs returns time and hybrid triggered PMs +- rule: Event routing use case finds all handlers for an event +- rule: Cron setup use case retrieves all time-triggered PMs for scheduling +- rule: Registry handles PMs with empty event subscriptions and commands diff --git a/specs/behavior/platform-core/process-manager/subscription.sdp.md b/specs/behavior/platform-core/process-manager/subscription.sdp.md new file mode 100644 index 00000000..3c194ac5 --- /dev/null +++ b/specs/behavior/platform-core/process-manager/subscription.sdp.md @@ -0,0 +1,40 @@ +--- +id: spec:behavior.platform-core.process-manager.subscription +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Process Manager EventBus Subscription + +## Intent + +- actor: a platform developer +- outcome: Subscribe process managers to domain events through EventBus helpers with correct instance routing. +- value: Instance identity comes from the correlation strategy or falls back to streamId so handlers see the right PM instance. + +## Behavior + +- rule: computePMInstanceId returns streamId when no correlation strategy +- rule: computePMInstanceId extracts correlation property from payload +- rule: computePMInstanceId falls back to streamId for invalid correlation values +- rule: computePMInstanceId accepts edge-case string values +- rule: createPMSubscription generates correct subscription names +- rule: createPMSubscription configures priority correctly +- rule: createPMSubscription filters by PM event types +- rule: createPMSubscription transforms handler args with default transformer +- rule: createPMSubscription computes instanceId from correlation strategy +- rule: createPMSubscription supports custom toHandlerArgs transformer +- rule: createPMSubscription partitions by instanceId by default +- rule: createPMSubscription uses correlation strategy for partition key +- rule: createPMSubscription supports custom getPartitionKey +- rule: createPMSubscription passes handler reference through +- rule: createPMSubscriptions creates subscriptions for all definitions +- rule: createPMSubscriptions throws on missing handler +- rule: createPMSubscriptions applies common options to all +- rule: createPMSubscriptions creates correct event filters +- rule: createPMSubscriptions handles empty definitions +- rule: createPMSubscriptions passes handlers correctly +- rule: DEFAULT_PM_SUBSCRIPTION_PRIORITY has value 200 +- rule: DEFAULT_PM_SUBSCRIPTION_PRIORITY is between projections and sagas diff --git a/specs/behavior/platform-core/process-manager/types.sdp.md b/specs/behavior/platform-core/process-manager/types.sdp.md new file mode 100644 index 00000000..4f88137b --- /dev/null +++ b/specs/behavior/platform-core/process-manager/types.sdp.md @@ -0,0 +1,30 @@ +--- +id: spec:behavior.platform-core.process-manager.types +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Process Manager Types + +## Intent + +- actor: a platform developer +- outcome: Validate process-manager and dead-letter status values at runtime with type guards and canonical status lists. +- value: Callers can narrow status unions and reject invalid strings before they enter PM runtime state. + +## Behavior + +- rule: isProcessManagerStatus returns true for all valid PM statuses +- rule: isProcessManagerStatus rejects invalid values +- rule: isProcessManagerStatus supports TypeScript type narrowing +- rule: PROCESS_MANAGER_STATUSES exports the canonical PM status list +- rule: isDeadLetterStatus returns true for all valid dead letter statuses +- rule: isDeadLetterStatus rejects invalid values +- rule: isDeadLetterStatus supports TypeScript type narrowing +- rule: DEAD_LETTER_STATUSES exports the canonical dead letter status list +- rule: ProcessManagerDeadLetter has correct structure with all fields +- rule: ProcessManagerDeadLetter supports all dead letter statuses +- rule: ProcessManagerDeadLetter failedCommand captures type and payload +- rule: ProcessManagerDeadLetter handles edge cases diff --git a/specs/behavior/platform-core/process-manager/with-pm-checkpoint.sdp.md b/specs/behavior/platform-core/process-manager/with-pm-checkpoint.sdp.md new file mode 100644 index 00000000..94bea887 --- /dev/null +++ b/specs/behavior/platform-core/process-manager/with-pm-checkpoint.sdp.md @@ -0,0 +1,26 @@ +--- +id: spec:behavior.platform-core.process-manager.with-pm-checkpoint +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# withPMCheckpoint Helper + +## Intent + +- outcome: Process process-manager events through withPMCheckpoint so already-processed and terminal-state events are skipped and failures record dead letters. +- value: Each PM instance keeps its own checkpoint, command counters, and retryable failure path. + +## Behavior + +- rule: withPMCheckpoint processes new events and updates PM state +- rule: withPMCheckpoint skips events at or below the checkpoint position +- rule: withPMCheckpoint skips events when PM is in a terminal state +- rule: withPMCheckpoint maintains separate state per PM instance +- rule: withPMCheckpoint allows retry after emitCommands failure +- rule: withPMCheckpoint validates input parameters +- rule: withPMCheckpoint records dead letters on failure +- rule: withPMCheckpoint tracks emitted commands accurately +- rule: createPMCheckpointHelper creates a reusable helper with bound storage diff --git a/specs/behavior/platform-core/production-hardening/admin-tooling.sdp.md b/specs/behavior/platform-core/production-hardening/admin-tooling.sdp.md new file mode 100644 index 00000000..a8b94f84 --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/admin-tooling.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-core.production-hardening.admin-tooling +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Admin Tooling - Operational Tasks + +## Intent + +- actor: a platform operator +- outcome: Provide admin endpoints for operational tasks so operators can rebuild projections, manage dead letters, and diagnose issues. +- value: Rebuild, DLQ retry, event-flow trace, and diagnostics stay behind a single admin surface. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Admin tooling enables operational tasks diff --git a/specs/behavior/platform-core/production-hardening/circuit-breakers.sdp.md b/specs/behavior/platform-core/production-hardening/circuit-breakers.sdp.md new file mode 100644 index 00000000..b2f7a8ba --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/circuit-breakers.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-core.production-hardening.circuit-breakers +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Circuit Breakers - Fault Isolation + +## Intent + +- actor: a platform developer +- outcome: Isolate external-dependency failures with circuit breakers so the system degrades gracefully. +- value: Repeated failures open the circuit, a timeout probe half-opens it, and success or failure of that probe closes or reopens it. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Circuit breakers prevent cascade failures diff --git a/specs/behavior/platform-core/production-hardening/distributed-tracing.sdp.md b/specs/behavior/platform-core/production-hardening/distributed-tracing.sdp.md new file mode 100644 index 00000000..68af0a19 --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/distributed-tracing.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-core.production-hardening.distributed-tracing +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Distributed Tracing - Event Flow Visualization + +## Intent + +- actor: a platform operator +- outcome: Trace event flows through the system so operators can debug issues and understand command-to-projection paths. +- value: A command, its published event, and the projections that consume it share one trace. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Distributed tracing visualizes event flow diff --git a/specs/behavior/platform-core/production-hardening/durable-function-integration.sdp.md b/specs/behavior/platform-core/production-hardening/durable-function-integration.sdp.md new file mode 100644 index 00000000..47ec748f --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/durable-function-integration.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-core.production-hardening.durable-function-integration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Durable Function Integration - Reliable Execution Patterns + +## Intent + +- actor: a platform developer +- outcome: Integrate durable function components with platform patterns so external calls, retries, and conflict handling stay reliable. +- value: Circuit probes, DCB conflicts, and DLQ retries use action retrier and workpool rather than in-process loops. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Durable functions provide reliable execution patterns diff --git a/specs/behavior/platform-core/production-hardening/health-endpoints.sdp.md b/specs/behavior/platform-core/production-hardening/health-endpoints.sdp.md new file mode 100644 index 00000000..b89ee5ca --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/health-endpoints.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-core.production-hardening.health-endpoints +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Health Endpoints - Kubernetes Probes + +## Intent + +- actor: a Kubernetes operator +- outcome: Expose health-check endpoints so Kubernetes can configure readiness and liveness probes for the application. +- value: Readiness fails when dependencies or projection lag are unhealthy; liveness stays up independently. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Health endpoints support Kubernetes probes diff --git a/specs/behavior/platform-core/production-hardening/metrics-collection.sdp.md b/specs/behavior/platform-core/production-hardening/metrics-collection.sdp.md new file mode 100644 index 00000000..19e9e74c --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/metrics-collection.sdp.md @@ -0,0 +1,38 @@ +--- +id: spec:behavior.platform-core.production-hardening.metrics-collection +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Metrics Collection - System Health Tracking + +## Intent + +- actor: a platform operator +- outcome: Collect system health metrics so operators can monitor projection lag, event throughput, and command latency. +- value: Lag, throughput, and DLQ size export as labeled metrics. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Metrics track system health indicators + +## Example space + +```gwt-vocabulary +Given the test environment is initialized +And a metrics collector is configured +And a projection with checkpoint at position {checkpointPosition:number} +And the latest event is at position {latestPosition:number} +And a projection without a checkpoint entry +And {eventCount:number} events were published in the last minute +And {deadLetterCount:number} dead letters exist for projection {projectionName:string} +When metrics are collected +Then projection.lag_events should be {lagEvents:number} +And the metric should include projection name label +And projection.lag_events should default to current global position +And a warning should be logged +And events.throughput should be approximately {throughput:number} events/min +And dlq.size should be {dlqSize:number} +``` diff --git a/specs/behavior/platform-core/production-hardening/rate-limiting.sdp.md b/specs/behavior/platform-core/production-hardening/rate-limiting.sdp.md new file mode 100644 index 00000000..93d0428c --- /dev/null +++ b/specs/behavior/platform-core/production-hardening/rate-limiting.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.production-hardening.rate-limiting +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Rate Limiting - API Protection + +## Intent + +- actor: a platform developer +- outcome: Rate-limit commands and admin operations so the system is protected from abuse and overload. +- value: Command dispatch and admin rebuild use separate limits, isolated by key. These scenarios remain unimplemented planning stubs. + +## Behavior + +- rule: Rate limiting protects command dispatch +- rule: Admin operations have separate rate limits +- rule: Rate limiter adapter integrates with middleware diff --git a/specs/behavior/platform-core/projection-categories/category-definitions.sdp.md b/specs/behavior/platform-core/projection-categories/category-definitions.sdp.md new file mode 100644 index 00000000..1284948f --- /dev/null +++ b/specs/behavior/platform-core/projection-categories/category-definitions.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.projection-categories.category-definitions +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Projection Category Definitions + +## Intent + +- actor: a platform developer +- outcome: Classify projections into four distinct categories so queries can be routed and projection behavior optimized. +- value: Logic, view, reporting, and integration stay mutually exclusive, and only view is client-exposed. + +## Behavior + +- rule: Every projection belongs to exactly one of logic, view, reporting, or integration. +- rule: PROJECTION_CATEGORIES is a readonly tuple of those four categories. +- rule: isProjectionCategory accepts only the four category strings. +- rule: Category helper functions identify the matching category. +- rule: isClientExposed is true only for view. diff --git a/specs/behavior/platform-core/projection-categories/explicit-declaration.sdp.md b/specs/behavior/platform-core/projection-categories/explicit-declaration.sdp.md new file mode 100644 index 00000000..50e6631b --- /dev/null +++ b/specs/behavior/platform-core/projection-categories/explicit-declaration.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.projection-categories.explicit-declaration +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Explicit Category Declaration + +## Intent + +- actor: a platform developer +- outcome: Require every projection to declare a category so query routing semantics stay explicit. +- value: Missing or invalid categories fail validation with CATEGORY_REQUIRED or INVALID_CATEGORY rather than defaulting. + +## Behavior + +- rule: Missing or null category returns CATEGORY_REQUIRED with suggested categories. +- rule: Valid categories pass validation and return the declared category. +- rule: Invalid category strings return INVALID_CATEGORY with suggested categories. +- rule: assertValidCategory returns the category on valid input and throws on invalid input. diff --git a/specs/behavior/platform-core/projection-categories/registry-lookup.sdp.md b/specs/behavior/platform-core/projection-categories/registry-lookup.sdp.md new file mode 100644 index 00000000..bfd3abe9 --- /dev/null +++ b/specs/behavior/platform-core/projection-categories/registry-lookup.sdp.md @@ -0,0 +1,35 @@ +--- +id: spec:behavior.platform-core.projection-categories.registry-lookup +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Registry Category Lookup + +## Intent + +- actor: a platform developer +- outcome: Query projections by category from the registry so infrastructure can target specific projection types. +- value: View projections feed the reactive layer and integration projections feed EventBus routing; empty registries return no matches. + +## Behavior + +- rule: getByCategory returns the complete subset of registered projections whose declared category matches. +- rule: Lookups against an empty registry return an empty collection rather than failing. +- rule: Reactive targeting queries the registry by the view category. +- rule: EventBus routing queries the registry by the integration category. + +## Example space + +```gwt-vocabulary +Given a projection registry with the following projections: +And an empty projection registry +When I call getByCategory with {category:"view"|"logic"|"reporting"|"integration"} +Then I receive {count:number} projections +And the result contains {projectionName:string} +And all returned projections have category {category:"view"|"logic"|"reporting"|"integration"} +And these are candidates for reactive subscriptions +And these are candidates for EventBus publication +``` diff --git a/specs/behavior/platform-core/projections/categories.sdp.md b/specs/behavior/platform-core/projections/categories.sdp.md new file mode 100644 index 00000000..e83c1812 --- /dev/null +++ b/specs/behavior/platform-core/projections/categories.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:behavior.platform-core.projections.categories +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Projection Categories Edge Cases and Schema Validation + +## Intent + +- outcome: Validate projection category values through the schema, type guard, and assertion helpers. +- value: Non-string and unknown values fail with the published validation error codes instead of being coerced. + +## Behavior + +- rule: ProjectionCategorySchema accepts only the four canonical categories +- rule: isProjectionCategory returns false for all non-string types +- rule: PROJECTION_VALIDATION_ERRORS exposes known error codes +- rule: validateProjectionCategory returns INVALID_CATEGORY for non-string types +- rule: assertValidCategory throws CATEGORY_REQUIRED for undefined input diff --git a/specs/behavior/platform-core/projections/lifecycle.sdp.md b/specs/behavior/platform-core/projections/lifecycle.sdp.md new file mode 100644 index 00000000..804cad39 --- /dev/null +++ b/specs/behavior/platform-core/projections/lifecycle.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.projections.lifecycle +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Projection Lifecycle State Machine + +## Intent + +- actor: a platform developer +- outcome: Validate projection state transitions through a lifecycle state machine so projection state changes stay auditable. +- value: Active, rebuilding, paused, and error states expose only the events that the transition table allows. + +## Behavior + +- rule: isValidTransition returns true for allowed transitions and false for disallowed +- rule: transitionState returns the target state for valid transitions and null for invalid +- rule: getValidEventsFrom returns the set of allowed events for each state +- rule: getAllTransitions returns all valid transitions in the state machine +- rule: assertValidTransition returns new state or throws with projection name +- rule: The state machine is complete — all states are reachable and can transition out +- rule: Typical multi-step workflows complete successfully diff --git a/specs/behavior/platform-core/projections/registry.sdp.md b/specs/behavior/platform-core/projections/registry.sdp.md new file mode 100644 index 00000000..21c0428b --- /dev/null +++ b/specs/behavior/platform-core/projections/registry.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.projections.registry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Projection Registry CRUD and Lookup + +## Intent + +- outcome: Register, retrieve, and look up projections by name, event type, context, category, and rebuild order. +- value: Duplicate names are rejected and category lookup stays indexed independently of registration order. + +## Behavior + +- rule: Registry accepts and stores projection definitions +- rule: Registry returns projection definitions by name +- rule: Registry checks existence of projection definitions +- rule: Registry lists all registered projection definitions +- rule: Registry reports its size accurately +- rule: Registry looks up projections by event type subscription +- rule: Registry aggregates all subscribed event types +- rule: Registry filters projections by bounded context +- rule: Registry determines projection rebuild ordering +- rule: Registry filters projections by category with indexed lookup diff --git a/specs/behavior/platform-core/projections/with-checkpoint.sdp.md b/specs/behavior/platform-core/projections/with-checkpoint.sdp.md new file mode 100644 index 00000000..e93c4a48 --- /dev/null +++ b/specs/behavior/platform-core/projections/with-checkpoint.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.projections.with-checkpoint +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# withCheckpoint Projection Idempotency + +## Intent + +- outcome: Process projection events through withCheckpoint so already-seen events are skipped and checkpoints stay partition-scoped. +- value: A failed process leaves the checkpoint unchanged so a retry can re-apply the same event. + +## Behavior + +- rule: withCheckpoint processes events that have not been seen before +- rule: withCheckpoint skips events at or below the checkpoint position +- rule: withCheckpoint maintains separate checkpoints per partition key +- rule: withCheckpoint does not update checkpoint when processing fails +- rule: withCheckpoint stores all checkpoint fields correctly +- rule: createCheckpointHelper creates a reusable pre-configured helper +- rule: shouldProcessEvent returns true only when event position exceeds checkpoint +- rule: createInitialCheckpoint creates a checkpoint with sentinel values diff --git a/specs/behavior/platform-core/queries/factory.sdp.md b/specs/behavior/platform-core/queries/factory.sdp.md new file mode 100644 index 00000000..37922b3f --- /dev/null +++ b/specs/behavior/platform-core/queries/factory.sdp.md @@ -0,0 +1,32 @@ +--- +id: spec:behavior.platform-core.queries.factory +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Query Factory + +## Intent + +- actor: a platform developer +- outcome: Factory functions produce typed query descriptors, registries, and pagination options so read model queries are created with correct types, configurations, and pagination defaults. +- value: Read model queries get consistent types, configurations, and pagination defaults. + +## Behavior + +- rule: createReadModelQuery produces descriptors with correct result type and config +- rule: createPaginatedQuery produces paginated descriptors with default page sizes +- rule: createPaginatedQuery accepts custom page sizes +- rule: createPaginatedQuery applies defaults to config when not provided +- rule: createQueryRegistry creates a registry with context and projection +- rule: createQueryRegistry indexes multiple query descriptors +- rule: createQueryRegistry provides type-safe access to query descriptors +- rule: getPaginationOptions returns defaults when no options provided +- rule: getPaginationOptions respects provided page size within limits +- rule: getPaginationOptions caps page size at max +- rule: getPaginationOptions enforces minimum page size of 1 +- rule: getPaginationOptions passes through cursor +- rule: getPaginationOptions returns undefined cursor when not provided +- rule: Query descriptors preserve TypeScript result types diff --git a/specs/behavior/platform-core/queries/pagination.sdp.md b/specs/behavior/platform-core/queries/pagination.sdp.md new file mode 100644 index 00000000..9943df9c --- /dev/null +++ b/specs/behavior/platform-core/queries/pagination.sdp.md @@ -0,0 +1,27 @@ +--- +id: spec:behavior.platform-core.queries.pagination +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Pagination Helpers + +## Intent + +- actor: a platform developer +- outcome: Cursor-based pagination utilities paginate query results with consistent defaults, cursor encoding, and page size validation. +- value: Query results are paginated with consistent defaults, cursor encoding, and page size validation. + +## Behavior + +- rule: Pagination constants define reasonable defaults +- rule: normalizePaginationOptions clamps page size and passes through cursor +- rule: createEmptyPage creates a done page with no items +- rule: createPagedResult creates a page with items and continuation state +- rule: encodeCursor and decodeCursor round-trip arbitrary position data +- rule: decodeCursor returns null for invalid or missing input +- rule: isValidPageSize validates integer page sizes within bounds +- rule: getEffectivePageSize returns clamped page size with defaults +- rule: Pagination workflow supports multi-page traversal and edge cases diff --git a/specs/behavior/platform-core/reactive-projections/conflict-detection.sdp.md b/specs/behavior/platform-core/reactive-projections/conflict-detection.sdp.md new file mode 100644 index 00000000..db855348 --- /dev/null +++ b/specs/behavior/platform-core/reactive-projections/conflict-detection.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.reactive-projections.conflict-detection +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Conflict Detection and Rollback + +## Intent + +- actor: a platform developer +- outcome: Detect and resolve conflicts automatically so data integrity is maintained despite optimistic updates. +- value: Optimistic overlays that diverge from durable truth are discarded rather than left as a permanent incorrect view. diff --git a/specs/behavior/platform-core/reactive-projections/hybrid-model.sdp.md b/specs/behavior/platform-core/reactive-projections/hybrid-model.sdp.md new file mode 100644 index 00000000..d7f4915f --- /dev/null +++ b/specs/behavior/platform-core/reactive-projections/hybrid-model.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.reactive-projections.hybrid-model +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Hybrid Model - Durable + Reactive Projections + +## Intent + +- actor: a frontend developer +- outcome: Combine durable projections with instant reactive feedback so users see optimistic updates while data integrity is maintained. +- value: Workpool persistence and the optimistic overlay operate on the same projection and converge once Workpool catches up. diff --git a/specs/behavior/platform-core/reactive-projections/reactive-eligibility.sdp.md b/specs/behavior/platform-core/reactive-projections/reactive-eligibility.sdp.md new file mode 100644 index 00000000..159b14ab --- /dev/null +++ b/specs/behavior/platform-core/reactive-projections/reactive-eligibility.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.reactive-projections.reactive-eligibility +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Reactive Eligibility by Category + +## Intent + +- actor: a platform developer +- outcome: Restrict reactive updates to view projections so system resources stay proportional to user-visible benefit. +- value: Logic, reporting, and integration projections reject reactive subscriptions instead of paying for unused push infrastructure. diff --git a/specs/behavior/platform-core/reactive-projections/shared-evolve.sdp.md b/specs/behavior/platform-core/reactive-projections/shared-evolve.sdp.md new file mode 100644 index 00000000..723f3083 --- /dev/null +++ b/specs/behavior/platform-core/reactive-projections/shared-evolve.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.reactive-projections.shared-evolve +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Shared Evolve Logic - Client/Server Consistency + +## Intent + +- actor: a platform developer +- outcome: Share evolve logic between client and server so state transformations stay consistent. +- value: Identical input state and event produce identical output on both surfaces; unknown event types leave state unchanged. diff --git a/specs/behavior/platform-core/registry/command-registry.sdp.md b/specs/behavior/platform-core/registry/command-registry.sdp.md new file mode 100644 index 00000000..e849300b --- /dev/null +++ b/specs/behavior/platform-core/registry/command-registry.sdp.md @@ -0,0 +1,33 @@ +--- +id: spec:behavior.platform-core.registry.command-registry +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# CommandRegistry + +## Intent + +- actor: a platform developer +- outcome: Provide a central registry for command definitions so commands can be looked up, validated, and filtered at runtime. +- value: Duplicate registration is rejected and payloads validate against registered Zod schemas. + +## Behavior + +- rule: CommandRegistry implements the singleton pattern +- rule: Commands can be registered and duplicate registration is rejected +- rule: Commands can be unregistered from the registry +- rule: getConfig returns the command configuration or undefined +- rule: getRegistration returns the full registration or undefined +- rule: has checks whether a command is registered +- rule: validate checks command payloads against registered Zod schemas +- rule: list returns all registered commands as CommandInfo objects +- rule: listByCategory filters commands by their category +- rule: listByContext filters commands by bounded context +- rule: listByTag filters commands by tag +- rule: groupByContext groups commands by their bounded context +- rule: size returns the number of registered commands +- rule: clear removes all registrations +- rule: globalRegistry is a functional singleton instance diff --git a/specs/behavior/platform-core/registry/define-command.sdp.md b/specs/behavior/platform-core/registry/define-command.sdp.md new file mode 100644 index 00000000..24da995b --- /dev/null +++ b/specs/behavior/platform-core/registry/define-command.sdp.md @@ -0,0 +1,39 @@ +--- +id: spec:behavior.platform-core.registry.define-command +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# defineCommand Helpers + +## Intent + +- actor: a platform developer +- outcome: Reduce boilerplate for defining aggregate, process, and system commands so they can be authored concisely. +- value: Helpers produce CommandConfig with metadata, handler argument mapping, partition keys, and optional auto-registration. + +## Behavior + +- rule: defineAggregateCommand creates a correctly structured command config +- rule: defineAggregateCommand generates toHandlerArgs that adds commandId and correlationId +- rule: defineAggregateCommand generates default partition key from aggregateIdField +- rule: defineAggregateCommand allows custom partition key override +- rule: defineAggregateCommand sets correct metadata for aggregate commands +- rule: defineAggregateCommand auto-registers with global registry by default +- rule: defineAggregateCommand handles secondary projections +- rule: defineAggregateCommand handles saga routing +- rule: defineAggregateCommand preserves sagaRoute.onComplete for dead letter tracking +- rule: defineAggregateCommand handles failed projection +- rule: defineAggregateCommand defaults schemaVersion to 1 +- rule: defineProcessCommand creates a process command with correct metadata +- rule: defineProcessCommand uses processIdField for default partition key +- rule: defineProcessCommand auto-registers with correct category info +- rule: defineSystemCommand creates a system command with correct metadata +- rule: defineSystemCommand generates toHandlerArgs correctly +- rule: defineSystemCommand works without projection +- rule: defineSystemCommand supports optional projection +- rule: defineSystemCommand uses system partition key when no custom key specified +- rule: defineSystemCommand registers only when projection is provided +- rule: defineSystemCommand defaults schemaVersion to 1 diff --git a/specs/behavior/platform-core/repository/cms-repository.sdp.md b/specs/behavior/platform-core/repository/cms-repository.sdp.md new file mode 100644 index 00000000..ceb25cc0 --- /dev/null +++ b/specs/behavior/platform-core/repository/cms-repository.sdp.md @@ -0,0 +1,25 @@ +--- +id: spec:behavior.platform-core.repository.cms-repository +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# CMS Repository + +## Intent + +- outcome: Load, insert, and update CMS entities through a typed repository so upcast and optimistic concurrency stay at the persistence boundary. +- value: Missing entities and version mismatches surface as NotFoundError and VersionConflictError. + +## Behavior + +- rule: load retrieves and upcasts a CMS entity by ID +- rule: tryLoad returns null instead of throwing for missing entities +- rule: exists checks entity presence without upcast overhead +- rule: loadMany retrieves multiple entities in parallel with null for missing +- rule: insert persists a new CMS record and returns the document ID +- rule: update patches CMS with optimistic concurrency control +- rule: NotFoundError has correct properties and type guard +- rule: VersionConflictError has correct properties and type guard diff --git a/specs/behavior/platform-core/reservation/confirm-operation.sdp.md b/specs/behavior/platform-core/reservation/confirm-operation.sdp.md new file mode 100644 index 00000000..36060fd4 --- /dev/null +++ b/specs/behavior/platform-core/reservation/confirm-operation.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.reservation.confirm-operation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Confirm Operation + +## Intent + +- actor: a platform developer +- outcome: Confirm reservations when entities are created so the reserved value becomes permanently associated. +- value: Only active reservations can be confirmed, and confirmation requires an entity ID. + +## Behavior + +- rule: confirm() links reservation to created entity +- rule: Only active reservations can be confirmed +- rule: Entity ID must be provided for confirmation diff --git a/specs/behavior/platform-core/reservation/release-operation.sdp.md b/specs/behavior/platform-core/reservation/release-operation.sdp.md new file mode 100644 index 00000000..02e6d845 --- /dev/null +++ b/specs/behavior/platform-core/reservation/release-operation.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.reservation.release-operation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Release Operation + +## Intent + +- actor: a platform developer +- outcome: Release reservations before they expire so values become immediately available when users cancel. +- value: Only active reservations can be released, and TTL expiration cron marks expired reservations. + +## Behavior + +- rule: release() frees a reservation immediately +- rule: Only active reservations can be released +- rule: TTL expiration cron marks expired reservations diff --git a/specs/behavior/platform-core/reservation/reservation-key.sdp.md b/specs/behavior/platform-core/reservation/reservation-key.sdp.md new file mode 100644 index 00000000..e1271e49 --- /dev/null +++ b/specs/behavior/platform-core/reservation/reservation-key.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.reservation.reservation-key +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Reservation Key Format + +## Intent + +- actor: a platform developer +- outcome: Scope reservation keys by type so different uniqueness constraints do not conflict. +- value: Keys combine type and value, types are independent namespaces, and the separator character is handled correctly. + +## Behavior + +- rule: Reservation key combines type and value +- rule: Different types are independent namespaces +- rule: Type and value must be valid strings +- rule: Reservations can be looked up by key +- rule: Separator character is handled correctly diff --git a/specs/behavior/platform-core/reservation/reserve-operation.sdp.md b/specs/behavior/platform-core/reservation/reserve-operation.sdp.md new file mode 100644 index 00000000..693609c6 --- /dev/null +++ b/specs/behavior/platform-core/reservation/reserve-operation.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.reservation.reserve-operation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Reserve Operation + +## Intent + +- actor: a platform developer +- outcome: Reserve unique values with TTL so uniqueness can be enforced before entity creation. +- value: Concurrent reservations use OCC for atomicity, and TTL plus type and value inputs are validated. + +## Behavior + +- rule: reserve() creates a time-limited claim on a unique value +- rule: Concurrent reservations use OCC for atomicity +- rule: TTL determines reservation expiration time +- rule: TTL boundary values are validated +- rule: Type and value input is sanitized diff --git a/specs/behavior/platform-core/schemas/command-schemas.sdp.md b/specs/behavior/platform-core/schemas/command-schemas.sdp.md new file mode 100644 index 00000000..f9019273 --- /dev/null +++ b/specs/behavior/platform-core/schemas/command-schemas.sdp.md @@ -0,0 +1,63 @@ +--- +id: spec:behavior.platform-core.schemas.command-schemas +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Schemas + +## Intent + +- outcome: Validate command metadata, factory-created command payloads, and the success, rejected, conflict, and error result union. +- value: Commands fail closed at the schema boundary so handlers receive typed metadata, payload, and result status. + +## Behavior + +- rule: CommandMetadataSchema validates required fields and timestamp constraints +- rule: createCommandSchema produces schemas that enforce commandType literal and payload shape +- rule: CommandSuccessResultSchema validates success results with version and optional data +- rule: CommandRejectedResultSchema validates rejected results with code and reason +- rule: CommandConflictResultSchema validates conflict results with CONCURRENT_MODIFICATION code +- rule: CommandErrorResultSchema validates error results requiring a message +- rule: CommandResultSchema discriminated union correctly routes by status field + +## Example space + +```gwt-vocabulary +Given a metadata object with commandId {commandId:string}, commandType {commandType:string}, correlationId {correlationId:string}, and a valid timestamp +And a metadata object with commandId {commandId:string}, commandType {commandType:string}, correlationId {correlationId:string}, userId {userId:string}, and a valid timestamp +And metadata objects with timestamps {timestamps:string} +And a metadata object with only commandId {commandId:string} +And a TestCommand schema created with createCommandSchema and payload field {payloadField:string} +And a command with commandType {commandType:string} and payload foo {foo:string} +And a command with commandType {commandType:string} and payload foo {foo:string} and bar {bar:number} +And a command with payload foo as number {fooNumber:number} +And a command with an empty payload object +And a command without targetContext +And a success result with version {version:number} and data id {dataId:string} +And a success result with version {version:number} and undefined data +And a success result without version and data id {dataId:string} +And a rejected result with code {code:string} and reason {reason:string} +And a rejected result with code {code:string}, reason {reason:string}, and context +And a rejected result with code {code:string} and no reason +And a conflict result with code {code:string} and currentVersion {currentVersion:number} +And a conflict result with code {code:string} and no currentVersion +And an error result with message {message:string} +And an error result with no message +And a result with status {status:"success"|"rejected"|"conflict"|"error"|"unknown"}, version {version:number}, and data null +And a result with status {status:"success"|"rejected"|"conflict"|"error"|"unknown"}, code {code:string}, and reason {reason:string} +And a result with status {status:"success"|"rejected"|"conflict"|"error"|"unknown"}, code {code:string}, and currentVersion {currentVersion:number} +And a result with status {status:"success"|"rejected"|"conflict"|"error"|"unknown"} and message {message:string} +And a result with status {status:"success"|"rejected"|"conflict"|"error"|"unknown"} and data object +When the input is validated against {schema:"CommandMetadataSchema"|"createCommandSchema"|"CommandSuccessResultSchema"|"CommandRejectedResultSchema"|"CommandConflictResultSchema"|"CommandErrorResultSchema"|"CommandResultSchema"} +Then the validation succeeds +And the validation fails +And each validation fails +And the parsed commandType equals {commandType:string} +And the parsed result has status {status:"success"|"rejected"|"conflict"|"error"|"unknown"} and version {version:number} +And the parsed result has status {status:"success"|"rejected"|"conflict"|"error"|"unknown"}, code {code:string}, and reason {reason:string} +And the parsed result has status {status:"success"|"rejected"|"conflict"|"error"|"unknown"} and currentVersion {currentVersion:number} +And the parsed result has status {status:"success"|"rejected"|"conflict"|"error"|"unknown"} and message {message:string} +``` diff --git a/specs/behavior/platform-core/testing/guards.sdp.md b/specs/behavior/platform-core/testing/guards.sdp.md new file mode 100644 index 00000000..d81637e4 --- /dev/null +++ b/specs/behavior/platform-core/testing/guards.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.testing.guards +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Test Environment Guards + +## Intent + +- actor: a platform developer +- outcome: Environment guards prevent test-only functions from being called in production. +- value: Test utilities cannot accidentally manipulate live data. diff --git a/specs/behavior/platform-core/testing/integration-isolation.sdp.md b/specs/behavior/platform-core/testing/integration-isolation.sdp.md new file mode 100644 index 00000000..8acaf2ea --- /dev/null +++ b/specs/behavior/platform-core/testing/integration-isolation.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.testing.integration-isolation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Integration Test Isolation + +## Intent + +- actor: a platform developer +- outcome: Integration tests stay isolated so they do not interfere with each other and produce reliable results. +- value: Docker restart, unique namespaces, and isolated background jobs keep results reproducible. + +## Behavior + +- rule: Docker restart provides clean state between test suites +- rule: Each test uses unique namespace to prevent collisions +- rule: Background jobs are isolated between tests diff --git a/specs/behavior/platform-core/testing/platform-coverage.sdp.md b/specs/behavior/platform-core/testing/platform-coverage.sdp.md new file mode 100644 index 00000000..4552a68f --- /dev/null +++ b/specs/behavior/platform-core/testing/platform-coverage.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:behavior.platform-core.testing.platform-coverage +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Platform Package BDD Coverage + +## Intent + +- actor: a platform maintainer +- outcome: All platform packages have BDD test coverage so public APIs are documented through executable specifications. +- value: Public APIs stay documented in Gherkin rather than opaque unit tests. + +## Behavior + +- rule: Each platform package must have a tests/features/ directory +- rule: Public APIs must have corresponding feature files +- rule: Step definitions must be organized by domain diff --git a/specs/behavior/platform-core/testing/polling.sdp.md b/specs/behavior/platform-core/testing/polling.sdp.md new file mode 100644 index 00000000..841c8d90 --- /dev/null +++ b/specs/behavior/platform-core/testing/polling.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.testing.polling +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# Polling Utilities for Integration Tests + +## Intent + +- actor: a developer writing integration tests +- outcome: Async polling utilities wait for eventual-consistency patterns in integration tests. +- value: Tests can wait for Workpool-processed projections without racing. diff --git a/specs/behavior/platform-core/testing/world.sdp.md b/specs/behavior/platform-core/testing/world.sdp.md new file mode 100644 index 00000000..e0846414 --- /dev/null +++ b/specs/behavior/platform-core/testing/world.sdp.md @@ -0,0 +1,15 @@ +--- +id: spec:behavior.platform-core.testing.world +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-core +--- +# BDD Test World State Management + +## Intent + +- actor: a BDD test author +- outcome: World and state management utilities hold scenario context across steps. +- value: Unit and integration scenarios share lastResult, lastError, and scenario fields without leaking state between runs. diff --git a/specs/behavior/platform-core/workpool-partitioning/complexity-classifier.sdp.md b/specs/behavior/platform-core/workpool-partitioning/complexity-classifier.sdp.md new file mode 100644 index 00000000..4eed7269 --- /dev/null +++ b/specs/behavior/platform-core/workpool-partitioning/complexity-classifier.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.workpool-partitioning.complexity-classifier +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Projection Complexity Classifier + +## Intent + +- actor: a platform developer +- outcome: Classify projections by complexity characteristics so the matching partition strategy can be selected. +- value: Global, saga, customer, and entity recommendations stay ordered by one decision tree instead of ad hoc choice. + +## Behavior + +- rule: The classification decision tree priority is global, then saga, then customer, then entity. +- rule: Single-entity projections recommend entity strategy at simple complexity, with rationale about streamId and per-entity ordering. +- rule: Global-rollup projections recommend global strategy at complex complexity, with rationale about OCC conflicts. +- rule: Cross-context projections recommend saga strategy at complex complexity, with rationale about correlationId and causal ordering. +- rule: Customer-scoped projections recommend customer strategy at moderate complexity, with rationale about customerId and per-customer ordering. +- rule: PARALLELISM_BY_STRATEGY and getRecommendedParallelism map entity to 10, customer to 5, saga to 5, and global to 1. diff --git a/specs/behavior/platform-core/workpool-partitioning/partition-key-helpers.sdp.md b/specs/behavior/platform-core/workpool-partitioning/partition-key-helpers.sdp.md new file mode 100644 index 00000000..05f9c80c --- /dev/null +++ b/specs/behavior/platform-core/workpool-partitioning/partition-key-helpers.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-core.workpool-partitioning.partition-key-helpers +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Workpool Partition Key Helpers + +## Intent + +- actor: a platform developer +- outcome: Provide standardized partition key helpers so projections generate consistent keys. +- value: Entity, customer, saga, global, and DCB flows share one key format instead of ad hoc strings. + +## Behavior + +- rule: GLOBAL_PARTITION_KEY has name global and value global. +- rule: createEntityPartitionKey uses streamType:entityId, prefers streamId, and falls back to orderId, productId, or reservationId. +- rule: createCustomerPartitionKey returns name customerId and requires a nonempty customerId. +- rule: createSagaPartitionKey returns name correlationId and requires a nonempty correlationId. +- rule: createGlobalPartitionKey always returns GLOBAL_PARTITION_KEY. +- rule: createDCBPartitionKey returns name dcb and uses the given scope key as value. diff --git a/specs/behavior/platform-core/workpool-partitioning/partition-validation.sdp.md b/specs/behavior/platform-core/workpool-partitioning/partition-validation.sdp.md new file mode 100644 index 00000000..29d7dfde --- /dev/null +++ b/specs/behavior/platform-core/workpool-partitioning/partition-validation.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-core.workpool-partitioning.partition-validation +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-core +--- +# Command Config Partition Key Validation + +## Intent + +- actor: a platform developer +- outcome: Validate command configs for partition keys so missing or invalid keys fail at startup. +- value: Startup rejects implicit partition keys before they can disorder Workpool processing. + +## Behavior + +- rule: Every projection config must have getPartitionKey defined. +- rule: Partition key functions must return a { name, value } object whose value is a nonempty string. +- rule: Missing keys report MISSING_PARTITION_KEY, bad shapes report INVALID_PARTITION_KEY_SHAPE, and empty values report EMPTY_PARTITION_VALUE. +- rule: Validation collects errors from all projections, including secondary and failed projections. +- rule: assertValidPartitionKeys does not throw for valid or empty arrays and throws one comprehensive error for invalid configs. diff --git a/specs/behavior/platform-decider/_epic.sdp.md b/specs/behavior/platform-decider/_epic.sdp.md new file mode 100644 index 00000000..0e503e4d --- /dev/null +++ b/specs/behavior/platform-decider/_epic.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.platform-decider +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-decider executable behavior + +## Intent + +- outcome: Capture the executable behavior of the platform-decider package. +- value: Decider output helpers and type guards stay traceable as one family of Specs. diff --git a/specs/behavior/platform-decider/decider-outputs.sdp.md b/specs/behavior/platform-decider/decider-outputs.sdp.md new file mode 100644 index 00000000..49ca20b7 --- /dev/null +++ b/specs/behavior/platform-decider/decider-outputs.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:behavior.platform-decider.decider-outputs +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-decider +--- +# Decider Output Helpers and Type Guards + +## Intent + +- outcome: Encode command outcomes as success, rejected, or failed outputs that helpers construct and type guards can narrow. +- value: Domain logic can return a discriminated union without calling infrastructure. + +## Behavior + +- rule: DeciderOutput encodes three outcomes: success emits an event and updates state, rejected is a business-rule violation with a code and no event, and failed is an unexpected failure with an audit event and preserved context. +- rule: Helper functions create these outputs, and type guards enable safe narrowing. diff --git a/specs/behavior/platform-fsm/_epic.sdp.md b/specs/behavior/platform-fsm/_epic.sdp.md new file mode 100644 index 00000000..636461b8 --- /dev/null +++ b/specs/behavior/platform-fsm/_epic.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.platform-fsm +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-fsm executable behavior + +## Intent + +- outcome: Give aggregates explicit typed FSM definitions that prevent invalid state transitions at runtime and report the allowed targets. +- value: Domain workflows can enforce progressions such as draft to submitted to confirmed without embedding transition tables in handlers. diff --git a/specs/behavior/platform-fsm/fsm-transitions.sdp.md b/specs/behavior/platform-fsm/fsm-transitions.sdp.md new file mode 100644 index 00000000..1703e2e3 --- /dev/null +++ b/specs/behavior/platform-fsm/fsm-transitions.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:behavior.platform-fsm.fsm-transitions +kind: behavior +altitude: story +readiness: defined +relations: + refines: spec:behavior.platform-fsm +--- +# FSM State Transitions + +## Intent + +- outcome: Define a typed FSM with explicit transition rules so invalid state changes fail at runtime with an error that names the allowed targets. +- value: Aggregates can reuse one transition map instead of scattering state-progression checks through handlers. + +## Behavior + +- rule: A defined FSM starts in the authored initial state and exposes its definition. +- rule: canTransition returns true only for transitions listed on the source state. +- rule: assertTransition throws FSMTransitionError for invalid transitions, with from, to, allowed targets, and code FSM_INVALID_TRANSITION. +- rule: Terminal states have no outgoing transitions and the error names "(none - terminal state)". +- rule: isValidState is true only for states in the definition. +- rule: validTransitions returns the allowed targets for a state. +- rule: Standalone canTransition and assertTransition functions match the FSM methods. diff --git a/specs/behavior/platform-store/_epic.sdp.md b/specs/behavior/platform-store/_epic.sdp.md new file mode 100644 index 00000000..a54aaebe --- /dev/null +++ b/specs/behavior/platform-store/_epic.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:behavior.platform-store +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# platform-store executable behavior + +## Intent + +- outcome: Specify platform-store Event Store foundation and type-contract behavior migrated from the package test corpus. +- value: The platform-store package is the Convex event storage, stream ordering, and idempotency-audit component. diff --git a/specs/behavior/platform-store/event-store-foundation-executable-tests.sdp.md b/specs/behavior/platform-store/event-store-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..7e86e366 --- /dev/null +++ b/specs/behavior/platform-store/event-store-foundation-executable-tests.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:behavior.platform-store.event-store-foundation-executable-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-store +--- +# EventStoreFoundation Executable Tests + +## Intent + +- problem: Event Sourcing requires centralized storage for domain events with ordering guarantees, concurrency control, and query capabilities for projections. Without infrastructure for stream-based storage, bounded contexts cannot maintain audit trails or support projection-based read models. +- outcome: Capture Event Store foundation coverage that events append immutably with stream versions, globalPosition ordering, OCC, and checkpointed projection reads until the stub harness is wired. +- value: The Event Store component provides stream-based storage with expectedVersion OCC, global positioning, appendToStream/readStream/readFromPosition APIs, event category taxonomy, and schema versioning. + +## Behavior + +- rule: Events are immutable once appended +- rule: Streams provide per-entity ordering via version numbers +- rule: globalPosition enables total ordering across all streams +- rule: OCC prevents concurrent modification conflicts +- rule: Checkpoints enable projection resumption with exactly-once semantics diff --git a/specs/behavior/platform-store/event-store-types.sdp.md b/specs/behavior/platform-store/event-store-types.sdp.md new file mode 100644 index 00000000..00a5d121 --- /dev/null +++ b/specs/behavior/platform-store/event-store-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:behavior.platform-store.event-store-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:behavior.platform-store +--- +# Event Store Type Contracts + +## Intent + +- outcome: Export EventInput, StoredEvent, AppendResult, and EventCategory type contracts that define the Event Store client surface. +- value: Type contracts ensure EventInput captures append data, StoredEvent includes storage fields, AppendResult discriminates success from conflict, and EventCategory supports the Phase 9 taxonomy. diff --git a/specs/codec-driven-reference-generation.sdp.md b/specs/codec-driven-reference-generation.sdp.md new file mode 100644 index 00000000..818cbfbc --- /dev/null +++ b/specs/codec-driven-reference-generation.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:platform.codec-driven-reference-generation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Codec-Driven Reference Generation + +## Intent + +- outcome: Reference documentation is specified via 11 recipe '.feature' files in 'architect/recipes/'. Each recipe contains a Source Mapping table (static configuration) and Rule blocks (durable content). But recipes are configuration masquerading as feature files — no scenarios execute, no BDD benefit exists. The Source Mapping is static and the Rule blocks are durable knowledge that belongs in decision records. +- problem: Reference documentation is specified via 11 recipe '.feature' files in 'architect/recipes/'. Each recipe contains a Source Mapping table (static configuration) and Rule blocks (durable content). But recipes are configuration masquerading as feature files — no scenarios execute, no BDD benefit exists. The Source Mapping is static and the Rule blocks are durable knowledge that belongs in decision records. +- value: Replace recipe files with a parameterized 'ReferenceDocumentCodec' that composes reference documents from convention-tagged decision records, TypeScript shape extractions, and behavior spec content. The Source Mapping becomes a TypeScript config object registered in the existing 'GeneratorRegistry'. Recipe Rule blocks migrate to decision records tagged '@architect-convention'. + +## Behavior + +- rule: Reference documents are generated by a parameterized codec +- rule: Convention content is extracted from tagged decision records +- rule: Reference codec handles missing or empty sources gracefully +- rule: Each reference generator produces dual output via DetailLevel +- rule: Reference generators are discovered via the existing registry +- rule: Convention tag values classify decision records by topic +- rule: Recipe Rule blocks are migrated to convention-tagged decision records diff --git a/specs/decisions.pack.sdp.md b/specs/decisions.pack.sdp.md new file mode 100644 index 00000000..4dc61e33 --- /dev/null +++ b/specs/decisions.pack.sdp.md @@ -0,0 +1,31 @@ +--- +id: pack:decisions +specs: + - spec:decisions.process + - spec:decisions.pdr-001-process-decisions-folder + - spec:decisions.pdr-002-release-management-architecture + - spec:decisions.pdr-003-behavior-feature-file-structure + - spec:decisions.pdr-004-unified-tag-prefix-architecture + - spec:decisions.pdr-005-mvp-workflow + - spec:decisions.pdr-006-typescript-sourced-taxonomy + - spec:decisions.pdr-007-two-tier-spec-architecture + - spec:decisions.pdr-008-example-app-purpose + - spec:decisions.pdr-009-design-session-methodology + - spec:decisions.pdr-010-cross-component-argument-injection + - spec:decisions.pdr-011-agent-action-handler-architecture + - spec:decisions.pdr-012-agent-command-routing + - spec:decisions.pdr-013-agent-lifecycle-fsm + - spec:decisions.pdr-014-component-boundary-authentication-convention + - spec:decisions.pdr-015-global-position-numeric-representation + - spec:decisions.pdr-016-projection-pool-split-named-pools-per-concern + - spec:decisions.pdr-017-tranche-3-platform-architecture-gate + - spec:decisions.pdr-018-idempotency-enforcement-for-append-to-stream + - spec:decisions.pdr-019-v-any-vs-v-unknown-boundary-policy + - spec:decisions.pdr-020-events-table-index-policy + - spec:decisions.pdr-021-platform-store-runtime-dependency-on-platform-core + - spec:decisions.pdr-022-value-transfer-doctrine-adoption + - spec:decisions.pdr-023-bulk-doctrine-rollback-and-recovery +--- +# Decisions + +Process Decision Records (PDRs) migrated from architect/decisions into SDP decision Specs. diff --git a/specs/decisions/_epic.sdp.md b/specs/decisions/_epic.sdp.md new file mode 100644 index 00000000..4a793360 --- /dev/null +++ b/specs/decisions/_epic.sdp.md @@ -0,0 +1,16 @@ +--- +id: spec:decisions.process +kind: decision +altitude: epic +readiness: idea +relations: {} +--- +# Process decision registry + +## Intent + +- outcome: Hold the monorepo Process Decision Records as a single refinement parent so each PDR can declare a relation without inventing a second decision. + +## Decision + +- decision: Every PDR under specs/decisions/ refines spec:decisions.process. diff --git a/specs/decisions/pdr-001-process-decisions-folder.sdp.md b/specs/decisions/pdr-001-process-decisions-folder.sdp.md new file mode 100644 index 00000000..ed69b4fb --- /dev/null +++ b/specs/decisions/pdr-001-process-decisions-folder.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-001-process-decisions-folder +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-001 - Process Decisions Live in /libar-platform/architect/decisions/ + +## Intent + +- outcome: Keep monorepo process decision records separate from package-level architecture decision records. + +## Decision + +- context: The monorepo needed a location for process-level decisions (PDRs) separate from package-level Architecture Decision Records (ADRs). Package ADRs live with the architect tool and document its own tooling; PDRs document how this monorepo uses the tool, with independent ownership, numbering, and tag registries. +- decision: Process Decision Records for the monorepo live in specs/decisions/ as SDP Markdown carriers named pdr-NNN-name.sdp.md, keeping package ADRs and repo PDRs in separate ownership and numbering sequences. +- rationale: The separation enables clear ownership boundaries, different tag registries for different scopes, and independent evolution of package versus repo process decisions. +- consequence: Package ADRs and repo PDRs stay separately numbered and owned. +- consequence: Two registries must be maintained (package versus repo). diff --git a/specs/decisions/pdr-002-release-management-architecture.sdp.md b/specs/decisions/pdr-002-release-management-architecture.sdp.md new file mode 100644 index 00000000..73f6cd95 --- /dev/null +++ b/specs/decisions/pdr-002-release-management-architecture.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:decisions.pdr-002-release-management-architecture +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-002 - Release Management Architecture + +## Intent + +- outcome: Organize delivery around release versions instead of pre-defined phase timelines. + +## Decision + +- context: Timeline feature files and TypeScript phase files created friction: deliverable DataTables were cumbersome, phases were pre-defined while work is not linear, and releases (external versions) were treated as if they were phases (internal work units). The relationship should be one roadmap phase to many releases. +- decision: Adopt a minimal release management architecture with three components: release definition files that list version, status, quarter, and highlights without deliverable DataTables; deliverable association via @architect-release tags; and generated changelog, roadmap, and release notes discovered by scanning those tags. +- rationale: Deliverables naturally belong to releases, not phases, so tagging and generation keep ceremony small while Git remains the event store and documentation remains a projection. +- consequence: Release files stay short and scope can change during development without restructuring. +- consequence: Scanner support for @architect-release is required, and both the release file and the tag on each deliverable must stay in sync. +- alternative: Timeline .feature files with DataTables and fifteen-plus metadata tags per file. +- alternative: TypeScript phase files tightly coupled 1:1 to releases. diff --git a/specs/decisions/pdr-003-behavior-feature-file-structure.sdp.md b/specs/decisions/pdr-003-behavior-feature-file-structure.sdp.md new file mode 100644 index 00000000..bdf14abe --- /dev/null +++ b/specs/decisions/pdr-003-behavior-feature-file-structure.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-003-behavior-feature-file-structure +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-003 - Behavior Feature File Structure + +## Intent + +- outcome: Let requirement specs evolve independently of release planning. + +## Decision + +- context: Timeline .feature files mixed requirements with libar-process-* phase and release tags, so DataTables were hard to maintain, metadata was scattered, and combining or splitting specs required updating process metadata everywhere. +- decision: Separate WHAT from WHEN: specs carry semantic requirements and deliverables with no libar-process-* tags or Release columns, while TypeScript phase files carry @architect-* release, phase, and dependency annotations and reference specs by pattern name. +- rationale: Specs describe what the system does, not when it was released; release coupling prevents specs from evolving independently. +- consequence: Specs can evolve independently of release planning, and roadmap generation has a single source of truth in TypeScript annotations. +- consequence: Two file types must be maintained, and phase files must manually reference spec files. diff --git a/specs/decisions/pdr-004-unified-tag-prefix-architecture.sdp.md b/specs/decisions/pdr-004-unified-tag-prefix-architecture.sdp.md new file mode 100644 index 00000000..9749b33d --- /dev/null +++ b/specs/decisions/pdr-004-unified-tag-prefix-architecture.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-004-unified-tag-prefix-architecture +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-004 - Unified Tag Prefix Architecture + +## Intent + +- outcome: Give process and documentation metadata one tag prefix so ownership is obvious. + +## Decision + +- context: Historical tag prefixes created confusion: libar-docs-* in TypeScript versus libar-process-* in Gherkin. Overlapping tags such as pattern, phase, and status had unclear ownership, so two mental models had to be maintained. +- decision: All process and documentation metadata tags use the unified @architect-* prefix; the libar-process-* prefix is deprecated; unprefixed BDD tags such as acceptance-criteria and happy-path remain unprefixed. +- rationale: A single prefix makes grep, onboarding, and ownership one mental model while leaving Cucumber-style scenario tags as BDD vocabulary. +- consequence: Contributors search and apply one @architect-* model for metadata. +- consequence: Existing libar-process-* tags must migrate, and the scanner accepts both prefixes during the transition. diff --git a/specs/decisions/pdr-005-mvp-workflow.sdp.md b/specs/decisions/pdr-005-mvp-workflow.sdp.md new file mode 100644 index 00000000..06390c11 --- /dev/null +++ b/specs/decisions/pdr-005-mvp-workflow.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-005-mvp-workflow +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-005 - MVP Workflow State Machine + +## Intent + +- outcome: Enforce a single process state machine so work items cannot skip or invent status transitions. + +## Decision + +- context: Previous status values (implemented, partial, roadmap, completed, active) had overlapping semantics and no programmatic enforcement, so work items could transition without validation. +- decision: Adopt the phase-state-machine FSM with Decider-based enforcement: roadmap, active, completed, and deferred; valid transitions are roadmap to active or deferred, active to completed or back to roadmap, and deferred back to roadmap; completed is terminal without an explicit unlock; required tags are @architect-pattern and @architect-status. +- rationale: Protection levels and Decider validation catch invalid transitions and prevent accidental scope creep, aligning process metadata with platform Decider and FSM patterns. +- consequence: Invalid transitions are caught in process linting, and protection levels block accidental modification of in-progress or completed work. +- consequence: lint:process is required in pre-commit and CI, and the FSM supersedes legacy status values in the tag registry. diff --git a/specs/decisions/pdr-006-typescript-sourced-taxonomy.sdp.md b/specs/decisions/pdr-006-typescript-sourced-taxonomy.sdp.md new file mode 100644 index 00000000..7af86078 --- /dev/null +++ b/specs/decisions/pdr-006-typescript-sourced-taxonomy.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-006-typescript-sourced-taxonomy +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-006 - TypeScript-Sourced Taxonomy + +## Intent + +- outcome: Make taxonomy values compile-time facts instead of untyped JSON strings. + +## Decision + +- context: tag-registry.json was the source of truth with Zod validating structure at runtime and no compile-time enforcement, so typos, renames, and missing autocomplete only appeared after JSON was edited. +- decision: TypeScript as-const arrays are the source of truth, types are inferred from those constants, Zod schemas reuse the constants for runtime validation, and JSON registries are generated artifacts rather than hand-edited files. +- rationale: Compile-time constants give IDE autocomplete and refactoring while keeping Zod at the runtime boundary and leaving external JSON consumers on generated output. +- consequence: Taxonomy values are checked at compile time and remain a single TypeScript source of truth. +- consequence: External tools that expect JSON must consume generated output from the registry builder. diff --git a/specs/decisions/pdr-007-two-tier-spec-architecture.sdp.md b/specs/decisions/pdr-007-two-tier-spec-architecture.sdp.md new file mode 100644 index 00000000..55e6f1b4 --- /dev/null +++ b/specs/decisions/pdr-007-two-tier-spec-architecture.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-007-two-tier-spec-architecture +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-007 Two-Tier Spec Architecture + +## Intent + +- outcome: Separate planning specs from executable package tests so scenarios are not duplicated. + +## Decision + +- context: Planning and tracking were conflated with implementation proof in the same feature files, which duplicated scenarios between roadmap specs and package tests and left ownership of executable versus documentation unclear. +- decision: Establish two tiers linked by metadata instead of duplicated scenarios: non-executable roadmap specs under libar-platform/architect/specs/ for planning and deliverables, and executable package specs under packages/*/tests/features/ for implementation tests, cross-referenced with @architect-executable-specs and @architect-roadmap-spec. +- rationale: Traceability via tags eliminates scenario duplication while keeping roadmap specs as lightweight planning documents and package specs as the authoritative behavior record. +- consequence: Ownership is clear and roadmap specs stay lightweight planning documents. +- consequence: Tag relationships must be maintained, and readers look in two places mitigated by the cross-references. diff --git a/specs/decisions/pdr-008-example-app-purpose.sdp.md b/specs/decisions/pdr-008-example-app-purpose.sdp.md new file mode 100644 index 00000000..2c148e25 --- /dev/null +++ b/specs/decisions/pdr-008-example-app-purpose.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-008-example-app-purpose +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-008 Example App Purpose and Guidelines + +## Intent + +- outcome: Keep example-app changes focused on demonstrating and testing the platform rather than growing a standalone product. + +## Decision + +- context: It was unclear whether example-app features should mirror production requirements, prioritize completeness versus demonstration, or be driven by business needs versus platform needs. The previous freeze policy listed allowed and prohibited change categories instead of stating the purpose that should guide those choices. +- decision: The example app exists to serve platform development, not as a standalone product: it is a development aid and testing consumer, a reference-grade demonstration of platform capabilities, and the primary vehicle for validating platform patterns in realistic scenarios. Changes are appropriate when they demonstrate, test, or unblock platform work, and not when they add unrelated business features. +- rationale: Articulating the fundamental purpose is simpler and more durable than an explicit allowed-and-prohibited freeze list. +- consequence: Example-app changes stay judged against platform value and are less likely to sprawl into unrelated business logic. +- consequence: The example app may not be a complete order-management product, and some realistic business scenarios stay simplified, so judgment is still required. diff --git a/specs/decisions/pdr-009-design-session-methodology.sdp.md b/specs/decisions/pdr-009-design-session-methodology.sdp.md new file mode 100644 index 00000000..fe7c0ed2 --- /dev/null +++ b/specs/decisions/pdr-009-design-session-methodology.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-009-design-session-methodology +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-009 Design Session Methodology + +## Intent + +- outcome: Give design sessions a fixed pair of outputs so HOW decisions and interface contracts do not live in throwaway documents or compile-breaking source stubs. + +## Decision + +- context: Plan-level Gherkin specs captured WHAT to build, but design sessions also needed HOW decisions and interface contracts. Without a methodology, markdown design documents duplicated specs, stubs in real source folders broke compilation on missing generated Convex server code, and architectural decisions were scattered without structured traceability. +- decision: Design sessions produce decision specs as Gherkin features under libar-platform/architect/decisions/ and TypeScript stubs under libar-platform/architect/stubs/{pattern-name}/, which sits outside package tsconfig and eslint scopes. Stubs use pattern-based folder names with @architect-implements and @architect-target; they are not implementation code, and markdown design documents are not a design-session output. Decision records from design sessions use the design category alongside process and architecture. +- rationale: Stubs outside compilation never break the tree, decision specs carry structured tags, and pattern names stay stable after ephemeral session numbers are gone. +- consequence: Stubs never break compilation or linting, and design-to-implementation linkage is explicit through @architect-implements and @architect-target. +- consequence: Stubs are not type-checked until implementation moves them to @architect-target locations. diff --git a/specs/decisions/pdr-010-cross-component-argument-injection.sdp.md b/specs/decisions/pdr-010-cross-component-argument-injection.sdp.md new file mode 100644 index 00000000..e1dd3787 --- /dev/null +++ b/specs/decisions/pdr-010-cross-component-argument-injection.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:decisions.pdr-010-cross-component-argument-injection +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-010 Cross-Component Argument Injection Pattern + +## Intent + +- outcome: Let a Convex component use data from outside its isolated database without querying across the boundary. + +## Decision + +- context: Convex component handlers can only access tables in that component's schema. They cannot query app-level tables or join across components, so all cross-component data access must go through handler arguments or return values. +- decision: When a component handler needs data from outside its boundary, the app-level caller loads that data, shapes it into a typed InjectedData container with optional fields, and passes it as an argument; the handler processes the pre-loaded data without external queries. +- rationale: Argument injection keeps the component pure and unaware of external schema, while the caller retains control over loading, caching, and batching. +- consequence: The component stays isolated, InjectedData is compile-time typed, and tests can inject mock data without projections. +- consequence: The caller must know what data the component needs, handler signatures carry extra arguments, and InjectedData can grow if different operations need different external data. +- alternative: A callback pattern in which the component requests data, which breaks transactional guarantees and makes the component aware of external schema. +- alternative: Duplicating external data into the component, which adds redundant storage and consistency risk. +- alternative: A shared database layer, which violates bounded-context isolation. diff --git a/specs/decisions/pdr-011-agent-action-handler-architecture.sdp.md b/specs/decisions/pdr-011-agent-action-handler-architecture.sdp.md new file mode 100644 index 00000000..bda3e3cf --- /dev/null +++ b/specs/decisions/pdr-011-agent-action-handler-architecture.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-011-agent-action-handler-architecture +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-011 Agent Action Handler Architecture + +## Intent + +- outcome: Split agent event handling so LLM calls can run in Convex actions while all persistence stays in onComplete mutations. + +## Decision + +- context: Agent event handlers that need LLM API calls cannot be mutations, because mutations cannot call external APIs and actions cannot write the database except through runMutation. Workpool partition-key ordering is not yet available, so concurrent actions for the same entity can run at once. This supersedes the single-mutation handler pattern from Phase 22 and is a companion to PDR-010. +- decision: Agent event processing is two-phase: an action loads checkpoint, history, and injectedData, runs pattern detection or LLM analysis, and returns AgentActionResult with no writes; an onComplete mutation persists audit, command, approval, and checkpoint last. EventSubscription is a discriminated union of mutation versus action, and ActionSubscription requires onComplete. Idempotency is guaranteed by OCC-serialized onComplete mutations, with an in-action checkpoint check only as a best-effort skip of unnecessary LLM calls. ActionSubscription and MutationSubscription may name an optional pool so agent LLM actions do not share the projection pool. +- rationale: A unified action-plus-onComplete path covers rule-only and LLM agents without dual handler models, and OCC on the checkpoint document is the correctness mechanism until Workpool key-based ordering exists. +- consequence: Agent handlers can call LLMs while all writes remain atomic in onComplete, and existing mutation subscriptions keep working. +- consequence: Two concurrent actions for the same entity can both analyze; serialization and duplicate suppression happen at onComplete, not at enqueue time. diff --git a/specs/decisions/pdr-012-agent-command-routing.sdp.md b/specs/decisions/pdr-012-agent-command-routing.sdp.md new file mode 100644 index 00000000..3b4c9ff5 --- /dev/null +++ b/specs/decisions/pdr-012-agent-command-routing.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-012-agent-command-routing +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-012 Agent Command Routing & Pattern Unification + +## Intent + +- outcome: Route agent-emitted commands through CommandOrchestrator and make PatternDefinition the single detection source of truth. + +## Decision + +- context: Commands emitted by agents were remaining pending in the agent component instead of reaching registered domain handlers, and inline onEvent handlers ran in parallel with unused PatternDefinition instances. This is a companion to PDR-011 and PDR-010. +- decision: Agent decisions that produce commands persist as before, then onComplete enqueues a Workpool mutation that loads the recorded command, maps it through AgentCommandRouter, and executes CommandOrchestrator. AgentBCConfig takes exactly one of onEvent or patterns: PatternExecutor iterates PatternDefinition[] in array order, short-circuits on the first match, and uses trigger() before optional analyze() so LLM calls are skipped when the cheap trigger does not fire. +- rationale: Workpool dispatch keeps persistence and routing in separate transactions with retry, and XOR config keeps existing onEvent agents working while new agents share one PatternDefinition source of truth. +- consequence: Agent commands reach domain handlers through the existing orchestrator pipeline, and unknown types fail with an audited routing error instead of sitting pending. +- consequence: Agents must choose onEvent or patterns; both or neither is invalid. diff --git a/specs/decisions/pdr-013-agent-lifecycle-fsm.sdp.md b/specs/decisions/pdr-013-agent-lifecycle-fsm.sdp.md new file mode 100644 index 00000000..24145949 --- /dev/null +++ b/specs/decisions/pdr-013-agent-lifecycle-fsm.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-013-agent-lifecycle-fsm +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-013 Agent Lifecycle FSM + +## Intent + +- outcome: Govern agent start, pause, resume, stop, and reconfigure with a formal lifecycle state machine that does not route through CommandOrchestrator. + +## Decision + +- context: Agent start, pause, resume, stop, and reconfigure needed validated transitions with checkpoint status as the single source of truth. Lifecycle commands are infrastructure, not domain commands, and paused events must not replay as a storm on resume. Companion to PDR-011, PDR-012, and PDR-010. +- decision: Agent lifecycle uses the established event-driven Map pattern (not platform-fsm/defineFSM) over states stopped, active, paused, and error_recovery, stored on checkpoint status and applied to every checkpoint for an agentId. StartAgent, PauseAgent, ResumeAgent, StopAgent, and ReconfigureAgent are direct internalMutation calls that bypass CommandOrchestrator. While paused, EventBus still delivers events; the action returns a null decision and onComplete advances the checkpoint so events are seen-but-skipped. ReconfigureAgent stores runtime overrides (confidenceThreshold, patternWindowDuration, rateLimits) on the checkpoint and merges them with AgentBCConfig at execution; error_recovery trigger mechanics stay deferred to circuit-breaker design. +- rationale: defineFSM cannot attach named event triggers, the checkpoint table already has the four states, infrastructure commands must not cycle agent infra through command infra, and advancing paused checkpoints prevents replaying every event received during the pause. +- consequence: Invalid transitions are rejected with INVALID_LIFECYCLE_TRANSITION, and pause does not queue events for later catch-up. +- consequence: Operators who want catch-up after a pause must stop and rewind; pending routed commands and approvals are not cancelled by pause. diff --git a/specs/decisions/pdr-014-component-boundary-authentication-convention.sdp.md b/specs/decisions/pdr-014-component-boundary-authentication-convention.sdp.md new file mode 100644 index 00000000..07a33ccb --- /dev/null +++ b/specs/decisions/pdr-014-component-boundary-authentication-convention.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:decisions.pdr-014-component-boundary-authentication-convention +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-014 - Component-Boundary Authentication Convention + +## Intent + +- outcome: Verify actor identity inside each identity-bearing component mutation instead of trusting caller-supplied ids. + +## Decision + +- context: Convex component boundaries do not carry ctx.auth, yet caller and component still run in the same top-level transaction. The insecure gap is trust: component mutations treated caller-supplied reviewerId, agentId, boundedContext, or tenantId strings as authoritative. Components cannot read process.env, so verification cannot depend on bearer tokens or env-backed secrets inside the component. +- decision: Every identity-bearing component mutation in scope accepts a canonical verificationProof and calls verifyActor() before reading or writing component state. On success the verified proof is the source of truth; raw caller-supplied identity fields are only compared against the proof, never persisted as trusted values. The tranche-1 keystone packet migrates approve, reject, audit.record, agentCommands.record, and appendToStream together so none of those mutations still trust raw caller fields. +- rationale: A signed proof keeps the boundary explicit, rejects tampering, and composes with atomic parent mutations without leaking bearer tokens into the component. +- consequence: Wrong boundedContext, tenantId, reviewerId, or agentId claims are rejected before mutation writes, while the parent app still owns end-user authentication. +- consequence: Parent mutations and infrastructure clients must mint verificationProof objects, and component-local verification helpers duplicate the proof algorithm because component code cannot import the parent implementation. +- alternative: Pass a bearer or JWT token into the component, which leaks bearer material and couples the component to token semantics. +- alternative: Trust caller-supplied ids and only annotate callers, which leaves the trust vacuum in place. diff --git a/specs/decisions/pdr-015-global-position-numeric-representation.sdp.md b/specs/decisions/pdr-015-global-position-numeric-representation.sdp.md new file mode 100644 index 00000000..083925db --- /dev/null +++ b/specs/decisions/pdr-015-global-position-numeric-representation.sdp.md @@ -0,0 +1,24 @@ +--- +id: spec:decisions.pdr-015-global-position-numeric-representation +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-015 - globalPosition Numeric Representation + +## Intent + +- outcome: Represent event-store globalPosition exactly at real Date.now() scales without losing ordering. + +## Decision + +- context: The old representation combined Date.now() with hash and version arithmetic inside a JavaScript number. At current timestamps that exceeds Number.MAX_SAFE_INTEGER, so ordering and equality become lossy exactly where checkpoints and replay need exact comparisons. The new representation must stay indexable in Convex and readable from legacy numeric checkpoint documents. +- decision: Event Store events.globalPosition is Convex v.int64() at rest and TypeScript bigint at runtime, allocated as BigInt(timestamp) * 1_000_000n + BigInt(sequence) from a per-millisecond sequence 0..999999, clamping backwards clocks and overflowing into the next millisecond. New event-row writes use int64 only; checkpoint readers accept legacy number or canonical bigint through normalizeGlobalPosition() and persist canonical bigint on new writes. +- rationale: int64/bigint stays exact and indexable, keeps timestamp-derived ordering, and makes sequential appends strictly monotonic without hash buckets or version modulo wraparound. +- consequence: globalPosition comparisons are exact and monotonic at current timestamp scales, and legacy numeric checkpoints can still be read. +- consequence: Consumers that used number arithmetic such as subtraction, Math.max, or greater-than must migrate to shared bigint-aware helpers, and logs and UI must stringify bigint values. +- alternative: Keep a JavaScript number and adjust the formula, which remains unsafe at real timestamp scales. +- alternative: Fixed-width string positions, which couple lexical format into every comparison. +- alternative: A pure global counter, which loses timestamp decomposition and complicates compatibility with historical position magnitude. diff --git a/specs/decisions/pdr-016-projection-pool-split-named-pools-per-concern.sdp.md b/specs/decisions/pdr-016-projection-pool-split-named-pools-per-concern.sdp.md new file mode 100644 index 00000000..919dff38 --- /dev/null +++ b/specs/decisions/pdr-016-projection-pool-split-named-pools-per-concern.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-016-projection-pool-split-named-pools-per-concern +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-016 - projectionPool Split into Named Pools per Concern + +## Intent + +- outcome: Isolate primary projection work from saga routing and secondary fanout so they no longer share one Workpool. + +## Decision + +- context: Tranche-2 adds more async traffic classes than a single projectionPool handled cleanly: primary projections are latency-sensitive, saga routing can compete with those updates, and wide fanout bursts can starve primary work. Upstream Workpool still does not provide a native FIFO key: ordering contract for general projection serialization, and this decision does not invent fake ordering around that missing feature. +- decision: OrchestratorDependencies requires three named pools: projectionPool for primary and failed projections, sagaPool for CommandOrchestrator.sagaRoute, and fanoutPool for secondary projections, the EventBus default pool, and IntegrationEventPublisher. The example app composition root mounts all three explicitly. +- rationale: Named pools make the topology explicit at the orchestrator boundary and insulate primary projection latency without claiming Workpool ordering the platform does not have. +- consequence: Primary projection latency is insulated from saga and fanout bursts, and those queues become separately observable. +- consequence: App infrastructure must mount and wire more named Workpool components, and tests and codegen must stay aligned with the expanded topology. diff --git a/specs/decisions/pdr-017-tranche-3-platform-architecture-gate.sdp.md b/specs/decisions/pdr-017-tranche-3-platform-architecture-gate.sdp.md new file mode 100644 index 00000000..7cdc2f1b --- /dev/null +++ b/specs/decisions/pdr-017-tranche-3-platform-architecture-gate.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-017-tranche-3-platform-architecture-gate +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-017 - Tranche 3 Platform Architecture Gate + +## Intent + +- outcome: Choose the smallest tranche-3 packet that removes duplicated contracts without starting a platform-core or platform-store split. + +## Decision + +- context: Tranche-3 work splits into cheap shared-contract extraction, medium cleanup and layering enforcement, and expensive full package splits. platform-core root exports are broad, platform-store and platform-bus still reach into platform-core, and too many consumers still import those broad surfaces, so a full split now would become a multi-package migration program. +- decision: Do not split platform-core or platform-store in tranche-3 packet 9. Extract EventCategory, ProcessManagerStatus, and DCB scope-key contracts into the zero-dependency package @libar-dev/platform-contracts-shared now; keep CommandBus and EventStore client classes as a deferred later replacement by functions; run P41 as a transitional lint:layers guard that freezes known bus/store reach-throughs; reject P42 and P43 for this packet while AC2 remains deferred follow-on work under this gate. +- rationale: Shared-contract extraction is the cheapest high-value boundary improvement and reduces duplication immediately without forcing a migration wave across every platform consumer. +- consequence: Tranche-3 closes real duplication now without starting an uncontrolled split, and later cleanup packets can proceed against resolved design questions. +- consequence: Root-export slimming, client-class removal, and remaining bus/store reach-throughs stay follow-on work, frozen from growing by the layering command. diff --git a/specs/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.sdp.md b/specs/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.sdp.md new file mode 100644 index 00000000..d939a45e --- /dev/null +++ b/specs/decisions/pdr-018-idempotency-enforcement-for-append-to-stream.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-018-idempotency-enforcement-for-append-to-stream +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-018 - Idempotency Enforcement for appendToStream + +## Intent + +- outcome: Make appendToStream honor idempotencyKey as an enforced contract instead of write-only metadata. + +## Decision + +- context: The old contract exposed and indexed events[].idempotencyKey and documented idempotent behavior, but the append path treated the key as write-only metadata, so retries could silently create duplicate or conflicting rows. Same key plus same payload must converge; same key plus different payload must not be silently deduplicated; idempotentAppendEvent() and appendToStream() must agree. +- decision: For every incoming event with an idempotencyKey, the Event Store fingerprints streamType, streamId, boundedContext, tenantId, eventType, category, schemaVersion, and payload. Same key and fingerprint returns duplicate with the original eventIds, globalPositions, and newVersion; same key and different fingerprint returns idempotency_conflict and persists an audit record; mixed or partial duplicate batches are rejected as idempotency_conflict; no key match continues normal append plus OCC. idempotentAppendEvent() follows the same rule rather than a softer pre-check. +- rationale: Semantic fingerprints distinguish retry of the same intent from conflicting reuse of a key, and a durable audit trail makes rejected attempts inspectable. +- consequence: Retries with the same intent converge to one durable event row, and conflicting key reuse is visible instead of swallowed. +- consequence: Direct appendToStream callers must handle duplicate and idempotency_conflict distinctly, and mixed duplicate batches cannot rely on partial success. diff --git a/specs/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.sdp.md b/specs/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.sdp.md new file mode 100644 index 00000000..47ae5227 --- /dev/null +++ b/specs/decisions/pdr-019-v-any-vs-v-unknown-boundary-policy.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-019-v-any-vs-v-unknown-boundary-policy +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-019 - v.any() vs v.unknown() Boundary Policy + +## Intent + +- outcome: Keep flexible component payload fields open in shape while bounding their serialized size. + +## Decision + +- context: Payload-like component boundaries intentionally store flexible values but used v.any() with no serialized-size guard, so type checks were weaker than needed and large payloads could cross the boundary until Convex or downstream code failed later. +- decision: Flexible storage and transport validators use v.unknown() instead of v.any(), with a default 64 KiB serialized-size cap that throws PAYLOAD_TOO_LARGE with field-specific context; a component may set a local constant when it needs a different cap. In-scope fields include payload, result, customState, configOverrides, failed-command payload, and debug context. +- rationale: v.unknown() plus an explicit size guard keeps the value shape flexible while making oversized failures deterministic before persistence. +- consequence: Oversized payload failures become deterministic and testable, and bus, store, and agent surfaces can share one validation helper. +- consequence: Callers that relied on arbitrarily large payloads now receive explicit rejections, and new flexible fields must opt into the shared size-guard policy. diff --git a/specs/decisions/pdr-020-events-table-index-policy.sdp.md b/specs/decisions/pdr-020-events-table-index-policy.sdp.md new file mode 100644 index 00000000..2b1758bd --- /dev/null +++ b/specs/decisions/pdr-020-events-table-index-policy.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-020-events-table-index-policy +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-020 - events Table Index Policy + +## Intent + +- outcome: Align events-table indexes with the live readFromPosition path and drop unused indexes only after audit. + +## Decision + +- context: The event store had accumulated indexes whose usage no longer matched the active read path. Removing them too early would be a breaking change; leaving them forever keeps append cost higher than necessary. Consumers must migrate first, removal must be repo-backed, and re-adding a removed index remains the rollback. +- decision: Replace by_event_type with by_event_type_and_global_position for readFromPosition event-type filtering, and drop by_bounded_context, by_event_id, and by_category after audit showed no remaining in-repo consumer. Replay and catch-up consume { events, nextPosition, hasMore } from readFromPosition. A missed consumer discovered after merge is fixed by re-adding the required index in a follow-up patch. +- rationale: The replacement compound index matches pagination by event type and global position, and dead indexes are removed only after verified consumer usage so append cost drops without guessing. +- consequence: Event-type catch-up gets an index aligned to its pagination key, and dropping dead indexes reduces write amplification on events. +- consequence: Future event-table indexes require an explicit consumer audit before removal, and missed out-of-repo consumers still need a re-add path. diff --git a/specs/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.sdp.md b/specs/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.sdp.md new file mode 100644 index 00000000..8907212e --- /dev/null +++ b/specs/decisions/pdr-021-platform-store-runtime-dependency-on-platform-core.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-021-platform-store-runtime-dependency-on-platform-core +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-021 - platform-store Runtime Dependency on platform-core Accepted with Constraints + +## Intent + +- outcome: Record the live platform-store to platform-core runtime seam as a frozen public-subpath allowlist instead of calling the dependency phantom. + +## Decision + +- context: @libar-dev/platform-store still declares @libar-dev/platform-core because package managers operate at the package boundary. Live imports already use a narrow public subset (events, security, durability, validation, processManager). AC4 asked whether that dependency was phantom; AC2's full platform-core split remains deferred to PDR-017 follow-on work. +- decision: Keep the runtime dependency only for those five public subpaths. Forbid the platform-core root barrel, src/** internals, and any other platform-core surface (agent, orchestration, reservations, DCB, monitoring, testing). New imports outside the allowlist are not incremental convenience changes; further growth requires extracting a smaller boundary under the tranche-3 path rather than widening this set. +- rationale: Shared global-position, verification-proof, idempotency, validation, and process-manager invariants must stay identical across store and consumers without pretending the live seam does not exist or splitting packages in this packet. +- consequence: AC4 is resolved by recording the real dependency shape, and README, layer-policy, and future extraction work share one allowlist. +- consequence: platform-store still depends on platform-core at the package boundary until a later extraction, and growth beyond the approved set needs a follow-up decision. diff --git a/specs/decisions/pdr-022-value-transfer-doctrine-adoption.sdp.md b/specs/decisions/pdr-022-value-transfer-doctrine-adoption.sdp.md new file mode 100644 index 00000000..154f8bb5 --- /dev/null +++ b/specs/decisions/pdr-022-value-transfer-doctrine-adoption.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-022-value-transfer-doctrine-adoption +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-022 Value-Transfer Doctrine Adoption and Naming Contract + +## Intent + +- outcome: Adopt in-repo doctrine and keep semantic pattern names distinct from later executable-carrier artifact names. + +## Decision + +- context: Live architect sources cited doctrine that existed only on the off-branch architect-studio/.../_shared/ path, so guidance was not self-contained. The repo also needed a naming contract for shipped patterns whose executable carriers were created later, including whether EventStoreFoundationExecutableTests should replace the semantic name EventStoreFoundation or merely carry it. +- decision: The in-repo doctrine set under libar-platform/architect/_shared/ is the authoritative guidance for value transfer, annotation ownership, pattern-carrier relationships, maturity classification, and FSM interpretation. Semantic pattern names stay bare; ExecutableTests suffixes name the proving artifact only; @architect-implements is the durable continuity edge back to the bare name, while @architect-pattern on a carrier names the artifact node. +- rationale: Bare names remain the canonical references used by roadmap specs, decisions, and graph work, so executable carriers can exist without renaming the underlying concept. +- consequence: The repo no longer relies on off-branch doctrine paths, and executable carriers do not distort semantic pattern identity. +- consequence: Contributors must maintain the local doctrine surface and learn that artifact names are not interchangeable with semantic pattern names. diff --git a/specs/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.sdp.md b/specs/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.sdp.md new file mode 100644 index 00000000..2651cf2a --- /dev/null +++ b/specs/decisions/pdr-023-bulk-doctrine-rollback-and-recovery.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:decisions.pdr-023-bulk-doctrine-rollback-and-recovery +kind: decision +altitude: feature +readiness: defined +relations: + refines: spec:decisions.process +--- +# PDR-023 Bulk Doctrine Rollback and Recovery Governance + +## Intent + +- outcome: Name how to undo a bulk doctrine packet, recover one pattern, or repair a transitional carrier without silent deferred work. + +## Decision + +- context: The doctrine cleanup branch deleted 19 standard gate-passing design specs, applied two narrative-only deletion exemptions, kept three specs blocked, and left four carve-out executable carriers completed but transitional. Review finding CI10 showed there was no in-repo protocol for undoing part of that packet; CI7, CI9, and CI12 showed deferred follow-up and reviewer duties were still mostly implicit. +- decision: Whole-packet failure is reverted as one git change set, then docs generation and the standard test.yml lanes rerun. Subset recovery restores only the affected spec and its paired continuity tags, carrier text, and report rows for that semantic pattern. A wrong transitional carve-out is repaired in place without restoring the deleted design spec. Deferred items T5-009 harness wiring, T5-010 expansion, saga fixture extraction, and commitlint stay named as deferred; release governance may summarize doctrine posture but must not become a second hard gate. +- rationale: Rollback decisions are made per semantic pattern group, not per touched file, so a live @architect-implements edge cannot point at a transfer that no longer claims to exist. +- consequence: Maintainers have a named protocol for restoring one pattern, one carve-out carrier, or the full packet, and deferred work stays visible instead of looking completed. +- consequence: Selective recovery still needs careful paired edits because git cannot infer semantic pattern boundaries, and transitional carve-out carriers plus missing commitlint remain until later follow-up. diff --git a/specs/epic-process-enhancements.sdp.md b/specs/epic-process-enhancements.sdp.md new file mode 100644 index 00000000..1ed2da72 --- /dev/null +++ b/specs/epic-process-enhancements.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.epic-process-enhancements +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# Process Enhancements - Unified Software Delivery Process + +## Intent + +- outcome: Current delivery process capabilities are limited to document generation. The convergence roadmap identified 8 opportunities: Process Views as Projections, DoD as Machine-Checkable, Earned-Value Tracking, Requirements-Tests Traceability, Architecture Change Control, Progressive Governance, and Living Roadmap. +- problem: Current delivery process capabilities are limited to document generation. The convergence roadmap identified 8 opportunities: Process Views as Projections, DoD as Machine-Checkable, Earned-Value Tracking, Requirements-Tests Traceability, Architecture Change Control, Progressive Governance, and Living Roadmap. +- value: Incrementally implement convergence opportunities, starting with foundation work (metadata tags) and progressing to validators, generators, and eventually Convex-native live projections. diff --git a/specs/example-app/agent-admin-frontend.sdp.md b/specs/example-app/agent-admin-frontend.sdp.md new file mode 100644 index 00000000..bc0ded60 --- /dev/null +++ b/specs/example-app/agent-admin-frontend.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.agent-admin-frontend +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Agent Admin Frontend - Complete Management UI with Multi-Agent Support + +## Intent + +- outcome: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. +- value: Complete the agent admin frontend with multi-agent support: 1. + +## Behavior + +- rule: Dead letters are visible and actionable +- rule: Decision history supports multi-agent filtering +- rule: Actions provide feedback via toast +- rule: High-value order agent functions end-to-end +- rule: Dashboard reflects multi-agent state diff --git a/specs/platform-patterns.pack.sdp.md b/specs/platform-patterns.pack.sdp.md new file mode 100644 index 00000000..42e425ed --- /dev/null +++ b/specs/platform-patterns.pack.sdp.md @@ -0,0 +1,115 @@ +--- +id: pack:platform-patterns +specs: + - spec:platform.active-reservations-projection + - spec:platform.agent-action-handler + - spec:platform.agent-as-bounded-context + - spec:platform.agent-churn-risk-completion + - spec:platform.agent-churn-risk-completion-executable-tests + - spec:platform.agent-on-complete-handler + - spec:platform.app-composition-root + - spec:platform.bdd-testing-infrastructure + - spec:platform.bdd-testing-infrastructure-executable-tests + - spec:platform.bdd-world + - spec:platform.bounded-context-foundation + - spec:platform.bounded-context-foundation-executable-tests + - spec:platform.bounded-context-identity + - spec:platform.cms-dual-write + - spec:platform.cms-repository + - spec:platform.command-bus + - spec:platform.command-bus-foundation + - spec:platform.command-bus-foundation-executable-tests + - spec:platform.command-bus-idempotency + - spec:platform.command-orchestrator + - spec:platform.command-registry + - spec:platform.confirmed-order-cancellation-executable-tests + - spec:platform.correlation-chain-system + - spec:platform.cross-context-read-model + - spec:platform.customer-cancellations-projection + - spec:platform.data-table-parsing + - spec:platform.dcb-multi-product-reservation + - spec:platform.dcb-retry-execution + - spec:platform.dcb-scope-key-utilities + - spec:platform.dcb-types + - spec:platform.decider-assertions + - spec:platform.decider-outputs + - spec:platform.decider-pattern + - spec:platform.dual-write-contract + - spec:platform.durable-append-action + - spec:platform.durable-events-integration + - spec:platform.durable-events-integration-executable-tests + - spec:platform.durable-function-adapters + - spec:platform.dynamic-consistency-boundaries + - spec:platform.ecst-fat-events + - spec:platform.event-bus-abstraction + - spec:platform.event-replay-infrastructure + - spec:platform.event-store + - spec:platform.event-store-durability + - spec:platform.event-store-foundation + - spec:platform.event-store-foundation-executable-tests + - spec:platform.event-subscription-registry + - spec:platform.event-upcasting + - spec:platform.example-app-architecture + - spec:platform.example-app-modernization + - spec:platform.example-app-modernization-executable-tests + - spec:platform.fsm-assertions + - spec:platform.fsm-transitions + - spec:platform.handler-factories + - spec:platform.integration-dead-letters + - spec:platform.integration-event-handlers + - spec:platform.integration-event-schemas + - spec:platform.integration-patterns-21-a + - spec:platform.integration-patterns-21-b + - spec:platform.integration-routes + - spec:platform.invariant-framework + - spec:platform.inventory-command-configs + - spec:platform.inventory-command-handlers + - spec:platform.inventory-deciders + - spec:platform.inventory-domain-events + - spec:platform.inventory-internal-mutations + - spec:platform.inventory-public-api + - spec:platform.logging-infrastructure + - spec:platform.middleware-pipeline + - spec:platform.mock-payment-actions + - spec:platform.order-command-configs + - spec:platform.order-command-handlers + - spec:platform.order-deciders + - spec:platform.order-domain-events + - spec:platform.order-fulfillment-saga + - spec:platform.order-items-projection + - spec:platform.order-management-infrastructure + - spec:platform.order-notification-pm + - spec:platform.order-public-api + - spec:platform.order-summary-projection + - spec:platform.order-with-inventory-projection + - spec:platform.payment-outbox-handler + - spec:platform.polling-utilities + - spec:platform.process-manager + - spec:platform.process-manager-lifecycle + - spec:platform.product-catalog-projection + - spec:platform.projection-categories + - spec:platform.projection-categories-executable-tests + - spec:platform.projection-checkpointing + - spec:platform.projection-dead-letters + - spec:platform.projection-definitions + - spec:platform.query-abstraction + - spec:platform.rate-limit-definitions + - spec:platform.reactive-projection-conflict-detection + - spec:platform.reactive-projection-eligibility + - spec:platform.reactive-projection-hybrid-model + - spec:platform.reactive-projection-shared-evolve + - spec:platform.reactive-projections + - spec:platform.reservation-pattern + - spec:platform.reservation-release-pm + - spec:platform.saga-completion-handler + - spec:platform.saga-orchestration + - spec:platform.saga-orchestration-executable-tests + - spec:platform.saga-registry + - spec:platform.saga-router + - spec:platform.test-environment-guards + - spec:platform.test-isolation + - spec:platform.workpool-partitioning-strategy +--- +# Platform patterns + +Code-originated pattern Specs derived from former @architect-pattern / @architect-implements bindings. diff --git a/specs/platform.pack.sdp.md b/specs/platform.pack.sdp.md new file mode 100644 index 00000000..32a9a7f2 --- /dev/null +++ b/specs/platform.pack.sdp.md @@ -0,0 +1,136 @@ +--- +id: pack:platform +specs: + - spec:platform.active-reservations-projection + - spec:platform.admin-tooling-consolidation + - spec:platform.agent-action-handler + - spec:platform.agent-as-bounded-context + - spec:platform.agent-bc-component-isolation + - spec:platform.agent-churn-risk-completion + - spec:platform.agent-churn-risk-completion-executable-tests + - spec:platform.agent-command-infrastructure + - spec:platform.agent-llm-integration + - spec:platform.agent-on-complete-handler + - spec:platform.app-composition-root + - spec:platform.bdd-testing-infrastructure + - spec:platform.bdd-testing-infrastructure-executable-tests + - spec:platform.bdd-world + - spec:platform.bounded-context-foundation + - spec:platform.bounded-context-foundation-executable-tests + - spec:platform.bounded-context-identity + - spec:platform.circuit-breaker-pattern + - spec:platform.cms-dual-write + - spec:platform.cms-repository + - spec:platform.codec-driven-reference-generation + - spec:platform.command-bus + - spec:platform.command-bus-foundation + - spec:platform.command-bus-foundation-executable-tests + - spec:platform.command-bus-idempotency + - spec:platform.command-orchestrator + - spec:platform.command-registry + - spec:platform.component-boundary-authentication-convention + - spec:platform.confirmed-order-cancellation + - spec:platform.confirmed-order-cancellation-executable-tests + - spec:platform.correlation-chain-system + - spec:platform.cross-context-read-model + - spec:platform.customer-cancellations-projection + - spec:platform.data-table-parsing + - spec:platform.dcb-api-reference + - spec:platform.dcb-multi-product-reservation + - spec:platform.dcb-retry-execution + - spec:platform.dcb-scope-key-utilities + - spec:platform.dcb-types + - spec:platform.decider-assertions + - spec:platform.decider-outputs + - spec:platform.decider-pattern + - spec:platform.deterministic-id-hashing + - spec:platform.dual-write-contract + - spec:platform.durable-append-action + - spec:platform.durable-events-integration + - spec:platform.durable-events-integration-executable-tests + - spec:platform.durable-function-adapters + - spec:platform.dynamic-consistency-boundaries + - spec:platform.ecst-fat-events + - spec:platform.epic-process-enhancements + - spec:platform.event-bus-abstraction + - spec:platform.event-correctness-migration + - spec:platform.event-replay-infrastructure + - spec:platform.event-store + - spec:platform.event-store-durability + - spec:platform.event-store-foundation + - spec:platform.event-store-foundation-executable-tests + - spec:platform.event-subscription-registry + - spec:platform.event-upcasting + - spec:platform.example-app-architecture + - spec:platform.example-app-modernization + - spec:platform.example-app-modernization-executable-tests + - spec:platform.fsm-assertions + - spec:platform.fsm-transitions + - spec:platform.handler-factories + - spec:platform.health-observability + - spec:platform.integration-dead-letters + - spec:platform.integration-event-handlers + - spec:platform.integration-event-schemas + - spec:platform.integration-patterns-21-a + - spec:platform.integration-patterns-21-b + - spec:platform.integration-patterns-21a + - spec:platform.integration-patterns-21b + - spec:platform.integration-routes + - spec:platform.invariant-framework + - spec:platform.inventory-command-configs + - spec:platform.inventory-command-handlers + - spec:platform.inventory-deciders + - spec:platform.inventory-domain-events + - spec:platform.inventory-internal-mutations + - spec:platform.inventory-public-api + - spec:platform.logging-infrastructure + - spec:platform.middleware-pipeline + - spec:platform.mock-payment-actions + - spec:platform.order-command-configs + - spec:platform.order-command-handlers + - spec:platform.order-deciders + - spec:platform.order-domain-events + - spec:platform.order-fulfillment-saga + - spec:platform.order-items-projection + - spec:platform.order-management-infrastructure + - spec:platform.order-notification-pm + - spec:platform.order-public-api + - spec:platform.order-summary-projection + - spec:platform.order-with-inventory-projection + - spec:platform.package-architecture + - spec:platform.payment-outbox-handler + - spec:platform.polling-utilities + - spec:platform.process-manager + - spec:platform.process-manager-lifecycle + - spec:platform.product-catalog-projection + - spec:platform.production-hardening + - spec:platform.projection-categories + - spec:platform.projection-categories-executable-tests + - spec:platform.projection-checkpointing + - spec:platform.projection-dead-letters + - spec:platform.projection-definitions + - spec:platform.query-abstraction + - spec:platform.rate-limit-definitions + - spec:platform.reactive-projection-conflict-detection + - spec:platform.reactive-projection-eligibility + - spec:platform.reactive-projection-hybrid-model + - spec:platform.reactive-projection-shared-evolve + - spec:platform.reactive-projections + - spec:platform.reservation-pattern + - spec:platform.reservation-release-pm + - spec:platform.saga-completion-handler + - spec:platform.saga-orchestration + - spec:platform.saga-orchestration-executable-tests + - spec:platform.saga-registry + - spec:platform.saga-router + - spec:platform.test-environment-guards + - spec:platform.test-isolation + - spec:platform.themed-decision-architecture + - spec:platform.tranche-0-readiness-harness-and-dependency-hardening + - spec:platform.tranche-0-release-ci-and-docs-process-guardrails + - spec:platform.tranche-1-supporting-security-and-contract-sweep + - spec:platform.workpool-partitioning-strategy +--- +# Platform + +Platform delivery Specs migrated from the former architect corpus, including code-originated pattern Specs. diff --git a/specs/platform/admin-tooling-consolidation.sdp.md b/specs/platform/admin-tooling-consolidation.sdp.md new file mode 100644 index 00000000..5443c6dd --- /dev/null +++ b/specs/platform/admin-tooling-consolidation.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:platform.admin-tooling-consolidation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Admin Tooling Consolidation - Unified Operations Interface + +## Intent + +- outcome: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. +- value: Consolidate admin functionality into 'convex/admin/' directory: - **projections.ts** - Rebuild triggers, status, checkpoint management - **deadLetters.ts** - DLQ inspection, retry, ignore (refactored from current location) - **diagnostics.ts** - Event flow trace, system state snapshot - **durableFunctions.ts** - Workpool/Workflow run inspection + +## Behavior + +- rule: Admin directory provides unified location for operational endpoints +- rule: DLQ endpoints provide inspection, retry, and ignore operations +- rule: System state snapshot provides full health picture +- rule: Admin endpoints require authorization diff --git a/specs/platform/agent-bc-component-isolation.sdp.md b/specs/platform/agent-bc-component-isolation.sdp.md new file mode 100644 index 00000000..744a4dae --- /dev/null +++ b/specs/platform/agent-bc-component-isolation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.agent-bc-component-isolation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Agent BC Component Isolation - Physical Bounded Context Enforcement + +## Intent + +- outcome: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. +- value: Implement agent as a proper Convex component: 1. **'defineComponent("agent")'** with isolated schema and private tables 2. diff --git a/specs/platform/agent-command-infrastructure.sdp.md b/specs/platform/agent-command-infrastructure.sdp.md new file mode 100644 index 00000000..4788dd3a --- /dev/null +++ b/specs/platform/agent-command-infrastructure.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.agent-command-infrastructure +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Agent Command Infrastructure - Routing, Lifecycle, and Pattern Unification + +## Intent + +- outcome: Three interconnected gaps in agent command infrastructure: 1. +- problem: Three interconnected gaps in agent command infrastructure: 1. +- value: Complete agent command infrastructure: 1. + +## Behavior + +- rule: Emitted commands are routed to handlers +- rule: Agent lifecycle is controlled via commands +- rule: Pattern definitions are the single source of truth diff --git a/specs/platform/agent-llm-integration.sdp.md b/specs/platform/agent-llm-integration.sdp.md new file mode 100644 index 00000000..d41e6fba --- /dev/null +++ b/specs/platform/agent-llm-integration.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.agent-llm-integration +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Agent LLM Integration - Action/Mutation Split and Cost Control + +## Intent + +- outcome: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. +- value: Implement hybrid action/mutation handler pattern: 1. + +## Behavior + +- rule: Rate limiting is enforced before LLM calls +- rule: Agent subscriptions support onComplete callbacks diff --git a/specs/platform/circuit-breaker-pattern.sdp.md b/specs/platform/circuit-breaker-pattern.sdp.md new file mode 100644 index 00000000..91f82527 --- /dev/null +++ b/specs/platform/circuit-breaker-pattern.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.circuit-breaker-pattern +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Circuit Breaker Pattern - External Service Resilience + +## Intent + +- outcome: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back +- value: Database-backed circuit breaker with state machine: - + +## Behavior + +- rule: Circuit breaker follows three-state machine +- rule: Half-open probes use Action Retrier with zero retries diff --git a/specs/platform/component-boundary-authentication-convention.sdp.md b/specs/platform/component-boundary-authentication-convention.sdp.md new file mode 100644 index 00000000..2fd7473b --- /dev/null +++ b/specs/platform/component-boundary-authentication-convention.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.component-boundary-authentication-convention +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Atomic Component-Boundary Authentication Convention + +## Intent + +- outcome: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. +- value: Plan P11 as one atomic remediation packet: PDR-014 defines the canonical 'verificationProof' contract, the 'verifyActor()' helper becomes the default component-side gate, and all listed mutation sites migrate in the same implementation session. + +## Behavior + +- rule: P11 ships as one atomic packet +- rule: Verification is component-side and defaults to deny diff --git a/specs/platform/confirmed-order-cancellation.sdp.md b/specs/platform/confirmed-order-cancellation.sdp.md new file mode 100644 index 00000000..993c20d1 --- /dev/null +++ b/specs/platform/confirmed-order-cancellation.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.confirmed-order-cancellation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Confirmed Order Cancellation with Reservation Release + +## Intent + +- outcome: The Order FSM treats 'confirmed' as terminal. Orders cannot be cancelled after saga confirmation, blocking the Agent BC demo which requires 3+ cancellations to trigger churn risk detection. The Reservation FSM already supports 'confirmed -) released', but no coordination exists to release reservations when confirmed orders are cancelled. +- problem: The Order FSM treats 'confirmed' as terminal. Orders cannot be cancelled after saga confirmation, blocking the Agent BC demo which requires 3+ cancellations to trigger churn risk detection. The Reservation FSM already supports 'confirmed -) released', but no coordination exists to release reservations when confirmed orders are cancelled. +- value: Enable cancellation of confirmed orders with automatic reservation release: 1. + +## Behavior + +- rule: Confirmed orders can be cancelled +- rule: Reservation is released when confirmed order is cancelled diff --git a/specs/platform/deterministic-id-hashing.sdp.md b/specs/platform/deterministic-id-hashing.sdp.md new file mode 100644 index 00000000..f027b335 --- /dev/null +++ b/specs/platform/deterministic-id-hashing.sdp.md @@ -0,0 +1,21 @@ +--- +id: spec:platform.deterministic-id-hashing +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Deterministic ID Hashing - OCC-Based Uniqueness Without TTL + +## Intent + +- outcome: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. +- problem: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. +- value: Generate entity stream ID from unique business key via deterministic hash. Concurrent creates target the same stream ID; OCC detects conflict automatically. + +## Behavior + +- rule: Stream ID is deterministic from business key +- rule: OCC prevents duplicate creation +- rule: Hash algorithm is collision-resistant +- rule: Pattern complements Reservation Pattern diff --git a/specs/platform/event-correctness-migration.sdp.md b/specs/platform/event-correctness-migration.sdp.md new file mode 100644 index 00000000..5dba1753 --- /dev/null +++ b/specs/platform/event-correctness-migration.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.event-correctness-migration +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Atomic Event Correctness Migration + +## Intent + +- outcome: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. +- value: Plan P14, P17, and P18 as one correctness packet. Implementation starts with a full consumer inventory, lands PDR-018 and PDR-015 first, then migrates idempotency, 'globalPosition', and canonical process-manager transitions together. + +## Behavior + +- rule: P14, P17, and P18 remain one correctness packet +- rule: Compatibility and ordering remain explicit diff --git a/specs/platform/generated-docs/dcb-api-reference.feature b/specs/platform/generated-docs/dcb-api-reference.feature deleted file mode 100644 index 41051b20..00000000 --- a/specs/platform/generated-docs/dcb-api-reference.feature +++ /dev/null @@ -1,169 +0,0 @@ -@architect -@architect-pattern:DCBAPIReference -@architect-status:active -@architect-phase:99 -@architect-core -@architect-ddd -@architect-claude-md-section:platform -Feature: DCB API Reference - Auto-Generated Documentation - - This feature file demonstrates code-first documentation generation. - The API reference is extracted directly from annotated TypeScript source files, - proving that documentation can be a projection of code. - - **Key Insight:** DCB enables cross-entity invariant validation within a single - bounded context with scope-based OCC. - - Rule: Source Mapping - Content Extraction Configuration - - The following table defines which content is extracted from which source files: - -| Section | Source File | Extraction Method | -| --- | --- | --- | -| Core Types | packages/platform-core/src/dcb/types.ts | @extract-shapes tag | -| Scope Key Utilities | packages/platform-core/src/dcb/scopeKey.ts | @extract-shapes tag | -| executeWithDCB Flow | THIS DECISION | Fenced code block (Mermaid) | -| Usage Example | THIS DECISION | Fenced code block | -| Constraints | THIS DECISION | Rule block table | -| Guarantees | THIS DECISION | Rule block table | - - **Usage Example:** - - """typescript - import { executeWithDCB, createScopeKey } from "@libar-dev/platform-core/dcb"; - - const result = await executeWithDCB(ctx, { - scopeKey: createScopeKey("tenant_1", "reservation", "res_123"), - expectedVersion: 0, - boundedContext: "inventory", - streamType: "Reservation", - schemaVersion: 1, - entities: { - streamIds: ["product-1", "product-2"], - loadEntity: async (ctx, streamId) => { - const product = await inventoryRepo.tryLoad(ctx, streamId); - return product ? { cms: product, _id: product._id } : null; - }, - }, - decider: reserveMultipleDecider, - command: { orderId: "order_456", items }, - applyUpdate: async (ctx, _id, cms, update, version, timestamp) => { - await ctx.db.patch(_id, { ...update, version, updatedAt: timestamp }); - }, - commandId: "cmd_789", - correlationId: "corr_abc", - }); - - switch (result.status) { - case "success": - // Append result.events to Event Store - break; - case "rejected": - // Business rule violation - result.code, result.reason - break; - case "conflict": - // OCC conflict - retry with fresh state - break; - } - """ - - Rule: Context - Why DCB Exists - - **Problem:** Traditional approaches to multi-entity coordination have significant - drawbacks: - - **Saga coordination** provides only eventual consistency - - **Sequential commands** create race condition windows - - **Aggregate enlargement** violates single responsibility - - **Solution:** DCB provides atomic validation across multiple entities with - scope-based optimistic concurrency control (OCC), all within a single - bounded context. - - Rule: Decision - Scope-Based OCC - - DCB uses a scope key to coordinate multiple entities atomically. - - **Scope Key Format:** `tenant:${tenantId}:${scopeType}:${scopeId}` - - The tenant prefix is mandatory to ensure multi-tenant isolation at the scope level. - - Rule: Decision - executeWithDCB Flow - - The following diagram shows the step-by-step flow of the `executeWithDCB` function: - - """mermaid - flowchart TD - A[1. Validate Scope Key] --> B[2. Load All Entities] - B --> C[3. Build Aggregated State] - C --> D[4. Execute Pure Decider] - D --> E{Result Status?} - E -->|rejected| F[Return Rejection
No events, no state changes] - E -->|failed| G[Return Failure
With failure event] - E -->|success| H[5. Check Scope Version OCC] - H --> I{Version Match?} - I -->|no| J[Return Conflict
currentVersion in result] - I -->|yes| K[6. Apply State Updates] - K --> L[7. Return Success
data + scopeVersion + events] - - style A fill:#e1f5fe - style D fill:#fff3e0 - style E fill:#fce4ec - style I fill:#fce4ec - style L fill:#e8f5e9 - """ - - **Step Details:** - - 1. **Validate Scope Key** - Ensures tenant prefix is present for isolation - 2. **Load All Entities** - Calls `loadEntity()` for each streamId in config - 3. **Build Aggregated State** - Creates `DCBAggregatedState` with all entities - 4. **Execute Pure Decider** - Calls decider function with aggregated state - 5. **Check Scope Version** - OCC validation via `scopeOperations.commitScope()` - 6. **Apply State Updates** - Calls `applyUpdate()` for each entity with changes - 7. **Return Success** - Returns data, new scopeVersion, and events to append - - Rule: Consequences - When to Use DCB vs Alternatives - -| Criterion | DCB | Saga | Regular Decider | -| --- | --- | --- | --- | -| Scope | Single BC | Cross-BC | Single entity | -| Consistency | Atomic | Eventual | Atomic | -| Use Case | Multi-product reservation | Order fulfillment | Simple updates | - - Rule: Consequences - Constraints and Error Codes - - **Mandatory Constraints:** - -| Constraint | Enforcement | Error Code | -| --- | --- | --- | -| Single bounded context only | Runtime validation | CROSS_BC_NOT_ALLOWED | -| Tenant-aware scope key | Scope key format | TENANT_ID_REQUIRED | -| Non-empty scope components | Scope key validation | SCOPE_KEY_EMPTY | -| Valid scope key format | Regex validation | INVALID_SCOPE_KEY_FORMAT | -| Decider must be pure | Design pattern | N/A (enforced by types) | - - **Scope Key Validation:** - - The `tenant:` prefix is mandatory in all scope keys - - Empty `tenantId`, `scopeType`, or `scopeId` are rejected - - Colons are not allowed in `tenantId` or `scopeType` (but allowed in `scopeId`) - - Rule: Consequences - Guarantees - - **System Guarantees:** - -| Guarantee | How Enforced | -| --- | --- | -| Tenant isolation | Scope key must include tenant prefix; validated at creation | -| Atomicity | All state updates + scope commit in same Convex mutation | -| OCC protection | Scope version checked before commit; conflict returns currentVersion | -| No partial updates | Rejected/failed status means no CMS changes persisted | -| Decider purity | Type system enforces no ctx/I/O in decider function signature | -| Event immutability | Events returned for caller to append; not modified by DCB | - - **Conflict Resolution:** - When an OCC conflict occurs (`status: "conflict"`), the caller should: - 1. Reload the current scope version from the result - 2. Re-fetch entity state - 3. Retry the operation with updated `expectedVersion` - - The `withDCBRetry` helper automates this pattern via Workpool scheduling. diff --git a/specs/platform/generated-docs/dcb-api-reference.sdp.md b/specs/platform/generated-docs/dcb-api-reference.sdp.md new file mode 100644 index 00000000..55f19354 --- /dev/null +++ b/specs/platform/generated-docs/dcb-api-reference.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.dcb-api-reference +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DCB API reference — code-first documentation + +## Intent + +- outcome: Project DCB API reference documentation from annotated TypeScript sources so docs stay a regenerable view of code, not a hand-maintained twin. diff --git a/specs/platform/health-observability.sdp.md b/specs/platform/health-observability.sdp.md new file mode 100644 index 00000000..c06f2ed3 --- /dev/null +++ b/specs/platform/health-observability.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.health-observability +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Health Endpoints and Metrics Collection + +## Intent + +- outcome: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. +- value: Production-ready observability infrastructure: - + +## Behavior + +- rule: Health endpoints support Kubernetes probes +- rule: Projection lag tracks distance from Event Store head diff --git a/specs/platform/integration-patterns-21a.sdp.md b/specs/platform/integration-patterns-21a.sdp.md new file mode 100644 index 00000000..0b1c88b5 --- /dev/null +++ b/specs/platform/integration-patterns-21a.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.integration-patterns-21a +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Integration Patterns (21a) - Registry & Core Patterns + +## Intent + +- outcome: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. +- value: Foundational patterns for cross-context communication: - + +## Behavior + +- rule: Context Map documents BC relationships +- rule: Published Language defines stable contracts +- rule: ACL translates external models diff --git a/specs/platform/integration-patterns-21b.sdp.md b/specs/platform/integration-patterns-21b.sdp.md new file mode 100644 index 00000000..3a9dea61 --- /dev/null +++ b/specs/platform/integration-patterns-21b.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.integration-patterns-21b +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Integration Patterns (21b) - Schema Evolution & Contract Testing + +## Intent + +- outcome: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. +- value: Schema evolution and contract testing patterns: - + +## Behavior + +- rule: Schema versioning enables evolution +- rule: Contract tests validate integration diff --git a/specs/platform/package-architecture.sdp.md b/specs/platform/package-architecture.sdp.md new file mode 100644 index 00000000..ea40624a --- /dev/null +++ b/specs/platform/package-architecture.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.package-architecture +kind: model +altitude: epic +readiness: idea +relations: {} +--- +# Package Architecture - Extraction and Naming Strategy + +## Intent + +- outcome: The original @convex-es/core package grew to 25+ modules, creating issues: - Large bundle size for consumers who only need specific patterns - Unclear API surface (what's core vs experimental?) - Testing sprawl (decider tests in example app, not package) - Difficult to release patterns independently +- problem: The original @convex-es/core package grew to 25+ modules, creating issues: - Large bundle size for consumers who only need specific patterns - Unclear API surface (what's core vs experimental?) - Testing sprawl (decider tests in example app, not package) - Difficult to release patterns independently +- value: Extract focused pattern packages under @libar-dev/platform-* namespace with a layered architecture enforcing strict dependency direction. Naming rationale: - "Libar" means book/library, repository of knowledge/wisdom - Events ARE the institutional memory - the "libar" of the system - "Platform" indicates infrastructure for building applications + +## Behavior + +- rule: Layer 0 packages have no framework dependencies +- rule: Consumers can install individual packages +- rule: Tests ship with framework packages +- rule: Backward compatibility is maintained +- rule: No naming conflicts with libar-ai project diff --git a/specs/platform/patterns/active-reservations-projection.sdp.md b/specs/platform/patterns/active-reservations-projection.sdp.md new file mode 100644 index 00000000..4bf99c90 --- /dev/null +++ b/specs/platform/patterns/active-reservations-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.active-reservations-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ActiveReservationsProjection + +## Intent + +- outcome: Track active stock reservations and update stock levels from StockReserved, ReservationConfirmed, ReservationReleased, and ReservationExpired events using event data only. diff --git a/specs/platform/patterns/agent-action-handler.sdp.md b/specs/platform/patterns/agent-action-handler.sdp.md new file mode 100644 index 00000000..c0134671 --- /dev/null +++ b/specs/platform/patterns/agent-action-handler.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.agent-action-handler +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AgentActionHandler + +## Intent + +- outcome: Run the churn-risk agent action in a Workpool action context so it can call external LLM APIs while leaving all persistence to the onComplete mutation. diff --git a/specs/platform/patterns/agent-as-bounded-context.sdp.md b/specs/platform/patterns/agent-as-bounded-context.sdp.md new file mode 100644 index 00000000..096c2efc --- /dev/null +++ b/specs/platform/patterns/agent-as-bounded-context.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.agent-as-bounded-context +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AgentAsBoundedContext + +## Intent + +- outcome: Integrate AI agents into the event-driven architecture as bounded contexts that subscribe to events, detect patterns, and emit commands. +- problem: AI agents are invoked manually without integration into the event-driven architecture. No pattern for agents to react to business events. +- value: AI agents implemented as bounded contexts that subscribe to event streams via EventBus, detect patterns across events using LLM or rules, and emit commands based on detected patterns. diff --git a/specs/platform/patterns/agent-churn-risk-completion-executable-tests.sdp.md b/specs/platform/patterns/agent-churn-risk-completion-executable-tests.sdp.md new file mode 100644 index 00000000..93e18ade --- /dev/null +++ b/specs/platform/patterns/agent-churn-risk-completion-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.agent-churn-risk-completion-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AgentChurnRiskCompletionExecutableTests + +## Intent + +- actor: a system operator +- outcome: Create dead letters for agent failures so that no events are silently lost during processing. diff --git a/specs/platform/patterns/agent-churn-risk-completion.sdp.md b/specs/platform/patterns/agent-churn-risk-completion.sdp.md new file mode 100644 index 00000000..6af69826 --- /dev/null +++ b/specs/platform/patterns/agent-churn-risk-completion.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.agent-churn-risk-completion +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AgentChurnRiskCompletion + +## Intent + +- outcome: Complete the churn-risk agent as a genuine AI agent reference so LLM failure retries to a dead letter, outreach commands create domain records, and the full pipeline is tested with a real LLM. +- problem: The churn-risk agent has working infrastructure from Phases 22a-22c but critical gaps prevent it from being a genuine AI agent reference: rule-based fallback defeats the AI purpose, command routing is a stub, and there is no end-to-end integration test with a real LLM. +- value: Remove the rule-based fallback, add a real outreach handler that emits OutreachCreated, add a full-pipeline OpenRouter integration test, add a BDD feature for the flow, and remove the rule-only highValueChurnPattern. diff --git a/specs/platform/patterns/agent-on-complete-handler.sdp.md b/specs/platform/patterns/agent-on-complete-handler.sdp.md new file mode 100644 index 00000000..49f2e1b4 --- /dev/null +++ b/specs/platform/patterns/agent-on-complete-handler.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.agent-on-complete-handler +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AgentOnCompleteHandler + +## Intent + +- outcome: Persist agent Workpool job results in a mutation so success writes audit, command, approval, and checkpoint last, while failure records a dead letter without advancing the checkpoint. diff --git a/specs/platform/patterns/app-composition-root.sdp.md b/specs/platform/patterns/app-composition-root.sdp.md new file mode 100644 index 00000000..5b93235b --- /dev/null +++ b/specs/platform/patterns/app-composition-root.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.app-composition-root +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# AppCompositionRoot + +## Intent + +- outcome: Mount all Convex components and bounded contexts at the application composition root, including workpool, workflow, event store, command bus, rate limiter, agent BC, orders, and inventory. diff --git a/specs/platform/patterns/bdd-testing-infrastructure-executable-tests.sdp.md b/specs/platform/patterns/bdd-testing-infrastructure-executable-tests.sdp.md new file mode 100644 index 00000000..e19cd34a --- /dev/null +++ b/specs/platform/patterns/bdd-testing-infrastructure-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.bdd-testing-infrastructure-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BddTestingInfrastructureExecutableTests + +## Intent + +- actor: a platform maintainer +- outcome: Give every platform package BDD coverage so public APIs are documented through executable specifications. diff --git a/specs/platform/patterns/bdd-testing-infrastructure.sdp.md b/specs/platform/patterns/bdd-testing-infrastructure.sdp.md new file mode 100644 index 00000000..3123449a --- /dev/null +++ b/specs/platform/patterns/bdd-testing-infrastructure.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.bdd-testing-infrastructure +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BddTestingInfrastructure + +## Intent + +- outcome: Test domain logic with Gherkin so deciders map to Given/When/Then without Docker, and organized step definitions avoid conflicts. +- problem: Domain logic tests require infrastructure (Docker, database). Duplicate step definitions cause conflicts. Platform packages lack BDD tests. +- value: Behavior-driven development using Gherkin as the exclusive testing approach: pure deciders map to Given/When/Then, domain logic tests need no Docker, and step definition organization prevents conflicts. diff --git a/specs/platform/patterns/bdd-world.sdp.md b/specs/platform/patterns/bdd-world.sdp.md new file mode 100644 index 00000000..f7e53404 --- /dev/null +++ b/specs/platform/patterns/bdd-world.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.bdd-world +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BDDWorld + +## Intent + +- actor: a BDD test author +- outcome: Provide world and state management utilities so scenario context can be shared across steps. diff --git a/specs/platform/patterns/bounded-context-foundation-executable-tests.sdp.md b/specs/platform/patterns/bounded-context-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..e3961e70 --- /dev/null +++ b/specs/platform/patterns/bounded-context-foundation-executable-tests.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.bounded-context-foundation-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BoundedContextFoundation Executable Tests + +## Intent + +- outcome: Execute coverage that Convex component databases stay isolated and DualWriteContextContract is the only typed path across bounded-context boundaries. + +## Behavior + +- rule: Components have isolated databases that parent cannot query directly +- rule: Sub-transactions are atomic within components +- rule: ctx.auth does not cross component boundaries +- rule: Id inside component becomes string at API boundary +- rule: DualWriteContextContract formalizes the bounded context API diff --git a/specs/platform/patterns/bounded-context-foundation.sdp.md b/specs/platform/patterns/bounded-context-foundation.sdp.md new file mode 100644 index 00000000..4e614502 --- /dev/null +++ b/specs/platform/patterns/bounded-context-foundation.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.bounded-context-foundation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BoundedContextFoundation + +## Intent + +- outcome: Enforce DDD bounded-context boundaries with isolated Convex component databases and type-safe dual-write contracts so contexts cannot couple accidentally. +- problem: DDD Bounded Contexts need clear boundaries with physical enforcement, type-safe contracts, and domain purity (no infrastructure coupling in domain logic). Without physical isolation, accidental coupling between contexts undermines the benefits of domain-driven design. +- value: Convex Components provide physical database isolation. The platform-bc package defines BoundedContextIdentity, DualWriteContextContract, and CMS type definitions. + +## Behavior + +- rule: Components have isolated databases that parent cannot query directly +- rule: Sub-transactions are atomic within components +- rule: ctx.auth does not cross component boundaries +- rule: Id table types inside a component become string at the API boundary +- rule: DualWriteContextContract formalizes the bounded context API diff --git a/specs/platform/patterns/bounded-context-identity.sdp.md b/specs/platform/patterns/bounded-context-identity.sdp.md new file mode 100644 index 00000000..400dd67a --- /dev/null +++ b/specs/platform/patterns/bounded-context-identity.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.bounded-context-identity +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# BoundedContextIdentity + +## Intent + +- outcome: Give each bounded context a core identification contract with name, description, version, and event stream prefixes for documentation, debugging, event routing, and cross-BC integration. diff --git a/specs/platform/patterns/cms-dual-write.sdp.md b/specs/platform/patterns/cms-dual-write.sdp.md new file mode 100644 index 00000000..c2632c2d --- /dev/null +++ b/specs/platform/patterns/cms-dual-write.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.cms-dual-write +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CMSDualWrite + +## Intent + +- outcome: Maintain a continuously updated Command Model State snapshot atomically alongside events in the dual-write pattern. diff --git a/specs/platform/patterns/cms-repository.sdp.md b/specs/platform/patterns/cms-repository.sdp.md new file mode 100644 index 00000000..bcc42abc --- /dev/null +++ b/specs/platform/patterns/cms-repository.sdp.md @@ -0,0 +1,23 @@ +--- +id: spec:platform.cms-repository +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CMS Repository + +## Intent + +- outcome: Provide typed CMS data access with automatic schema upcasting so dual-write handlers can load, validate, and persist entities without repeating boilerplate. + +## Behavior + +- rule: load retrieves and upcasts a CMS entity by ID +- rule: tryLoad returns null instead of throwing for missing entities +- rule: exists checks entity presence without upcast overhead +- rule: loadMany retrieves multiple entities in parallel with null for missing +- rule: insert persists a new CMS record and returns the document ID +- rule: update patches CMS with optimistic concurrency control +- rule: NotFoundError has correct properties and type guard +- rule: VersionConflictError has correct properties and type guard diff --git a/specs/platform/patterns/command-bus-foundation-executable-tests.sdp.md b/specs/platform/patterns/command-bus-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..9244aa0c --- /dev/null +++ b/specs/platform/patterns/command-bus-foundation-executable-tests.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.command-bus-foundation-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandBusFoundation Executable Tests + +## Intent + +- outcome: Execute coverage that command execution records once, tracks status, and follows the CommandOrchestrator so duplicate requests cannot corrupt domain state. + +## Behavior + +- rule: Commands are idempotent via commandId deduplication +- rule: Status tracks the complete command lifecycle +- rule: The CommandOrchestrator is the only command execution path +- rule: correlationId links commands, events, and projections +- rule: Middleware provides composable cross-cutting concerns diff --git a/specs/platform/patterns/command-bus-foundation.sdp.md b/specs/platform/patterns/command-bus-foundation.sdp.md new file mode 100644 index 00000000..e1a560fb --- /dev/null +++ b/specs/platform/patterns/command-bus-foundation.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.command-bus-foundation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandBusFoundation + +## Intent + +- outcome: Give command execution infrastructure-level idempotency, status tracking, and a single standardized flow from receipt through execution so duplicate requests cannot corrupt domain state. +- problem: Command execution requires idempotency (same command = same result), status tracking, and a standardized flow from receipt through execution. Without infrastructure-level idempotency, duplicate requests could corrupt domain state. +- value: The Command Bus provides commandId deduplication, status lifecycle tracking, the 7-step CommandOrchestrator, correlationId tracing, and TTL-based cleanup of expired command records. + +## Behavior + +- rule: Commands are idempotent via commandId deduplication +- rule: Status tracks the complete command lifecycle +- rule: The CommandOrchestrator is the only command execution path +- rule: correlationId links commands, events, and projections +- rule: Middleware provides composable cross-cutting concerns diff --git a/specs/platform/patterns/command-bus-idempotency.sdp.md b/specs/platform/patterns/command-bus-idempotency.sdp.md new file mode 100644 index 00000000..6297ce08 --- /dev/null +++ b/specs/platform/patterns/command-bus-idempotency.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.command-bus-idempotency +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandBusIdempotency + +## Intent + +- outcome: Deduplicate commands by commandId so the same command always returns the cached result without re-execution. diff --git a/specs/platform/patterns/command-bus.sdp.md b/specs/platform/patterns/command-bus.sdp.md new file mode 100644 index 00000000..fa359431 --- /dev/null +++ b/specs/platform/patterns/command-bus.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.command-bus +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandBus + +## Intent + +- outcome: Provide a type-safe Convex Command Bus client that records commands once, tracks pending through executed, rejected, or failed status, and links command-event correlations for audit. diff --git a/specs/platform/patterns/command-orchestrator.sdp.md b/specs/platform/patterns/command-orchestrator.sdp.md new file mode 100644 index 00000000..f498cec8 --- /dev/null +++ b/specs/platform/patterns/command-orchestrator.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.command-orchestrator +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandOrchestrator partition key structure + +## Intent + +- outcome: Run every command through the 7-step dual-write CommandOrchestrator and pass structured partition keys to primary, secondary, and failed projections while saga routing uses sagaPool. + +## Behavior + +- rule: Primary projection receives structured partition key +- rule: Secondary projections receive structured partition key +- rule: Failed projection receives structured partition key +- rule: Saga routing uses sagaPool diff --git a/specs/platform/patterns/command-registry.sdp.md b/specs/platform/patterns/command-registry.sdp.md new file mode 100644 index 00000000..4af2548a --- /dev/null +++ b/specs/platform/patterns/command-registry.sdp.md @@ -0,0 +1,31 @@ +--- +id: spec:platform.command-registry +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CommandRegistry + +## Intent + +- actor: a platform developer +- outcome: a central registry for command definitions so that commands can be looked up, validated, and filtered at runtime + +## Behavior + +- rule: CommandRegistry implements the singleton pattern +- rule: Commands can be registered and duplicate registration is rejected +- rule: Commands can be unregistered from the registry +- rule: getConfig returns the command configuration or undefined +- rule: getRegistration returns the full registration or undefined +- rule: has checks whether a command is registered +- rule: validate checks command payloads against registered Zod schemas +- rule: list returns all registered commands as CommandInfo objects +- rule: listByCategory filters commands by their category +- rule: listByContext filters commands by bounded context +- rule: listByTag filters commands by tag +- rule: groupByContext groups commands by their bounded context +- rule: size returns the number of registered commands +- rule: clear removes all registrations +- rule: globalRegistry is a functional singleton instance diff --git a/specs/platform/patterns/confirmed-order-cancellation-executable-tests.sdp.md b/specs/platform/patterns/confirmed-order-cancellation-executable-tests.sdp.md new file mode 100644 index 00000000..8fc65d91 --- /dev/null +++ b/specs/platform/patterns/confirmed-order-cancellation-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.confirmed-order-cancellation-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ConfirmedOrderCancellationExecutableTests + +## Intent + +- outcome: Execute coverage for cancelling confirmed orders and releasing their reservations so the Agent BC demo can record the three cancellations needed for churn-risk detection. +- problem: The Order FSM treats confirmed as terminal. Orders cannot be cancelled after saga confirmation, blocking the Agent BC demo which requires 3+ cancellations to trigger churn risk detection. diff --git a/specs/platform/patterns/correlation-chain-system.sdp.md b/specs/platform/patterns/correlation-chain-system.sdp.md new file mode 100644 index 00000000..edf95a56 --- /dev/null +++ b/specs/platform/patterns/correlation-chain-system.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.correlation-chain-system +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CorrelationChainSystem + +## Intent + +- outcome: Track causal relationships in command-event flows with commandId, correlationId, and causationId so requests can be traced across bounded-context boundaries. diff --git a/specs/platform/patterns/cross-context-read-model.sdp.md b/specs/platform/patterns/cross-context-read-model.sdp.md new file mode 100644 index 00000000..df2ced8a --- /dev/null +++ b/specs/platform/patterns/cross-context-read-model.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.cross-context-read-model +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CrossContextReadModel + +## Intent + +- outcome: Combine data from multiple bounded contexts into unified app-level read models for the frontend. diff --git a/specs/platform/patterns/customer-cancellations-projection.sdp.md b/specs/platform/patterns/customer-cancellations-projection.sdp.md new file mode 100644 index 00000000..c3c41883 --- /dev/null +++ b/specs/platform/patterns/customer-cancellations-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.customer-cancellations-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# CustomerCancellationsProjection + +## Intent + +- outcome: Keep a rolling 30-day customer cancellation history so the churn-risk agent can detect patterns via getCustomerCancellations. diff --git a/specs/platform/patterns/data-table-parsing.sdp.md b/specs/platform/patterns/data-table-parsing.sdp.md new file mode 100644 index 00000000..8b355972 --- /dev/null +++ b/specs/platform/patterns/data-table-parsing.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.data-table-parsing +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Gherkin DataTable Parsing Utilities + +## Intent + +- actor: a BDD test author +- outcome: DataTable parsing helpers so that I can easily extract structured data from Gherkin tables diff --git a/specs/platform/patterns/dcb-multi-product-reservation.sdp.md b/specs/platform/patterns/dcb-multi-product-reservation.sdp.md new file mode 100644 index 00000000..db73aed0 --- /dev/null +++ b/specs/platform/patterns/dcb-multi-product-reservation.sdp.md @@ -0,0 +1,17 @@ +--- +id: spec:platform.dcb-multi-product-reservation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DCB Multi-Product Reservation + +## Intent + +- actor: a platform developer +- outcome: Demonstrate DCB in the order submission flow so executeWithDCB can reserve multiple products atomically. + +## Behavior + +- rule: Order submission uses DCB for atomic multi-product reservation diff --git a/specs/platform/patterns/dcb-retry-execution.sdp.md b/specs/platform/patterns/dcb-retry-execution.sdp.md new file mode 100644 index 00000000..5a581708 --- /dev/null +++ b/specs/platform/patterns/dcb-retry-execution.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.dcb-retry-execution +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DCBRetryExecution + +## Intent + +- outcome: Integrate withDCBRetry into command handlers with a self-referential retry mutation that reschedules itself on OCC conflicts. diff --git a/specs/platform/patterns/dcb-scope-key-utilities.sdp.md b/specs/platform/patterns/dcb-scope-key-utilities.sdp.md new file mode 100644 index 00000000..a0bdf92d --- /dev/null +++ b/specs/platform/patterns/dcb-scope-key-utilities.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.dcb-scope-key-utilities +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DCBScopeKeyUtilities + +## Intent + +- outcome: Re-export the canonical shared scope-key contract so platform packages create, parse, and validate tenant, scope type, and scope ID segments without duplicating helpers. diff --git a/specs/platform/patterns/dcb-types.sdp.md b/specs/platform/patterns/dcb-types.sdp.md new file mode 100644 index 00000000..960c466b --- /dev/null +++ b/specs/platform/patterns/dcb-types.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.dcb-types +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DCBTypes + +## Intent + +- outcome: Type scope-based multi-entity coordination within bounded contexts, including OCC operations, aggregated state, and DCB execution results. diff --git a/specs/platform/patterns/decider-assertions.sdp.md b/specs/platform/patterns/decider-assertions.sdp.md new file mode 100644 index 00000000..abba10ec --- /dev/null +++ b/specs/platform/patterns/decider-assertions.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.decider-assertions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Decider Testing Assertions + +## Intent + +- actor: a developer testing deciders +- outcome: assertion helpers for DeciderOutput results so that I can write clear, consistent test assertions diff --git a/specs/platform/patterns/decider-outputs.sdp.md b/specs/platform/patterns/decider-outputs.sdp.md new file mode 100644 index 00000000..ee610969 --- /dev/null +++ b/specs/platform/patterns/decider-outputs.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.decider-outputs +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Decider Output Helpers and Type Guards + +## Intent + +- outcome: Encode command outcomes as success, rejected, or failed outputs that helpers construct and type guards can narrow. diff --git a/specs/platform/patterns/decider-pattern.sdp.md b/specs/platform/patterns/decider-pattern.sdp.md new file mode 100644 index 00000000..125aa341 --- /dev/null +++ b/specs/platform/patterns/decider-pattern.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.decider-pattern +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DeciderPattern + +## Intent + +- outcome: Separate domain logic into pure decide and evolve functions so aggregates stay immutable and tests need no infrastructure. +- problem: Domain logic embedded in handlers makes testing require infrastructure. Mutable aggregates complicate state management and prevent property-based testing. +- value: The Decider pattern separates domain logic into pure functions: decide(state, command) returns events, and evolve(state, event) returns the next state. + +## Behavior + +- rule: Deciders must be pure functions +- rule: DeciderOutput encodes three outcomes +- rule: FSM enforces valid state transitions +- rule: Evolve functions use event payload as source of truth +- rule: Handler factories wrap deciders with infrastructure diff --git a/specs/platform/patterns/dual-write-contract.sdp.md b/specs/platform/patterns/dual-write-contract.sdp.md new file mode 100644 index 00000000..a2d32b45 --- /dev/null +++ b/specs/platform/patterns/dual-write-contract.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.dual-write-contract +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DualWriteContract + +## Intent + +- outcome: Declare a type-safe dual-write contract for each bounded context so command types, event types, and CMS tables are verified at compile time. diff --git a/specs/platform/patterns/durable-append-action.sdp.md b/specs/platform/patterns/durable-append-action.sdp.md new file mode 100644 index 00000000..ed9d00ca --- /dev/null +++ b/specs/platform/patterns/durable-append-action.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.durable-append-action +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DurableAppendAction + +## Intent + +- outcome: Append events through a Workpool-backed action that retries failed appends and records exhausted failures in eventAppendDeadLetters. diff --git a/specs/platform/patterns/durable-events-integration-executable-tests.sdp.md b/specs/platform/patterns/durable-events-integration-executable-tests.sdp.md new file mode 100644 index 00000000..345ee855 --- /dev/null +++ b/specs/platform/patterns/durable-events-integration-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.durable-events-integration-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DurableEventsIntegrationExecutableTests + +## Intent + +- outcome: Execute coverage that the order-management command flow uses Phase 18 durability primitives instead of leaving them only in test harnesses. +- problem: Phase 18 delivered durability primitives to platform-core, but the example app's main command flow still uses direct event append. Durability patterns exist only in test harnesses, not in the production order and inventory flows. diff --git a/specs/platform/patterns/durable-events-integration.sdp.md b/specs/platform/patterns/durable-events-integration.sdp.md new file mode 100644 index 00000000..8a5dae70 --- /dev/null +++ b/specs/platform/patterns/durable-events-integration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.durable-events-integration +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DurableEventsIntegration + +## Intent + +- outcome: Integrate Phase 18 durability primitives into the order-management command flow so users see idempotent append, intent bracketing, durable publication, outbox, poison handling, and projection rebuild in production paths. +- problem: Phase 18 delivered durability primitives to platform-core, but the example app's main command flow still uses direct event append. Durability patterns exist only in test harnesses, not in the production order and inventory flows. +- value: Integrate idempotent event append, intent/completion bracketing, durable event publication, outbox handlers, poison event handling, and projection rebuild into the main order management flow. diff --git a/specs/platform/patterns/durable-function-adapters.sdp.md b/specs/platform/patterns/durable-function-adapters.sdp.md new file mode 100644 index 00000000..53fb904f --- /dev/null +++ b/specs/platform/patterns/durable-function-adapters.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.durable-function-adapters +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DurableFunctionAdapters + +## Intent + +- outcome: Bridge platform interfaces to production Convex durable components so rate limiting is persisted and DCB OCC conflicts retry through Workpool instead of in-memory fallbacks. +- problem: The platform has well-defined interfaces (RateLimitChecker, DCB conflict handling) but uses in-memory implementations not suitable for production. DCB returns conflict status but callers must implement manual retry logic. +- value: Minimal adapters connect RateLimitChecker to the Convex rate limiter and wrap executeWithDCB with Workpool-based OCC retry, then delete in-memory implementations. diff --git a/specs/platform/patterns/dynamic-consistency-boundaries.sdp.md b/specs/platform/patterns/dynamic-consistency-boundaries.sdp.md new file mode 100644 index 00000000..d9f753e9 --- /dev/null +++ b/specs/platform/patterns/dynamic-consistency-boundaries.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.dynamic-consistency-boundaries +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# DynamicConsistencyBoundaries + +## Intent + +- outcome: Enforce cross-entity invariants inside a bounded context by applying OCC to a runtime scope instead of sequential commands or saga compensation. +- problem: Cross-entity invariants within a bounded context currently require sequential commands (no atomicity) or saga coordination (eventual consistency). This leads to complex compensation logic and race conditions between related entities that should be validated together. +- value: DCB groups related entities into a scope, applies OCC on the scope rather than individual entities, and uses correlation chains to track the boundary. diff --git a/specs/platform/patterns/ecst-fat-events.sdp.md b/specs/platform/patterns/ecst-fat-events.sdp.md new file mode 100644 index 00000000..14ad0039 --- /dev/null +++ b/specs/platform/patterns/ecst-fat-events.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.ecst-fat-events +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EcstFatEvents + +## Intent + +- outcome: Carry full consumer context on events so downstream services can process them without querying the source bounded context. +- problem: Thin events require consumers to query back to the source BC, creating coupling and requiring synchronous communication. +- value: Event-Carried State Transfer (ECST) events carry full context for downstream consumers, eliminating back-queries. diff --git a/specs/platform/patterns/event-bus-abstraction.sdp.md b/specs/platform/patterns/event-bus-abstraction.sdp.md new file mode 100644 index 00000000..d16b3923 --- /dev/null +++ b/specs/platform/patterns/event-bus-abstraction.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.event-bus-abstraction +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventBusAbstraction + +## Intent + +- outcome: Publish domain events to matching Workpool subscriptions with parallelism, retries, dead-letter handling, and priority-based ordering. diff --git a/specs/platform/patterns/event-replay-infrastructure.sdp.md b/specs/platform/patterns/event-replay-infrastructure.sdp.md new file mode 100644 index 00000000..11d3fe16 --- /dev/null +++ b/specs/platform/patterns/event-replay-infrastructure.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.event-replay-infrastructure +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventReplayInfrastructure + +## Intent + +- outcome: Rebuild corrupted or migrated projections from the Event Store with checkpointed Workpool chunks so failed rebuilds resume instead of starting over. +- problem: When projections become corrupted, require schema migration, or drift from the Event Store, there is no infrastructure to replay events and rebuild them. Manual intervention requires direct database access and risks data inconsistency. +- value: A checkpoint-based replay system with a dedicated low-priority Workpool, chunked processing, admin mutations, and atomic next-chunk scheduling. diff --git a/specs/platform/patterns/event-store-durability.sdp.md b/specs/platform/patterns/event-store-durability.sdp.md new file mode 100644 index 00000000..6002124a --- /dev/null +++ b/specs/platform/patterns/event-store-durability.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.event-store-durability +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventStoreDurability + +## Intent + +- outcome: Provide guaranteed Convex-native event persistence through outbox, idempotent append, durable append, durable publication, intent/completion bracketing, and poison-event quarantine. diff --git a/specs/platform/patterns/event-store-foundation-executable-tests.sdp.md b/specs/platform/patterns/event-store-foundation-executable-tests.sdp.md new file mode 100644 index 00000000..e2a1d8d2 --- /dev/null +++ b/specs/platform/patterns/event-store-foundation-executable-tests.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.event-store-foundation-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventStoreFoundation Executable Tests + +## Intent + +- outcome: Execute coverage that event streams append immutably with OCC, global positioning, and checkpointed projection reads. + +## Behavior + +- rule: Events are immutable once appended +- rule: Streams provide per-entity ordering via version numbers +- rule: globalPosition enables total ordering across all streams +- rule: OCC prevents concurrent modification conflicts +- rule: Checkpoints enable projection resumption with exactly-once semantics diff --git a/specs/platform/patterns/event-store-foundation.sdp.md b/specs/platform/patterns/event-store-foundation.sdp.md new file mode 100644 index 00000000..9d548383 --- /dev/null +++ b/specs/platform/patterns/event-store-foundation.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.event-store-foundation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventStoreFoundation + +## Intent + +- outcome: Store domain events in versioned streams with OCC, global positioning, and category-aware read APIs so bounded contexts can keep audit trails and projection read models. +- problem: Event Sourcing requires centralized storage for domain events with ordering guarantees, concurrency control, and query capabilities for projections. Without infrastructure for stream-based storage, bounded contexts cannot maintain audit trails or support projection-based read models. +- value: The Event Store component provides stream-based storage with expectedVersion OCC, global positioning, appendToStream/readStream/readFromPosition APIs, event category taxonomy, and schema versioning. + +## Behavior + +- rule: Events are immutable once appended +- rule: Streams provide per-entity ordering via version numbers +- rule: globalPosition enables total ordering across all streams +- rule: OCC prevents concurrent modification conflicts +- rule: Checkpoints enable projection resumption with exactly-once semantics diff --git a/specs/platform/patterns/event-store.sdp.md b/specs/platform/patterns/event-store.sdp.md new file mode 100644 index 00000000..9e7a5c39 --- /dev/null +++ b/specs/platform/patterns/event-store.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.event-store +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventStore + +## Intent + +- outcome: Provide a type-safe Convex Event Store client with optimistic concurrency and global ordering for dual-write appends and projection reads. diff --git a/specs/platform/patterns/event-subscription-registry.sdp.md b/specs/platform/patterns/event-subscription-registry.sdp.md new file mode 100644 index 00000000..cf8d32fa --- /dev/null +++ b/specs/platform/patterns/event-subscription-registry.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.event-subscription-registry +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventSubscriptionRegistry + +## Intent + +- outcome: Register EventBus subscriptions for process managers at priority 200 and agents at priority 250 without duplicating CommandConfig projection routes. diff --git a/specs/platform/patterns/event-upcasting.sdp.md b/specs/platform/patterns/event-upcasting.sdp.md new file mode 100644 index 00000000..3874dcab --- /dev/null +++ b/specs/platform/patterns/event-upcasting.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.event-upcasting +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# EventUpcasting + +## Intent + +- outcome: Transform older event schema versions to the current version at read time so stored events can evolve without breaking projections or replay. diff --git a/specs/platform/patterns/example-app-architecture.sdp.md b/specs/platform/patterns/example-app-architecture.sdp.md new file mode 100644 index 00000000..97ef5c27 --- /dev/null +++ b/specs/platform/patterns/example-app-architecture.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.example-app-architecture +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ExampleAppArchitecture + +## Intent + +- outcome: Document the order-management reference architecture as Convex-native DDD/ES/CQRS with dual-write CMS snapshots, physically isolated bounded contexts, and built-in Workpool orchestration. diff --git a/specs/platform/patterns/example-app-modernization-executable-tests.sdp.md b/specs/platform/patterns/example-app-modernization-executable-tests.sdp.md new file mode 100644 index 00000000..e761ef98 --- /dev/null +++ b/specs/platform/patterns/example-app-modernization-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.example-app-modernization-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ExampleAppModernizationExecutableTests + +## Intent + +- outcome: Execute coverage that the order-management example demonstrates DCB, reactive projections, and fat events after the one-time modernization freeze. +- problem: The order-management example app grew organically during platform development. It does not demonstrate DCB, ReactiveProjections, or Fat Events from Phases 16-20. diff --git a/specs/platform/patterns/example-app-modernization.sdp.md b/specs/platform/patterns/example-app-modernization.sdp.md new file mode 100644 index 00000000..ece41104 --- /dev/null +++ b/specs/platform/patterns/example-app-modernization.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.example-app-modernization +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ExampleAppModernization + +## Intent + +- outcome: Modernize the order-management example once to demonstrate DCB, reactive projections, and fat events, then freeze it as a reference implementation. +- problem: The order-management example app grew organically during platform development. It does not demonstrate DCB, ReactiveProjections, or Fat Events from Phases 16-20, and full e2e coverage treats it like a production app. +- value: Add targeted demonstrations of each new platform pattern, designate the app as a reference implementation, and establish post-freeze change boundaries. diff --git a/specs/platform/patterns/fsm-assertions.sdp.md b/specs/platform/patterns/fsm-assertions.sdp.md new file mode 100644 index 00000000..f6c80992 --- /dev/null +++ b/specs/platform/patterns/fsm-assertions.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.fsm-assertions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# FSM Testing Assertions + +## Intent + +- actor: a developer testing finite state machines +- outcome: FSM-specific assertion helpers so that I can verify transition validity concisely diff --git a/specs/platform/patterns/fsm-transitions.sdp.md b/specs/platform/patterns/fsm-transitions.sdp.md new file mode 100644 index 00000000..22a900ba --- /dev/null +++ b/specs/platform/patterns/fsm-transitions.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.fsm-transitions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# FSM State Transitions + +## Intent + +- outcome: Prevent invalid aggregate state transitions at runtime with explicit FSM rules and clear error messages. diff --git a/specs/platform/patterns/handler-factories.sdp.md b/specs/platform/patterns/handler-factories.sdp.md new file mode 100644 index 00000000..95447bfc --- /dev/null +++ b/specs/platform/patterns/handler-factories.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.handler-factories +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# HandlerFactories + +## Intent + +- outcome: Wrap pure deciders with infrastructure so command handlers can load state, persist dual-write results, and keep domain logic unit-testable without a database. diff --git a/specs/platform/patterns/integration-dead-letters.sdp.md b/specs/platform/patterns/integration-dead-letters.sdp.md new file mode 100644 index 00000000..175ce142 --- /dev/null +++ b/specs/platform/patterns/integration-dead-letters.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.integration-dead-letters +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationDeadLetters + +## Intent + +- outcome: Manage a dead-letter queue for failed cross-context event publications so operators can replay or ignore poisoned integration work. diff --git a/specs/platform/patterns/integration-event-handlers.sdp.md b/specs/platform/patterns/integration-event-handlers.sdp.md new file mode 100644 index 00000000..e7c8f2f7 --- /dev/null +++ b/specs/platform/patterns/integration-event-handlers.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.integration-event-handlers +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationEventHandlers + +## Intent + +- outcome: Process Published Language integration events and dispatch them to the appropriate bounded-context commands. diff --git a/specs/platform/patterns/integration-event-schemas.sdp.md b/specs/platform/patterns/integration-event-schemas.sdp.md new file mode 100644 index 00000000..1fab4adc --- /dev/null +++ b/specs/platform/patterns/integration-event-schemas.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.integration-event-schemas +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationEventSchemas + +## Intent + +- outcome: Define Published Language schemas that form the contract for cross-context integration events. diff --git a/specs/platform/patterns/integration-patterns-21-a.sdp.md b/specs/platform/patterns/integration-patterns-21-a.sdp.md new file mode 100644 index 00000000..c0e0d917 --- /dev/null +++ b/specs/platform/patterns/integration-patterns-21-a.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.integration-patterns-21-a +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationPatterns21a + +## Intent + +- outcome: Replace ad-hoc cross-context event coupling with a Context Map, Published Language, and Anti-Corruption Layer. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. +- value: Foundational patterns for cross-context communication: Context Map documents BC relationships, Published Language defines stable integration schemas, and ACL translates external models. diff --git a/specs/platform/patterns/integration-patterns-21-b.sdp.md b/specs/platform/patterns/integration-patterns-21-b.sdp.md new file mode 100644 index 00000000..344431ba --- /dev/null +++ b/specs/platform/patterns/integration-patterns-21-b.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.integration-patterns-21-b +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationPatterns21b + +## Intent + +- outcome: Evolve integration schemas with upcasters, downcasters, and contract tests so producer-consumer mismatches fail before runtime. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. +- value: Schema evolution and contract testing patterns: upcasters and downcasters migrate versions, contract tests validate compatibility, and violation detection reports mismatches. diff --git a/specs/platform/patterns/integration-routes.sdp.md b/specs/platform/patterns/integration-routes.sdp.md new file mode 100644 index 00000000..dfbc5d45 --- /dev/null +++ b/specs/platform/patterns/integration-routes.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.integration-routes +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# IntegrationRoutes + +## Intent + +- outcome: Translate internal domain events to integration events for external consumers, currently mapping OrderSubmitted to OrderPlacedIntegration. diff --git a/specs/platform/patterns/invariant-framework.sdp.md b/specs/platform/patterns/invariant-framework.sdp.md new file mode 100644 index 00000000..dda18f35 --- /dev/null +++ b/specs/platform/patterns/invariant-framework.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.invariant-framework +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InvariantFramework + +## Intent + +- outcome: Create declarative business-rule invariants with check, assert, and validate from a single configuration object so validation stays type-safe and consistent. diff --git a/specs/platform/patterns/inventory-command-configs.sdp.md b/specs/platform/patterns/inventory-command-configs.sdp.md new file mode 100644 index 00000000..9a68ffdd --- /dev/null +++ b/specs/platform/patterns/inventory-command-configs.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-command-configs +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryCommandConfigs + +## Intent + +- outcome: Wire seven inventory commands to their primary and secondary projections, including the cross-context orderWithInventory projection. diff --git a/specs/platform/patterns/inventory-command-handlers.sdp.md b/specs/platform/patterns/inventory-command-handlers.sdp.md new file mode 100644 index 00000000..99f06155 --- /dev/null +++ b/specs/platform/patterns/inventory-command-handlers.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-command-handlers +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryCommandHandlers + +## Intent + +- outcome: Handle inventory commands with the dual-write sequence: load CMS, lazy-upcast, validate invariants, apply logic, update CMS, and return event data for app-level persistence. diff --git a/specs/platform/patterns/inventory-deciders.sdp.md b/specs/platform/patterns/inventory-deciders.sdp.md new file mode 100644 index 00000000..f57f8af1 --- /dev/null +++ b/specs/platform/patterns/inventory-deciders.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-deciders +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryDeciders + +## Intent + +- outcome: Decide inventory product and reservation outcomes with pure functions that enforce SKU uniqueness, stock sufficiency, and reservation lifecycle invariants without I/O. diff --git a/specs/platform/patterns/inventory-domain-events.sdp.md b/specs/platform/patterns/inventory-domain-events.sdp.md new file mode 100644 index 00000000..cb1ad655 --- /dev/null +++ b/specs/platform/patterns/inventory-domain-events.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-domain-events +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryDomainEvents + +## Intent + +- outcome: Publish the seven Inventory bounded-context domain events covering product lifecycle and reservation reserved, failed, confirmed, released, and expired. diff --git a/specs/platform/patterns/inventory-internal-mutations.sdp.md b/specs/platform/patterns/inventory-internal-mutations.sdp.md new file mode 100644 index 00000000..604dea37 --- /dev/null +++ b/specs/platform/patterns/inventory-internal-mutations.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-internal-mutations +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryInternalMutations + +## Intent + +- outcome: Expose internal inventory mutations that sagas and process managers can invoke for programmatic inventory commands. diff --git a/specs/platform/patterns/inventory-public-api.sdp.md b/specs/platform/patterns/inventory-public-api.sdp.md new file mode 100644 index 00000000..4a44afad --- /dev/null +++ b/specs/platform/patterns/inventory-public-api.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.inventory-public-api +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# InventoryPublicAPI + +## Intent + +- outcome: Expose an app-level Inventory public API whose mutations run through the CommandOrchestrator for external consumers. diff --git a/specs/platform/patterns/logging-infrastructure.sdp.md b/specs/platform/patterns/logging-infrastructure.sdp.md new file mode 100644 index 00000000..3f61c347 --- /dev/null +++ b/specs/platform/patterns/logging-infrastructure.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.logging-infrastructure +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# LoggingInfrastructure + +## Intent + +- outcome: Create domain-specific loggers with scope prefixes and level filtering so platform components share a consistent Workpool-style logging surface. diff --git a/specs/platform/patterns/middleware-pipeline.sdp.md b/specs/platform/patterns/middleware-pipeline.sdp.md new file mode 100644 index 00000000..1bd78c0e --- /dev/null +++ b/specs/platform/patterns/middleware-pipeline.sdp.md @@ -0,0 +1,31 @@ +--- +id: spec:platform.middleware-pipeline +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# MiddlewarePipeline orchestration + +## Intent + +- outcome: MiddlewarePipeline orchestration + +## Behavior + +- rule: use() adds middleware and supports chaining +- rule: remove() removes middleware by name +- rule: has() checks middleware existence +- rule: getMiddlewareNames returns names sorted by order +- rule: execute() runs handler when no middlewares are registered +- rule: Before hooks execute in ascending order +- rule: After hooks execute in reverse order +- rule: Before hook short-circuits on continue false +- rule: Context passes between before hooks +- rule: Before hook errors produce MIDDLEWARE_ERROR rejection +- rule: Handler errors produce HANDLER_ERROR rejection +- rule: After hook errors do not prevent other after hooks or change result +- rule: Short-circuit runs after hooks only for already-executed middlewares +- rule: clear() removes all middlewares +- rule: clone() creates an independent copy +- rule: createMiddlewarePipeline factory creates instances diff --git a/specs/platform/patterns/mock-payment-actions.sdp.md b/specs/platform/patterns/mock-payment-actions.sdp.md new file mode 100644 index 00000000..2503f892 --- /dev/null +++ b/specs/platform/patterns/mock-payment-actions.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.mock-payment-actions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# MockPaymentActions + +## Intent + +- outcome: Simulate an external Stripe charge as a mock action for integration testing until production replaces it with the real Stripe SDK. diff --git a/specs/platform/patterns/order-command-configs.sdp.md b/specs/platform/patterns/order-command-configs.sdp.md new file mode 100644 index 00000000..d19613e1 --- /dev/null +++ b/specs/platform/patterns/order-command-configs.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-command-configs +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderCommandConfigs + +## Intent + +- outcome: Wire six order commands to their primary and secondary projections, saga routes, and integration events. diff --git a/specs/platform/patterns/order-command-handlers.sdp.md b/specs/platform/patterns/order-command-handlers.sdp.md new file mode 100644 index 00000000..c51e0c7c --- /dev/null +++ b/specs/platform/patterns/order-command-handlers.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-command-handlers +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderCommandHandlers + +## Intent + +- outcome: Handle order commands with the dual-write sequence and return event data so the app layer persists events and triggers projections across component boundaries. diff --git a/specs/platform/patterns/order-deciders.sdp.md b/specs/platform/patterns/order-deciders.sdp.md new file mode 100644 index 00000000..734e45c2 --- /dev/null +++ b/specs/platform/patterns/order-deciders.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-deciders +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderDeciders + +## Intent + +- outcome: Decide Order aggregate outcomes with pure functions that validate invariants and produce events without I/O or Convex context. diff --git a/specs/platform/patterns/order-domain-events.sdp.md b/specs/platform/patterns/order-domain-events.sdp.md new file mode 100644 index 00000000..d6a2d168 --- /dev/null +++ b/specs/platform/patterns/order-domain-events.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-domain-events +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderDomainEvents + +## Intent + +- outcome: Publish the six Orders domain event types, including V2 OrderSubmitted with a CustomerSnapshot fat event, and upcast V1 events at read time. diff --git a/specs/platform/patterns/order-fulfillment-saga.sdp.md b/specs/platform/patterns/order-fulfillment-saga.sdp.md new file mode 100644 index 00000000..79983ccb --- /dev/null +++ b/specs/platform/patterns/order-fulfillment-saga.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-fulfillment-saga +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderFulfillmentSaga + +## Intent + +- outcome: Coordinate order fulfillment across contexts by reserving inventory on OrderSubmitted, confirming on success, and cancelling the order as compensation on failure. diff --git a/specs/platform/patterns/order-items-projection.sdp.md b/specs/platform/patterns/order-items-projection.sdp.md new file mode 100644 index 00000000..fc065766 --- /dev/null +++ b/specs/platform/patterns/order-items-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-items-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderItemsProjection + +## Intent + +- outcome: Maintain an order line-item read model that upserts items from OrderItemAdded and OrderItemRemoved events. diff --git a/specs/platform/patterns/order-management-infrastructure.sdp.md b/specs/platform/patterns/order-management-infrastructure.sdp.md new file mode 100644 index 00000000..091d74af --- /dev/null +++ b/specs/platform/patterns/order-management-infrastructure.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-management-infrastructure +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderManagementInfrastructure + +## Intent + +- outcome: Initialize Workpool, Workflow, and the other infrastructure components required by the order-management application. diff --git a/specs/platform/patterns/order-notification-pm.sdp.md b/specs/platform/patterns/order-notification-pm.sdp.md new file mode 100644 index 00000000..7f1e8fb0 --- /dev/null +++ b/specs/platform/patterns/order-notification-pm.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-notification-pm +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderNotificationPM + +## Intent + +- outcome: React to OrderConfirmed with a fire-and-forget SendNotification command via an EventBus process manager at priority 200. diff --git a/specs/platform/patterns/order-public-api.sdp.md b/specs/platform/patterns/order-public-api.sdp.md new file mode 100644 index 00000000..779cc76b --- /dev/null +++ b/specs/platform/patterns/order-public-api.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-public-api +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderPublicAPI + +## Intent + +- outcome: Expose an app-level Orders public API whose mutations run through the CommandOrchestrator for external consumers. diff --git a/specs/platform/patterns/order-summary-projection.sdp.md b/specs/platform/patterns/order-summary-projection.sdp.md new file mode 100644 index 00000000..90924516 --- /dev/null +++ b/specs/platform/patterns/order-summary-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-summary-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderSummaryProjection + +## Intent + +- outcome: Update the orderSummaries read model from order events only, using globalPosition checkpoints and poison-event handling. diff --git a/specs/platform/patterns/order-with-inventory-projection.sdp.md b/specs/platform/patterns/order-with-inventory-projection.sdp.md new file mode 100644 index 00000000..e73c1d9e --- /dev/null +++ b/specs/platform/patterns/order-with-inventory-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.order-with-inventory-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# OrderWithInventoryProjection + +## Intent + +- outcome: Combine order status with inventory reservation status in an app-level projection fed by both Orders and Inventory events. diff --git a/specs/platform/patterns/payment-outbox-handler.sdp.md b/specs/platform/patterns/payment-outbox-handler.sdp.md new file mode 100644 index 00000000..a3cb2017 --- /dev/null +++ b/specs/platform/patterns/payment-outbox-handler.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.payment-outbox-handler +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# PaymentOutboxHandler + +## Intent + +- outcome: Capture payment action success or failure as domain events through an outbox onComplete handler so later processing failures cannot lose the result. diff --git a/specs/platform/patterns/polling-utilities.sdp.md b/specs/platform/patterns/polling-utilities.sdp.md new file mode 100644 index 00000000..71debe41 --- /dev/null +++ b/specs/platform/patterns/polling-utilities.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.polling-utilities +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# PollingUtilities + +## Intent + +- actor: a developer writing integration tests +- outcome: Provide async polling utilities so tests can wait for Workpool projections and other eventual-consistency patterns. diff --git a/specs/platform/patterns/process-manager-lifecycle.sdp.md b/specs/platform/patterns/process-manager-lifecycle.sdp.md new file mode 100644 index 00000000..14cc60e1 --- /dev/null +++ b/specs/platform/patterns/process-manager-lifecycle.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.process-manager-lifecycle +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProcessManagerLifecycle + +## Intent + +- outcome: Validate process-manager transitions among idle, processing, completed, and failed so invalid lifecycle changes are rejected. diff --git a/specs/platform/patterns/process-manager.sdp.md b/specs/platform/patterns/process-manager.sdp.md new file mode 100644 index 00000000..594bfe08 --- /dev/null +++ b/specs/platform/patterns/process-manager.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.process-manager +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProcessManager + +## Intent + +- outcome: React to events by emitting fire-and-forget commands without saga compensation or projection read-model updates. diff --git a/specs/platform/patterns/product-catalog-projection.sdp.md b/specs/platform/patterns/product-catalog-projection.sdp.md new file mode 100644 index 00000000..c6932955 --- /dev/null +++ b/specs/platform/patterns/product-catalog-projection.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.product-catalog-projection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProductCatalogProjection + +## Intent + +- outcome: Maintain a product catalog read model from ProductCreated and StockAdded events and update stockAvailability as a secondary projection. diff --git a/specs/platform/patterns/projection-categories-executable-tests.sdp.md b/specs/platform/patterns/projection-categories-executable-tests.sdp.md new file mode 100644 index 00000000..0717ec27 --- /dev/null +++ b/specs/platform/patterns/projection-categories-executable-tests.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.projection-categories-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProjectionCategoriesExecutableTests + +## Intent + +- actor: a platform developer +- outcome: Query projections by category from the registry so each purpose can target the matching projection types. diff --git a/specs/platform/patterns/projection-categories.sdp.md b/specs/platform/patterns/projection-categories.sdp.md new file mode 100644 index 00000000..f0641392 --- /dev/null +++ b/specs/platform/patterns/projection-categories.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.projection-categories +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Projection Categories + +## Intent + +- outcome: Categorize projections as logic, view, reporting, or integration so each query use case hits the right read model. +- problem: Projections exist but categories are implicit. Developers must know which projection to query for which use case, leading to misuse and performance issues. +- value: A taxonomy that categorizes projections by purpose and query pattern: Logic for command validation, View for UI queries, Reporting for analytics, and Integration for cross-context synchronization. diff --git a/specs/platform/patterns/projection-checkpointing.sdp.md b/specs/platform/patterns/projection-checkpointing.sdp.md new file mode 100644 index 00000000..1592ba6e --- /dev/null +++ b/specs/platform/patterns/projection-checkpointing.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.projection-checkpointing +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProjectionCheckpointing + +## Intent + +- outcome: Wrap projection handlers with a checkpoint helper so event processing stays idempotent without repeating boilerplate. diff --git a/specs/platform/patterns/projection-dead-letters.sdp.md b/specs/platform/patterns/projection-dead-letters.sdp.md new file mode 100644 index 00000000..7b61f7d7 --- /dev/null +++ b/specs/platform/patterns/projection-dead-letters.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.projection-dead-letters +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProjectionDeadLetters + +## Intent + +- outcome: Queue failed projection and EventBus subscription work in a shared onComplete dead-letter handler that supports replay, ignore, and bulk retry. diff --git a/specs/platform/patterns/projection-definitions.sdp.md b/specs/platform/patterns/projection-definitions.sdp.md new file mode 100644 index 00000000..372ad8fb --- /dev/null +++ b/specs/platform/patterns/projection-definitions.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.projection-definitions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ProjectionDefinitions + +## Intent + +- outcome: Register every projection definition and replay handler in one central configuration for projection infrastructure. diff --git a/specs/platform/patterns/query-abstraction.sdp.md b/specs/platform/patterns/query-abstraction.sdp.md new file mode 100644 index 00000000..1b6dc911 --- /dev/null +++ b/specs/platform/patterns/query-abstraction.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.query-abstraction +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# QueryAbstraction + +## Intent + +- outcome: Build type-safe read-model queries with factory helpers for pagination, introspection, and registry grouping by context. diff --git a/specs/platform/patterns/rate-limit-definitions.sdp.md b/specs/platform/patterns/rate-limit-definitions.sdp.md new file mode 100644 index 00000000..a6256b23 --- /dev/null +++ b/specs/platform/patterns/rate-limit-definitions.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.rate-limit-definitions +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# RateLimitDefinitions + +## Intent + +- outcome: Centralize order-management rate-limit configuration on the Convex rate limiter with production-grade sharding. diff --git a/specs/platform/patterns/reactive-projection-conflict-detection.sdp.md b/specs/platform/patterns/reactive-projection-conflict-detection.sdp.md new file mode 100644 index 00000000..4517261c --- /dev/null +++ b/specs/platform/patterns/reactive-projection-conflict-detection.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.reactive-projection-conflict-detection +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReactiveProjectionConflictDetection + +## Intent + +- actor: a platform developer +- outcome: Detect and resolve optimistic-update conflicts automatically so clients discard stale overlays and keep durable data integrity. diff --git a/specs/platform/patterns/reactive-projection-eligibility.sdp.md b/specs/platform/patterns/reactive-projection-eligibility.sdp.md new file mode 100644 index 00000000..93469b5b --- /dev/null +++ b/specs/platform/patterns/reactive-projection-eligibility.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.reactive-projection-eligibility +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReactiveProjectionEligibility + +## Intent + +- actor: a platform developer +- outcome: Allow reactive updates only on view projections so system resources stay optimized. diff --git a/specs/platform/patterns/reactive-projection-hybrid-model.sdp.md b/specs/platform/patterns/reactive-projection-hybrid-model.sdp.md new file mode 100644 index 00000000..c8d6ba2a --- /dev/null +++ b/specs/platform/patterns/reactive-projection-hybrid-model.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.reactive-projection-hybrid-model +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReactiveProjectionHybridModel + +## Intent + +- actor: a frontend developer +- outcome: Combine durable projection state with instant optimistic feedback so users see updates quickly while data integrity is preserved. diff --git a/specs/platform/patterns/reactive-projection-shared-evolve.sdp.md b/specs/platform/patterns/reactive-projection-shared-evolve.sdp.md new file mode 100644 index 00000000..b89816e6 --- /dev/null +++ b/specs/platform/patterns/reactive-projection-shared-evolve.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.reactive-projection-shared-evolve +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReactiveProjectionSharedEvolve + +## Intent + +- actor: a platform developer +- outcome: Share evolve logic between client and server so optimistic and durable state transformations stay consistent. diff --git a/specs/platform/patterns/reactive-projections.sdp.md b/specs/platform/patterns/reactive-projections.sdp.md new file mode 100644 index 00000000..693e3d35 --- /dev/null +++ b/specs/platform/patterns/reactive-projections.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:platform.reactive-projections +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReactiveProjections + +## Intent + +- outcome: Combine durable Workpool projections with reactive push so users see 10-50ms optimistic feedback without losing eventual consistency. +- problem: Workpool-based projections have 100-500ms latency. Users expect instant feedback (10-50ms) for their actions without polling. +- value: A hybrid model combining Workpool for durable, eventually-consistent updates and reactive push for instant UI feedback, with graceful fallback to durable state on conflict. diff --git a/specs/platform/patterns/reservation-pattern.sdp.md b/specs/platform/patterns/reservation-pattern.sdp.md new file mode 100644 index 00000000..93ac4609 --- /dev/null +++ b/specs/platform/patterns/reservation-pattern.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.reservation-pattern +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReservationPattern + +## Intent + +- outcome: Enforce uniqueness before entity creation with TTL reservations that can be confirmed, released, or expired. +- problem: Uniqueness constraints before entity creation require check-then-create patterns with race condition risk, or post-creation unique indexes. +- value: TTL-based reservations claim a unique value, confirm converts it to a permanent entity, and release or expire frees unused claims. + +## Behavior + +- rule: Reservations prevent race conditions +- rule: Reservations have TTL for auto-cleanup +- rule: Confirmation converts to permanent entity +- rule: Release frees reservation before expiry +- rule: Reservation key combines type and value diff --git a/specs/platform/patterns/reservation-release-pm.sdp.md b/specs/platform/patterns/reservation-release-pm.sdp.md new file mode 100644 index 00000000..76928018 --- /dev/null +++ b/specs/platform/patterns/reservation-release-pm.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.reservation-release-pm +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# ReservationReleasePM + +## Intent + +- outcome: Emit ReleaseReservation when an order is cancelled after confirming an active reservation exists on the orderWithInventory projection. diff --git a/specs/platform/patterns/saga-completion-handler.sdp.md b/specs/platform/patterns/saga-completion-handler.sdp.md new file mode 100644 index 00000000..131aa566 --- /dev/null +++ b/specs/platform/patterns/saga-completion-handler.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.saga-completion-handler +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# SagaCompletionHandler + +## Intent + +- outcome: Update saga status and clean up workflow state from the workflow onComplete callback outside the workflow itself. diff --git a/specs/platform/patterns/saga-orchestration-executable-tests.sdp.md b/specs/platform/patterns/saga-orchestration-executable-tests.sdp.md new file mode 100644 index 00000000..96531530 --- /dev/null +++ b/specs/platform/patterns/saga-orchestration-executable-tests.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.saga-orchestration-executable-tests +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# SagaOrchestration Executable Tests + +## Intent + +- outcome: Transfer SagaOrchestration rule coverage into executable scenarios so cross-context compensation and sagaId idempotency can be wired once the order-management harness exists. + +## Behavior + +- rule: Sagas orchestrate operations across multiple bounded contexts +- rule: @convex-dev/workflow provides durability across server restarts +- rule: Compensation reverses partial operations on failure +- rule: Saga idempotency prevents duplicate workflows via sagaId +- rule: Saga status is updated via onComplete callback, not inside workflow diff --git a/specs/platform/patterns/saga-orchestration.sdp.md b/specs/platform/patterns/saga-orchestration.sdp.md new file mode 100644 index 00000000..71337124 --- /dev/null +++ b/specs/platform/patterns/saga-orchestration.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:platform.saga-orchestration +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# SagaOrchestration + +## Intent + +- outcome: Coordinate cross-bounded-context operations with durable multi-step sagas so partial failures can compensate instead of leaving inconsistent state. +- problem: Cross-BC operations (for example Order to Inventory to Shipping) cannot use atomic transactions because bounded contexts have isolated databases. Without coordination infrastructure, partial failures leave the system in inconsistent states. +- value: Sagas use durable multi-step orchestration where each step calls a bounded context via the CommandOrchestrator, failures trigger compensation, saga idempotency prevents duplicate workflows, and onComplete updates saga status outside the workflow. + +## Behavior + +- rule: Sagas orchestrate operations across multiple bounded contexts +- rule: @convex-dev/workflow provides durability across server restarts +- rule: Compensation reverses partial operations on failure +- rule: Saga idempotency prevents duplicate workflows via sagaId +- rule: Saga status is updated via onComplete callback, not inside workflow diff --git a/specs/platform/patterns/saga-registry.sdp.md b/specs/platform/patterns/saga-registry.sdp.md new file mode 100644 index 00000000..545e72fd --- /dev/null +++ b/specs/platform/patterns/saga-registry.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.saga-registry +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# SagaRegistry + +## Intent + +- outcome: Start sagas idempotently through startSagaIfNotExists while tracking status and validating payloads with Zod. diff --git a/specs/platform/patterns/saga-router.sdp.md b/specs/platform/patterns/saga-router.sdp.md new file mode 100644 index 00000000..2f8cd941 --- /dev/null +++ b/specs/platform/patterns/saga-router.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.saga-router +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# SagaRouter + +## Intent + +- outcome: Route domain events to saga workflows, starting OrderFulfillment idempotently from OrderSubmitted. diff --git a/specs/platform/patterns/test-environment-guards.sdp.md b/specs/platform/patterns/test-environment-guards.sdp.md new file mode 100644 index 00000000..fb3a6783 --- /dev/null +++ b/specs/platform/patterns/test-environment-guards.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.test-environment-guards +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# TestEnvironmentGuards + +## Intent + +- actor: a platform developer +- outcome: Guard test-only functions so utilities such as createTestEntity cannot run in production. diff --git a/specs/platform/patterns/test-isolation.sdp.md b/specs/platform/patterns/test-isolation.sdp.md new file mode 100644 index 00000000..144fb22d --- /dev/null +++ b/specs/platform/patterns/test-isolation.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:platform.test-isolation +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Test Isolation via Namespace Prefixing + +## Intent + +- actor: a test author +- outcome: automatic namespace isolation for test data so that tests don't interfere with each other diff --git a/specs/platform/patterns/workpool-partitioning-strategy.sdp.md b/specs/platform/patterns/workpool-partitioning-strategy.sdp.md new file mode 100644 index 00000000..75f4c3b9 --- /dev/null +++ b/specs/platform/patterns/workpool-partitioning-strategy.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:platform.workpool-partitioning-strategy +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# WorkpoolPartitioningStrategy + +## Intent + +- outcome: Standardize Workpool partition-key patterns so projections keep per-entity event order and avoid OCC conflicts. diff --git a/specs/platform/production-hardening.sdp.md b/specs/platform/production-hardening.sdp.md new file mode 100644 index 00000000..d83ea80a --- /dev/null +++ b/specs/platform/production-hardening.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.production-hardening +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Production Hardening - Observability and Operational Tooling + +## Intent + +- outcome: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. +- value: Comprehensive production-ready infrastructure: - + +## Behavior + +- rule: Metrics track system health indicators +- rule: Distributed tracing visualizes event flow +- rule: Health endpoints support Kubernetes probes diff --git a/specs/platform/sdp-bindings.ts b/specs/platform/sdp-bindings.ts new file mode 100644 index 00000000..6d40bbfc --- /dev/null +++ b/specs/platform/sdp-bindings.ts @@ -0,0 +1,666 @@ +import { codeAnchor, codeAnchorId, ref } from "@libar-dev/software-delivery-protocol"; + +/** + * SDP identity bindings for the migrated platform delivery surface. + * One anchor per former architect pattern / implements target. + */ + +export const activeReservationsProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.active-reservations-projection"), + label: "ActiveReservationsProjection", + satisfies: ref("spec:platform.active-reservations-projection"), +}); + +export const agentActionHandlerAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.agent-action-handler"), + label: "AgentActionHandler", + satisfies: ref("spec:platform.agent-action-handler"), +}); + +export const agentAsBoundedContextAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.agent-as-bounded-context"), + label: "AgentAsBoundedContext", + satisfies: ref("spec:platform.agent-as-bounded-context"), +}); + +export const agentChurnRiskCompletionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.agent-churn-risk-completion"), + label: "AgentChurnRiskCompletion", + satisfies: ref("spec:platform.agent-churn-risk-completion"), +}); + +export const agentChurnRiskCompletionExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.agent-churn-risk-completion-executable-tests"), + label: "AgentChurnRiskCompletionExecutableTests", + satisfies: ref("spec:platform.agent-churn-risk-completion-executable-tests"), +}); + +export const agentOnCompleteHandlerAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.agent-on-complete-handler"), + label: "AgentOnCompleteHandler", + satisfies: ref("spec:platform.agent-on-complete-handler"), +}); + +export const appCompositionRootAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.app-composition-root"), + label: "AppCompositionRoot", + satisfies: ref("spec:platform.app-composition-root"), +}); + +export const bddWorldAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bdd-world"), + label: "BDDWorld", + satisfies: ref("spec:platform.bdd-world"), +}); + +export const bddTestingInfrastructureAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bdd-testing-infrastructure"), + label: "BddTestingInfrastructure", + satisfies: ref("spec:platform.bdd-testing-infrastructure"), +}); + +export const bddTestingInfrastructureExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bdd-testing-infrastructure-executable-tests"), + label: "BddTestingInfrastructureExecutableTests", + satisfies: ref("spec:platform.bdd-testing-infrastructure-executable-tests"), +}); + +export const boundedContextFoundationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bounded-context-foundation"), + label: "BoundedContextFoundation", + satisfies: ref("spec:platform.bounded-context-foundation"), +}); + +export const boundedContextFoundationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bounded-context-foundation-executable-tests"), + label: "BoundedContextFoundationExecutableTests", + satisfies: ref("spec:platform.bounded-context-foundation-executable-tests"), +}); + +export const boundedContextIdentityAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.bounded-context-identity"), + label: "BoundedContextIdentity", + satisfies: ref("spec:platform.bounded-context-identity"), +}); + +export const cmsDualWriteAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.cms-dual-write"), + label: "CMSDualWrite", + satisfies: ref("spec:platform.cms-dual-write"), +}); + +export const cmsRepositoryAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.cms-repository"), + label: "CMSRepository", + satisfies: ref("spec:platform.cms-repository"), +}); + +export const commandBusAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-bus"), + label: "CommandBus", + satisfies: ref("spec:platform.command-bus"), +}); + +export const commandBusFoundationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-bus-foundation"), + label: "CommandBusFoundation", + satisfies: ref("spec:platform.command-bus-foundation"), +}); + +export const commandBusFoundationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-bus-foundation-executable-tests"), + label: "CommandBusFoundationExecutableTests", + satisfies: ref("spec:platform.command-bus-foundation-executable-tests"), +}); + +export const commandBusIdempotencyAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-bus-idempotency"), + label: "CommandBusIdempotency", + satisfies: ref("spec:platform.command-bus-idempotency"), +}); + +export const commandOrchestratorAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-orchestrator"), + label: "CommandOrchestrator", + satisfies: ref("spec:platform.command-orchestrator"), +}); + +export const commandRegistryAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.command-registry"), + label: "CommandRegistry", + satisfies: ref("spec:platform.command-registry"), +}); + +export const confirmedOrderCancellationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.confirmed-order-cancellation"), + label: "ConfirmedOrderCancellation", + satisfies: ref("spec:platform.confirmed-order-cancellation"), +}); + +export const confirmedOrderCancellationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.confirmed-order-cancellation-executable-tests"), + label: "ConfirmedOrderCancellationExecutableTests", + satisfies: ref("spec:platform.confirmed-order-cancellation-executable-tests"), +}); + +export const correlationChainSystemAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.correlation-chain-system"), + label: "CorrelationChainSystem", + satisfies: ref("spec:platform.correlation-chain-system"), +}); + +export const crossContextReadModelAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.cross-context-read-model"), + label: "CrossContextReadModel", + satisfies: ref("spec:platform.cross-context-read-model"), +}); + +export const customerCancellationsProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.customer-cancellations-projection"), + label: "CustomerCancellationsProjection", + satisfies: ref("spec:platform.customer-cancellations-projection"), +}); + +export const dcbMultiProductReservationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dcb-multi-product-reservation"), + label: "DCBMultiProductReservation", + satisfies: ref("spec:platform.dcb-multi-product-reservation"), +}); + +export const dcbRetryExecutionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dcb-retry-execution"), + label: "DCBRetryExecution", + satisfies: ref("spec:platform.dcb-retry-execution"), +}); + +export const dcbScopeKeyUtilitiesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dcb-scope-key-utilities"), + label: "DCBScopeKeyUtilities", + satisfies: ref("spec:platform.dcb-scope-key-utilities"), +}); + +export const dcbTypesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dcb-types"), + label: "DCBTypes", + satisfies: ref("spec:platform.dcb-types"), +}); + +export const dataTableParsingAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.data-table-parsing"), + label: "DataTableParsing", + satisfies: ref("spec:platform.data-table-parsing"), +}); + +export const deciderAssertionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.decider-assertions"), + label: "DeciderAssertions", + satisfies: ref("spec:platform.decider-assertions"), +}); + +export const deciderOutputsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.decider-outputs"), + label: "DeciderOutputs", + satisfies: ref("spec:platform.decider-outputs"), +}); + +export const deciderPatternAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.decider-pattern"), + label: "DeciderPattern", + satisfies: ref("spec:platform.decider-pattern"), +}); + +export const dualWriteContractAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dual-write-contract"), + label: "DualWriteContract", + satisfies: ref("spec:platform.dual-write-contract"), +}); + +export const durableAppendActionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.durable-append-action"), + label: "DurableAppendAction", + satisfies: ref("spec:platform.durable-append-action"), +}); + +export const durableEventsIntegrationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.durable-events-integration"), + label: "DurableEventsIntegration", + satisfies: ref("spec:platform.durable-events-integration"), +}); + +export const durableEventsIntegrationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.durable-events-integration-executable-tests"), + label: "DurableEventsIntegrationExecutableTests", + satisfies: ref("spec:platform.durable-events-integration-executable-tests"), +}); + +export const durableFunctionAdaptersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.durable-function-adapters"), + label: "DurableFunctionAdapters", + satisfies: ref("spec:platform.durable-function-adapters"), +}); + +export const dynamicConsistencyBoundariesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.dynamic-consistency-boundaries"), + label: "DynamicConsistencyBoundaries", + satisfies: ref("spec:platform.dynamic-consistency-boundaries"), +}); + +export const ecstFatEventsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.ecst-fat-events"), + label: "EcstFatEvents", + satisfies: ref("spec:platform.ecst-fat-events"), +}); + +export const eventBusAbstractionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-bus-abstraction"), + label: "EventBusAbstraction", + satisfies: ref("spec:platform.event-bus-abstraction"), +}); + +export const eventReplayInfrastructureAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-replay-infrastructure"), + label: "EventReplayInfrastructure", + satisfies: ref("spec:platform.event-replay-infrastructure"), +}); + +export const eventStoreAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-store"), + label: "EventStore", + satisfies: ref("spec:platform.event-store"), +}); + +export const eventStoreDurabilityAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-store-durability"), + label: "EventStoreDurability", + satisfies: ref("spec:platform.event-store-durability"), +}); + +export const eventStoreFoundationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-store-foundation"), + label: "EventStoreFoundation", + satisfies: ref("spec:platform.event-store-foundation"), +}); + +export const eventStoreFoundationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-store-foundation-executable-tests"), + label: "EventStoreFoundationExecutableTests", + satisfies: ref("spec:platform.event-store-foundation-executable-tests"), +}); + +export const eventSubscriptionRegistryAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-subscription-registry"), + label: "EventSubscriptionRegistry", + satisfies: ref("spec:platform.event-subscription-registry"), +}); + +export const eventUpcastingAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.event-upcasting"), + label: "EventUpcasting", + satisfies: ref("spec:platform.event-upcasting"), +}); + +export const exampleAppArchitectureAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.example-app-architecture"), + label: "ExampleAppArchitecture", + satisfies: ref("spec:platform.example-app-architecture"), +}); + +export const exampleAppModernizationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.example-app-modernization"), + label: "ExampleAppModernization", + satisfies: ref("spec:platform.example-app-modernization"), +}); + +export const exampleAppModernizationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.example-app-modernization-executable-tests"), + label: "ExampleAppModernizationExecutableTests", + satisfies: ref("spec:platform.example-app-modernization-executable-tests"), +}); + +export const fsmAssertionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.fsm-assertions"), + label: "FSMAssertions", + satisfies: ref("spec:platform.fsm-assertions"), +}); + +export const fsmTransitionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.fsm-transitions"), + label: "FSMTransitions", + satisfies: ref("spec:platform.fsm-transitions"), +}); + +export const handlerFactoriesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.handler-factories"), + label: "HandlerFactories", + satisfies: ref("spec:platform.handler-factories"), +}); + +export const integrationDeadLettersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-dead-letters"), + label: "IntegrationDeadLetters", + satisfies: ref("spec:platform.integration-dead-letters"), +}); + +export const integrationEventHandlersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-event-handlers"), + label: "IntegrationEventHandlers", + satisfies: ref("spec:platform.integration-event-handlers"), +}); + +export const integrationEventSchemasAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-event-schemas"), + label: "IntegrationEventSchemas", + satisfies: ref("spec:platform.integration-event-schemas"), +}); + +export const integrationPatterns21AAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-patterns-21-a"), + label: "IntegrationPatterns21a", + satisfies: ref("spec:platform.integration-patterns-21-a"), +}); + +export const integrationPatterns21BAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-patterns-21-b"), + label: "IntegrationPatterns21b", + satisfies: ref("spec:platform.integration-patterns-21-b"), +}); + +export const integrationRoutesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.integration-routes"), + label: "IntegrationRoutes", + satisfies: ref("spec:platform.integration-routes"), +}); + +export const invariantFrameworkAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.invariant-framework"), + label: "InvariantFramework", + satisfies: ref("spec:platform.invariant-framework"), +}); + +export const inventoryCommandConfigsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-command-configs"), + label: "InventoryCommandConfigs", + satisfies: ref("spec:platform.inventory-command-configs"), +}); + +export const inventoryCommandHandlersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-command-handlers"), + label: "InventoryCommandHandlers", + satisfies: ref("spec:platform.inventory-command-handlers"), +}); + +export const inventoryDecidersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-deciders"), + label: "InventoryDeciders", + satisfies: ref("spec:platform.inventory-deciders"), +}); + +export const inventoryDomainEventsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-domain-events"), + label: "InventoryDomainEvents", + satisfies: ref("spec:platform.inventory-domain-events"), +}); + +export const inventoryInternalMutationsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-internal-mutations"), + label: "InventoryInternalMutations", + satisfies: ref("spec:platform.inventory-internal-mutations"), +}); + +export const inventoryPublicApiAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.inventory-public-api"), + label: "InventoryPublicAPI", + satisfies: ref("spec:platform.inventory-public-api"), +}); + +export const loggingInfrastructureAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.logging-infrastructure"), + label: "LoggingInfrastructure", + satisfies: ref("spec:platform.logging-infrastructure"), +}); + +export const middlewarePipelineAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.middleware-pipeline"), + label: "MiddlewarePipeline", + satisfies: ref("spec:platform.middleware-pipeline"), +}); + +export const mockPaymentActionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.mock-payment-actions"), + label: "MockPaymentActions", + satisfies: ref("spec:platform.mock-payment-actions"), +}); + +export const orderCommandConfigsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-command-configs"), + label: "OrderCommandConfigs", + satisfies: ref("spec:platform.order-command-configs"), +}); + +export const orderCommandHandlersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-command-handlers"), + label: "OrderCommandHandlers", + satisfies: ref("spec:platform.order-command-handlers"), +}); + +export const orderDecidersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-deciders"), + label: "OrderDeciders", + satisfies: ref("spec:platform.order-deciders"), +}); + +export const orderDomainEventsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-domain-events"), + label: "OrderDomainEvents", + satisfies: ref("spec:platform.order-domain-events"), +}); + +export const orderFulfillmentSagaAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-fulfillment-saga"), + label: "OrderFulfillmentSaga", + satisfies: ref("spec:platform.order-fulfillment-saga"), +}); + +export const orderItemsProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-items-projection"), + label: "OrderItemsProjection", + satisfies: ref("spec:platform.order-items-projection"), +}); + +export const orderManagementInfrastructureAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-management-infrastructure"), + label: "OrderManagementInfrastructure", + satisfies: ref("spec:platform.order-management-infrastructure"), +}); + +export const orderNotificationPmAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-notification-pm"), + label: "OrderNotificationPM", + satisfies: ref("spec:platform.order-notification-pm"), +}); + +export const orderPublicApiAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-public-api"), + label: "OrderPublicAPI", + satisfies: ref("spec:platform.order-public-api"), +}); + +export const orderSummaryProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-summary-projection"), + label: "OrderSummaryProjection", + satisfies: ref("spec:platform.order-summary-projection"), +}); + +export const orderWithInventoryProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.order-with-inventory-projection"), + label: "OrderWithInventoryProjection", + satisfies: ref("spec:platform.order-with-inventory-projection"), +}); + +export const paymentOutboxHandlerAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.payment-outbox-handler"), + label: "PaymentOutboxHandler", + satisfies: ref("spec:platform.payment-outbox-handler"), +}); + +export const pollingUtilitiesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.polling-utilities"), + label: "PollingUtilities", + satisfies: ref("spec:platform.polling-utilities"), +}); + +export const processManagerAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.process-manager"), + label: "ProcessManager", + satisfies: ref("spec:platform.process-manager"), +}); + +export const processManagerLifecycleAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.process-manager-lifecycle"), + label: "ProcessManagerLifecycle", + satisfies: ref("spec:platform.process-manager-lifecycle"), +}); + +export const productCatalogProjectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.product-catalog-projection"), + label: "ProductCatalogProjection", + satisfies: ref("spec:platform.product-catalog-projection"), +}); + +export const productionHardeningAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.production-hardening"), + label: "ProductionHardening", + satisfies: ref("spec:platform.production-hardening"), +}); + +export const projectionCategoriesAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.projection-categories"), + label: "ProjectionCategories", + satisfies: ref("spec:platform.projection-categories"), +}); + +export const projectionCategoriesExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.projection-categories-executable-tests"), + label: "ProjectionCategoriesExecutableTests", + satisfies: ref("spec:platform.projection-categories-executable-tests"), +}); + +export const projectionCheckpointingAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.projection-checkpointing"), + label: "ProjectionCheckpointing", + satisfies: ref("spec:platform.projection-checkpointing"), +}); + +export const projectionDeadLettersAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.projection-dead-letters"), + label: "ProjectionDeadLetters", + satisfies: ref("spec:platform.projection-dead-letters"), +}); + +export const projectionDefinitionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.projection-definitions"), + label: "ProjectionDefinitions", + satisfies: ref("spec:platform.projection-definitions"), +}); + +export const queryAbstractionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.query-abstraction"), + label: "QueryAbstraction", + satisfies: ref("spec:platform.query-abstraction"), +}); + +export const rateLimitDefinitionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.rate-limit-definitions"), + label: "RateLimitDefinitions", + satisfies: ref("spec:platform.rate-limit-definitions"), +}); + +export const reactiveProjectionConflictDetectionAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reactive-projection-conflict-detection"), + label: "ReactiveProjectionConflictDetection", + satisfies: ref("spec:platform.reactive-projection-conflict-detection"), +}); + +export const reactiveProjectionEligibilityAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reactive-projection-eligibility"), + label: "ReactiveProjectionEligibility", + satisfies: ref("spec:platform.reactive-projection-eligibility"), +}); + +export const reactiveProjectionHybridModelAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reactive-projection-hybrid-model"), + label: "ReactiveProjectionHybridModel", + satisfies: ref("spec:platform.reactive-projection-hybrid-model"), +}); + +export const reactiveProjectionSharedEvolveAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reactive-projection-shared-evolve"), + label: "ReactiveProjectionSharedEvolve", + satisfies: ref("spec:platform.reactive-projection-shared-evolve"), +}); + +export const reactiveProjectionsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reactive-projections"), + label: "ReactiveProjections", + satisfies: ref("spec:platform.reactive-projections"), +}); + +export const reservationPatternAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reservation-pattern"), + label: "ReservationPattern", + satisfies: ref("spec:platform.reservation-pattern"), +}); + +export const reservationReleasePmAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.reservation-release-pm"), + label: "ReservationReleasePM", + satisfies: ref("spec:platform.reservation-release-pm"), +}); + +export const sagaCompletionHandlerAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.saga-completion-handler"), + label: "SagaCompletionHandler", + satisfies: ref("spec:platform.saga-completion-handler"), +}); + +export const sagaOrchestrationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.saga-orchestration"), + label: "SagaOrchestration", + satisfies: ref("spec:platform.saga-orchestration"), +}); + +export const sagaOrchestrationExecutableTestsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.saga-orchestration-executable-tests"), + label: "SagaOrchestrationExecutableTests", + satisfies: ref("spec:platform.saga-orchestration-executable-tests"), +}); + +export const sagaRegistryAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.saga-registry"), + label: "SagaRegistry", + satisfies: ref("spec:platform.saga-registry"), +}); + +export const sagaRouterAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.saga-router"), + label: "SagaRouter", + satisfies: ref("spec:platform.saga-router"), +}); + +export const testEnvironmentGuardsAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.test-environment-guards"), + label: "TestEnvironmentGuards", + satisfies: ref("spec:platform.test-environment-guards"), +}); + +export const testIsolationAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.test-isolation"), + label: "TestIsolation", + satisfies: ref("spec:platform.test-isolation"), +}); + +export const workpoolPartitioningStrategyAnchor = codeAnchor({ + id: codeAnchorId("impl:platform.workpool-partitioning-strategy"), + label: "WorkpoolPartitioningStrategy", + satisfies: ref("spec:platform.workpool-partitioning-strategy"), +}); diff --git a/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.sdp.md b/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.sdp.md new file mode 100644 index 00000000..5965b9fd --- /dev/null +++ b/specs/platform/tranche-0-readiness-harness-and-dependency-hardening.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Tranche 0 Readiness Harness and Dependency Hardening + +## Intent + +- outcome: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. +- value: Land the tranche-0 readiness packet first so later packets inherit a trustworthy backend test surface, aligned package scripts, and strict validation baselines. + +## Behavior + +- rule: Tranche 0 readiness is a hard gate +- rule: Validation posture must fail closed diff --git a/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.sdp.md b/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.sdp.md new file mode 100644 index 00000000..b131ab81 --- /dev/null +++ b/specs/platform/tranche-0-release-ci-and-docs-process-guardrails.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Tranche 0 Release, CI, and Docs/Process Guardrails + +## Intent + +- outcome: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. +- value: Ship a tranche-0 governance packet that mirrors release metadata from 'pdr-002-release-management-architecture.feature', adds docs/process CI coverage, and makes contract-status and rename-guard policy enforceable before behavior-changing remediation work. + +## Behavior + +- rule: PDR-002 is the only release authority +- rule: Docs and process changes must have a non-skipped CI lane diff --git a/specs/platform/tranche-1-supporting-security-and-contract-sweep.sdp.md b/specs/platform/tranche-1-supporting-security-and-contract-sweep.sdp.md new file mode 100644 index 00000000..666f7380 --- /dev/null +++ b/specs/platform/tranche-1-supporting-security-and-contract-sweep.sdp.md @@ -0,0 +1,19 @@ +--- +id: spec:platform.tranche-1-supporting-security-and-contract-sweep +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Tranche 1 Supporting Security and Contract Sweep + +## Intent + +- outcome: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. +- value: Plan P12, P13, P15, P16, P19, P20, and P21 as one supporting packet that executes after the component-boundary auth convention is established, but stays distinct from the P11 and event-correctness packets. + +## Behavior + +- rule: Supporting tranche-1 work follows the auth convention +- rule: Legacy shortcuts are removed, not documented as acceptable debt diff --git a/specs/releases.pack.sdp.md b/specs/releases.pack.sdp.md new file mode 100644 index 00000000..e3dd4a1e --- /dev/null +++ b/specs/releases.pack.sdp.md @@ -0,0 +1,12 @@ +--- +id: pack:releases +specs: + - spec:releases.line + - spec:releases.v0.1.0 + - spec:releases.v0.2.0 + - spec:releases.v0.3.0 + - spec:releases.vNEXT +--- +# Releases + +Release-boundary Specs migrated from architect/releases. diff --git a/specs/releases/_epic.sdp.md b/specs/releases/_epic.sdp.md new file mode 100644 index 00000000..30cb4028 --- /dev/null +++ b/specs/releases/_epic.sdp.md @@ -0,0 +1,16 @@ +--- +id: spec:releases.line +kind: decision +altitude: epic +readiness: idea +relations: {} +--- +# Release boundary registry + +## Intent + +- outcome: Hold numbered and vNEXT release-boundary Specs as a single refinement parent. + +## Decision + +- decision: Every release Spec under specs/releases/ refines spec:releases.line. diff --git a/specs/releases/v0.1.0.sdp.md b/specs/releases/v0.1.0.sdp.md new file mode 100644 index 00000000..d801f428 --- /dev/null +++ b/specs/releases/v0.1.0.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:releases.v0.1.0 +kind: decision +altitude: epic +readiness: defined +relations: + refines: spec:releases.line +--- +# v0.1.0 - Delivery Process Foundation + +## Intent + +- outcome: Establish the software delivery process for the libar-dev platform monorepo. + +## Decision + +- context: This is the initial process-setup release and has no breaking changes. +- decision: Formalize how the monorepo tracks work, makes decisions, and generates documentation from code by introducing the delivery-process package and Process Decision Record conventions, completing the scanner, extractor, and generator pipeline, and establishing a Gherkin-only testing policy with release-management infrastructure. +- rationale: The release records PDR-001 through PDR-005, including process-decisions folder structure, behavior feature file structure, the unified @architect-* tag prefix, and release management architecture. +- consequence: The @libar-process-* tag prefix is deprecated in favor of the unified @architect-* prefix per PDR-004; the scanner accepts both during migration and logs warnings for deprecated usage. diff --git a/specs/releases/v0.2.0.sdp.md b/specs/releases/v0.2.0.sdp.md new file mode 100644 index 00000000..7ca91e2b --- /dev/null +++ b/specs/releases/v0.2.0.sdp.md @@ -0,0 +1,22 @@ +--- +id: spec:releases.v0.2.0 +kind: decision +altitude: epic +readiness: defined +relations: + refines: spec:releases.line +--- +# v0.2.0 - Platform Roadmap (Aggregate-Less Pivot) + +## Intent + +- outcome: Convert the aggregate-less pivot roadmap into executable specs for Phases 14-22. + +## Decision + +- context: The platform is already aggregate-less; Convex-native event sourcing is neither traditional OOP aggregates nor Kafka-style streaming, and the CMS dual-write pattern eliminates rehydration. +- decision: Formalize the Third Way as the v0.2.0 platform roadmap and establish Phases 14-22 as the development path for the libar-dev platform infrastructure. +- rationale: Phase 14 (Decider Pattern) and Phase 16 (Dynamic Consistency Boundaries) are complete, Phase 19 (BDD Testing Infrastructure) is active, and Phases 15, 17, 18, and 20-22 remain on the roadmap. +- rationale: Phase 15-22 specs are defined from pattern briefs, a session context module is added to CLAUDE.md, DELIVERY-PROCESS-GUIDE.md is the reference document, and a single Platform product area is established. +- consequence: Pattern briefs in docs/project-management/aggregate-less-pivot/pattern-briefs/ are superseded by executable specs in specs/platform/; the pattern briefs remain as historical reference. +- consequence: There are no breaking changes; the release is additive for the platform roadmap. diff --git a/specs/releases/v0.3.0.sdp.md b/specs/releases/v0.3.0.sdp.md new file mode 100644 index 00000000..027f0397 --- /dev/null +++ b/specs/releases/v0.3.0.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:releases.v0.3.0 +kind: decision +altitude: epic +readiness: defined +relations: + refines: spec:releases.line +--- +# v0.3.0 - TypeScript Taxonomy Migration + +## Intent + +- outcome: Complete the migration from JSON to TypeScript as the source of truth for the delivery process taxonomy. + +## Decision + +- context: This release formalizes PDR-006 (TypeScript-Sourced Taxonomy), moving taxonomy definitions off hand-edited JSON files that lacked compile-time protection. +- decision: TypeScript as-const arrays define valid taxonomy values, Zod schemas use those constants for runtime validation, and JSON files become generated artifacts. +- rationale: Compile-time constants give a single typed source of truth while Zod stays at the runtime boundary and external JSON consumers keep generated output. +- consequence: There are no breaking changes; the release is backward compatible. diff --git a/specs/releases/vNEXT.sdp.md b/specs/releases/vNEXT.sdp.md new file mode 100644 index 00000000..de7ca779 --- /dev/null +++ b/specs/releases/vNEXT.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:releases.vNEXT +kind: decision +altitude: epic +readiness: defined +relations: + refines: spec:releases.line +--- +# vNEXT - Unreleased Work + +## Intent + +- outcome: Stage work in progress that has not yet been assigned to a specific release version. + +## Decision + +- context: Unreleased work needs a staging release until a version number is chosen. +- decision: Track deliverables tagged @architect-release:vNEXT here until a release is cut; then choose the version from the changes, create a new release Spec under specs/releases, retag those deliverables from vNEXT to the new version, and run pnpm docs:all to regenerate the changelog. +- rationale: Work in progress is staged here instead of being assigned a version before the release is cut. +- consequence: Deliverables tagged @architect-release:vNEXT stay on this boundary until a numbered release Spec is authored. diff --git a/specs/themed-decision-architecture.sdp.md b/specs/themed-decision-architecture.sdp.md new file mode 100644 index 00000000..24bec89d --- /dev/null +++ b/specs/themed-decision-architecture.sdp.md @@ -0,0 +1,20 @@ +--- +id: spec:platform.themed-decision-architecture +kind: behavior +altitude: feature +readiness: idea +relations: {} +--- +# Themed Decision Architecture + +## Intent + +- outcome: Themed Decision Architecture + +## Behavior + +- rule: Decisions are grouped by theme +- rule: Decisions declare dependencies +- rule: Decisions are layered by evolution phase +- rule: Existing ADRs are migrated with review +- rule: Multiple output formats are generated diff --git a/specs/unimplemented.pack.sdp.md b/specs/unimplemented.pack.sdp.md new file mode 100644 index 00000000..dead1474 --- /dev/null +++ b/specs/unimplemented.pack.sdp.md @@ -0,0 +1,139 @@ +--- +id: pack:unimplemented +specs: + - spec:unimplemented.admin-tooling-consolidation.admin-api-documentation + - spec:unimplemented.admin-tooling-consolidation.admin-authorization-wrapper + - spec:unimplemented.admin-tooling-consolidation.create-admin-directory + - spec:unimplemented.admin-tooling-consolidation.durable-function-run-queries + - spec:unimplemented.admin-tooling-consolidation.event-flow-trace-query + - spec:unimplemented.admin-tooling-consolidation.projection-admin-endpoints + - spec:unimplemented.admin-tooling-consolidation.refactored-dlq-endpoints + - spec:unimplemented.admin-tooling-consolidation.system-state-snapshot-query + - spec:unimplemented.agent-admin-frontend.action-feedback-toasts + - spec:unimplemented.agent-admin-frontend.agent-admin-page-page-object + - spec:unimplemented.agent-admin-frontend.auth-integration-documentation + - spec:unimplemented.agent-admin-frontend.dashboard-update-for-multi-agent + - spec:unimplemented.agent-admin-frontend.dead-letter-management-section-in-monitoring + - spec:unimplemented.agent-admin-frontend.decision-history-tab + - spec:unimplemented.agent-admin-frontend.e2-e-step-definitions + - spec:unimplemented.agent-admin-frontend.high-value-action-handler + - spec:unimplemented.agent-admin-frontend.high-value-agent-config + - spec:unimplemented.agent-admin-frontend.high-value-command-route + - spec:unimplemented.agent-admin-frontend.high-value-event-bus-subscription + - spec:unimplemented.agent-admin-frontend.high-value-integration-test-real-llm + - spec:unimplemented.agent-admin-frontend.high-value-on-complete-handler + - spec:unimplemented.agent-admin-frontend.high-value-pattern-definition + - spec:unimplemented.agent-admin-frontend.tag-unimplemented-agent-e2e-scenarios-skip + - spec:unimplemented.agent-admin-frontend.toast-notification-integration-sonner + - spec:unimplemented.agent-admin-frontend.use-dead-letter-actions-hook + - spec:unimplemented.agent-admin-frontend.use-dead-letters-hook + - spec:unimplemented.agent-admin-frontend.use-decision-history-hook-with-filters + - spec:unimplemented.agent-bc-component-isolation.agent-component-definition + - spec:unimplemented.agent-bc-component-isolation.agent-component-schema + - spec:unimplemented.agent-bc-component-isolation.approval-public-api + - spec:unimplemented.agent-bc-component-isolation.audit-public-api + - spec:unimplemented.agent-bc-component-isolation.checkpoint-public-api + - spec:unimplemented.agent-bc-component-isolation.command-public-api + - spec:unimplemented.agent-bc-component-isolation.cross-component-query-pattern + - spec:unimplemented.agent-bc-component-isolation.dead-letter-public-api + - spec:unimplemented.agent-llm-integration.action-mutation-integration-test + - spec:unimplemented.agent-llm-integration.agent-action-handler-factory + - spec:unimplemented.agent-llm-integration.agent-workpool-configuration + - spec:unimplemented.agent-llm-integration.circuit-breaker-for-llm + - spec:unimplemented.agent-llm-integration.convex-dev-agent-thread-adapter + - spec:unimplemented.agent-llm-integration.cost-budget-tracking + - spec:unimplemented.agent-llm-integration.llm-integrated-on-complete-handler + - spec:unimplemented.agent-llm-integration.on-complete-in-create-agent-subscription-options + - spec:unimplemented.agent-llm-integration.rate-limiter-integration + - spec:unimplemented.backlog + - spec:unimplemented.circuit-breaker-pattern.check-half-open-scheduled-mutation + - spec:unimplemented.circuit-breaker-pattern.circuit-breaker-metrics + - spec:unimplemented.circuit-breaker-pattern.circuit-breaker-state-machine-pure + - spec:unimplemented.circuit-breaker-pattern.circuit-breaker-types + - spec:unimplemented.circuit-breaker-pattern.circuit-breakers-table-schema + - spec:unimplemented.circuit-breaker-pattern.load-circuit-state-query + - spec:unimplemented.circuit-breaker-pattern.on-circuit-probe-complete-handler + - spec:unimplemented.circuit-breaker-pattern.record-failure-mutation + - spec:unimplemented.circuit-breaker-pattern.record-success-mutation + - spec:unimplemented.circuit-breaker-pattern.with-circuit-breaker-wrapper + - spec:unimplemented.component-boundary-authentication-convention.canonical-verification-proof-contract + - spec:unimplemented.component-boundary-authentication-convention.component-boundary-auth-integration-suite + - spec:unimplemented.component-boundary-authentication-convention.contract-status-tagging-for-system-only-exceptions + - spec:unimplemented.component-boundary-authentication-convention.identity-bearing-mutation-migration + - spec:unimplemented.component-boundary-authentication-convention.pdr-014-placeholder + - spec:unimplemented.component-boundary-authentication-convention.verify-actor-helper + - spec:unimplemented.deterministic-id-hashing.conflict-error-handling + - spec:unimplemented.deterministic-id-hashing.deterministic-stream-id-function + - spec:unimplemented.deterministic-id-hashing.hash-algorithm-selection + - spec:unimplemented.deterministic-id-hashing.pattern-documentation + - spec:unimplemented.event-correctness-migration.append-to-stream-idempotency-migration + - spec:unimplemented.event-correctness-migration.canonical-pm-transition-map-parity + - spec:unimplemented.event-correctness-migration.event-correctness-integration-suite + - spec:unimplemented.event-correctness-migration.global-position-consumer-inventory + - spec:unimplemented.event-correctness-migration.global-position-representation-migration-and-compat-reader + - spec:unimplemented.event-correctness-migration.pdr-015-placeholder + - spec:unimplemented.event-correctness-migration.pdr-018-placeholder + - spec:unimplemented.health-observability.check-liveness-query + - spec:unimplemented.health-observability.check-readiness-query + - spec:unimplemented.health-observability.health-check-types + - spec:unimplemented.health-observability.http-router-with-health-routes + - spec:unimplemented.health-observability.metrics-collector + - spec:unimplemented.health-observability.metrics-types + - spec:unimplemented.health-observability.projection-lag-calculator + - spec:unimplemented.health-observability.system-health-aggregator + - spec:unimplemented.health-observability.workpool-depth-query + - spec:unimplemented.integration-patterns-21a.acl-builder-enhancement + - spec:unimplemented.integration-patterns-21a.context-map-documentation + - spec:unimplemented.integration-patterns-21a.context-map-registry + - spec:unimplemented.integration-patterns-21a.integration-event-metadata-extension + - spec:unimplemented.integration-patterns-21a.published-language-registry + - spec:unimplemented.integration-patterns-21a.to-published-language-converter + - spec:unimplemented.integration-patterns-21b.compatibility-verification + - spec:unimplemented.integration-patterns-21b.consumer-contract-tests + - spec:unimplemented.integration-patterns-21b.contract-sample-generation + - spec:unimplemented.integration-patterns-21b.contract-violation-detection + - spec:unimplemented.integration-patterns-21b.downcaster-implementation + - spec:unimplemented.integration-patterns-21b.migration-path-validation + - spec:unimplemented.integration-patterns-21b.producer-contract-tests + - spec:unimplemented.integration-patterns-21b.upcaster-implementation + - spec:unimplemented.production-hardening.admin-diagnostics + - spec:unimplemented.production-hardening.admin-dlq-endpoints + - spec:unimplemented.production-hardening.admin-projection-endpoints + - spec:unimplemented.production-hardening.circuit-breaker-implementation + - spec:unimplemented.production-hardening.circuit-breaker-retrier-integration + - spec:unimplemented.production-hardening.contract-violation-types + - spec:unimplemented.production-hardening.dlq-action-retrier-pattern + - spec:unimplemented.production-hardening.durable-function-decision-guide + - spec:unimplemented.production-hardening.durable-function-run-diagnostics + - spec:unimplemented.production-hardening.grafana-dashboard-templates + - spec:unimplemented.production-hardening.health-check-queries + - spec:unimplemented.production-hardening.health-http-router + - spec:unimplemented.production-hardening.metrics-collection-types + - spec:unimplemented.production-hardening.metrics-collector + - spec:unimplemented.production-hardening.runbook-documentation + - spec:unimplemented.themed-decision-architecture.add-adr-theme-tag-to-registry + - spec:unimplemented.themed-decision-architecture.adr-migration-scripts + - spec:unimplemented.themed-decision-architecture.dependency-graph-generator + - spec:unimplemented.themed-decision-architecture.review-and-port-33-active-ad-rs + - spec:unimplemented.themed-decision-architecture.theme-grouped-decision-generator + - spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.bus-backend-integration-harness + - spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.dependency-delta-memo + - spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.store-backend-integration-harness + - spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.strict-ts-and-es-lint-hardening + - spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.typecheck-and-vitest-config-alignment + - spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.contract-status-convention-and-linting + - spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.convex-es-rename-guard + - spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.dependency-scanning-in-ci + - spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.docs-process-validation-workflow + - spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.release-automation-aligned-to-architect-releases + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.approval-expiration-ordering-fix + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.correlation-id-required-at-validator-boundary + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.ensure-test-environment-fail-closed + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.full-length-uui-dv7-helper-centralization + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.lifecycle-stubs-throw-or-are-removed + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.platform-store-dependency-decision-guardrails + - spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.reviewer-authorization-default-deny-migration +--- +# Unimplemented + +Named remaining-work items that refine a live platform Spec. Status dumps from docs-living are not carriers. diff --git a/specs/unimplemented/_epic.sdp.md b/specs/unimplemented/_epic.sdp.md new file mode 100644 index 00000000..09af8e7b --- /dev/null +++ b/specs/unimplemented/_epic.sdp.md @@ -0,0 +1,12 @@ +--- +id: spec:unimplemented.backlog +kind: behavior +altitude: epic +readiness: idea +relations: {} +--- +# Unimplemented delivery backlog + +## Intent + +- outcome: Hold non-implemented architect deliverables and remaining-work items until they are authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-001-create-admin-directory.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-001-create-admin-directory.sdp.md new file mode 100644 index 00000000..ab958cd0 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-001-create-admin-directory.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.create-admin-directory +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Create admin/ directory + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Create admin/ directory" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-002-projection-admin-endpoints.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-002-projection-admin-endpoints.sdp.md new file mode 100644 index 00000000..186274e5 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-002-projection-admin-endpoints.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.projection-admin-endpoints +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Projection admin endpoints + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Projection admin endpoints" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-003-refactored-dlq-endpoints.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-003-refactored-dlq-endpoints.sdp.md new file mode 100644 index 00000000..e059b9e0 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-003-refactored-dlq-endpoints.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.refactored-dlq-endpoints +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Refactored DLQ endpoints + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Refactored DLQ endpoints" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-004-event-flow-trace-query.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-004-event-flow-trace-query.sdp.md new file mode 100644 index 00000000..fbf43dcc --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-004-event-flow-trace-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.event-flow-trace-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Event flow trace query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Event flow trace query" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-005-system-state-snapshot-query.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-005-system-state-snapshot-query.sdp.md new file mode 100644 index 00000000..d763f1b6 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-005-system-state-snapshot-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.system-state-snapshot-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# System state snapshot query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "System state snapshot query" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-006-durable-function-run-queries.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-006-durable-function-run-queries.sdp.md new file mode 100644 index 00000000..0d611000 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-006-durable-function-run-queries.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.durable-function-run-queries +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Durable function run queries + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Durable function run queries" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-007-admin-authorization-wrapper.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-007-admin-authorization-wrapper.sdp.md new file mode 100644 index 00000000..eaea542b --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-007-admin-authorization-wrapper.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.admin-authorization-wrapper +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Admin authorization wrapper + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Admin authorization wrapper" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/admin-tooling-consolidation/d-008-admin-api-documentation.sdp.md b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-008-admin-api-documentation.sdp.md new file mode 100644 index 00000000..bbff3518 --- /dev/null +++ b/specs/unimplemented/deliverables/admin-tooling-consolidation/d-008-admin-api-documentation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.admin-tooling-consolidation.admin-api-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.admin-tooling-consolidation +--- +# Admin API documentation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Admin API documentation" until it is authored to a higher readiness rung. +- problem: Admin functionality is scattered across the codebase: - Dead letter queue at 'convex/projections/deadLetters.ts' - Saga admin at 'convex/sagas/admin.ts' - No centralized diagnostics or event flow tracing - No unified interface for durable function inspection This fragmentation makes operational tasks difficult and error-prone. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-001-high-value-agent-config.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-001-high-value-agent-config.sdp.md new file mode 100644 index 00000000..d60e09e0 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-001-high-value-agent-config.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-agent-config +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value agent config + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value agent config" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-002-high-value-pattern-definition.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-002-high-value-pattern-definition.sdp.md new file mode 100644 index 00000000..918035c3 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-002-high-value-pattern-definition.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-pattern-definition +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value pattern definition + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value pattern definition" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-003-high-value-action-handler.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-003-high-value-action-handler.sdp.md new file mode 100644 index 00000000..84ee1c2c --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-003-high-value-action-handler.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-action-handler +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value action handler + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value action handler" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-004-high-value-on-complete-handler.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-004-high-value-on-complete-handler.sdp.md new file mode 100644 index 00000000..06bc5e92 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-004-high-value-on-complete-handler.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-on-complete-handler +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value onComplete handler + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value onComplete handler" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-005-high-value-command-route.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-005-high-value-command-route.sdp.md new file mode 100644 index 00000000..fb8058d7 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-005-high-value-command-route.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-command-route +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value command route + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value command route" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-006-high-value-event-bus-subscription.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-006-high-value-event-bus-subscription.sdp.md new file mode 100644 index 00000000..cdf4b864 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-006-high-value-event-bus-subscription.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-event-bus-subscription +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value EventBus subscription + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value EventBus subscription" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-007-high-value-integration-test-real-llm.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-007-high-value-integration-test-real-llm.sdp.md new file mode 100644 index 00000000..1d79c87b --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-007-high-value-integration-test-real-llm.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.high-value-integration-test-real-llm +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# High-value integration test (real LLM) + +## Intent + +- outcome: Capture the still-unimplemented deliverable "High-value integration test (real LLM)" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-008-dead-letter-management-section-in-monitoring.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-008-dead-letter-management-section-in-monitoring.sdp.md new file mode 100644 index 00000000..9e8b8133 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-008-dead-letter-management-section-in-monitoring.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.dead-letter-management-section-in-monitoring +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Dead letter management section in Monitoring + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dead letter management section in Monitoring" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-009-use-dead-letters-hook.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-009-use-dead-letters-hook.sdp.md new file mode 100644 index 00000000..24648bfd --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-009-use-dead-letters-hook.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.use-dead-letters-hook +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# useDeadLetters hook + +## Intent + +- outcome: Capture the still-unimplemented deliverable "useDeadLetters hook" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-010-use-dead-letter-actions-hook.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-010-use-dead-letter-actions-hook.sdp.md new file mode 100644 index 00000000..4abc9ff4 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-010-use-dead-letter-actions-hook.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.use-dead-letter-actions-hook +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# useDeadLetterActions hook + +## Intent + +- outcome: Capture the still-unimplemented deliverable "useDeadLetterActions hook" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-011-decision-history-tab.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-011-decision-history-tab.sdp.md new file mode 100644 index 00000000..0c5b6342 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-011-decision-history-tab.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.decision-history-tab +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Decision history tab + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Decision history tab" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-012-use-decision-history-hook-with-filters.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-012-use-decision-history-hook-with-filters.sdp.md new file mode 100644 index 00000000..5ff8ba04 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-012-use-decision-history-hook-with-filters.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.use-decision-history-hook-with-filters +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# useDecisionHistory hook with filters + +## Intent + +- outcome: Capture the still-unimplemented deliverable "useDecisionHistory hook with filters" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-013-toast-notification-integration-sonner.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-013-toast-notification-integration-sonner.sdp.md new file mode 100644 index 00000000..9da3840f --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-013-toast-notification-integration-sonner.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.toast-notification-integration-sonner +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Toast notification integration (Sonner) + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Toast notification integration (Sonner)" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-014-action-feedback-toasts.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-014-action-feedback-toasts.sdp.md new file mode 100644 index 00000000..acc81cd8 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-014-action-feedback-toasts.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.action-feedback-toasts +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Action feedback toasts + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Action feedback toasts" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-015-dashboard-update-for-multi-agent.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-015-dashboard-update-for-multi-agent.sdp.md new file mode 100644 index 00000000..9435c2fd --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-015-dashboard-update-for-multi-agent.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.dashboard-update-for-multi-agent +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Dashboard update for multi-agent + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dashboard update for multi-agent" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-016-e2-e-step-definitions.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-016-e2-e-step-definitions.sdp.md new file mode 100644 index 00000000..65907517 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-016-e2-e-step-definitions.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.e2-e-step-definitions +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# E2E step definitions + +## Intent + +- outcome: Capture the still-unimplemented deliverable "E2E step definitions" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-017-agent-admin-page-page-object.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-017-agent-admin-page-page-object.sdp.md new file mode 100644 index 00000000..6f7777f0 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-017-agent-admin-page-page-object.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.agent-admin-page-page-object +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# AgentAdminPage page object + +## Intent + +- outcome: Capture the still-unimplemented deliverable "AgentAdminPage page object" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-018-tag-unimplemented-agent-e2e-scenarios-skip.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-018-tag-unimplemented-agent-e2e-scenarios-skip.sdp.md new file mode 100644 index 00000000..b5d85ae2 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-018-tag-unimplemented-agent-e2e-scenarios-skip.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.tag-unimplemented-agent-e2e-scenarios-skip +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Tag unimplemented agent e2e scenarios @skip + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Tag unimplemented agent e2e scenarios @skip" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-admin-frontend/d-019-auth-integration-documentation.sdp.md b/specs/unimplemented/deliverables/agent-admin-frontend/d-019-auth-integration-documentation.sdp.md new file mode 100644 index 00000000..f3c44d7a --- /dev/null +++ b/specs/unimplemented/deliverables/agent-admin-frontend/d-019-auth-integration-documentation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-admin-frontend.auth-integration-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-admin-frontend +--- +# Auth integration documentation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Auth integration documentation" until it is authored to a higher readiness rung. +- problem: The admin UI at '/admin/agents' has implementation gaps identified in the E2E feature file ('agent-approvals.feature') and investigation: 1. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-001-agent-component-definition.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-001-agent-component-definition.sdp.md new file mode 100644 index 00000000..ac250633 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-001-agent-component-definition.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.agent-component-definition +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Agent component definition + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Agent component definition" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-002-agent-component-schema.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-002-agent-component-schema.sdp.md new file mode 100644 index 00000000..c040ecf8 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-002-agent-component-schema.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.agent-component-schema +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Agent component schema + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Agent component schema" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-003-checkpoint-public-api.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-003-checkpoint-public-api.sdp.md new file mode 100644 index 00000000..31408059 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-003-checkpoint-public-api.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.checkpoint-public-api +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Checkpoint public API + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Checkpoint public API" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-004-audit-public-api.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-004-audit-public-api.sdp.md new file mode 100644 index 00000000..0f4c0723 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-004-audit-public-api.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.audit-public-api +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Audit public API + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Audit public API" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-005-dead-letter-public-api.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-005-dead-letter-public-api.sdp.md new file mode 100644 index 00000000..9f2281bc --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-005-dead-letter-public-api.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.dead-letter-public-api +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Dead letter public API + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dead letter public API" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-006-command-public-api.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-006-command-public-api.sdp.md new file mode 100644 index 00000000..f7110fcc --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-006-command-public-api.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.command-public-api +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Command public API + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Command public API" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-007-approval-public-api.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-007-approval-public-api.sdp.md new file mode 100644 index 00000000..ef5cbac9 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-007-approval-public-api.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.approval-public-api +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Approval public API + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Approval public API" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-bc-component-isolation/d-008-cross-component-query-pattern.sdp.md b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-008-cross-component-query-pattern.sdp.md new file mode 100644 index 00000000..08a5f327 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-bc-component-isolation/d-008-cross-component-query-pattern.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-bc-component-isolation.cross-component-query-pattern +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-bc-component-isolation +--- +# Cross-component query pattern + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Cross-component query pattern" until it is authored to a higher readiness rung. +- problem: Agent BC tables ('agentCheckpoints', 'agentAuditEvents', 'agentDeadLetters', 'agentCommands', 'pendingApprovals') reside in the shared app schema without physical BC isolation. Any app mutation can read/write agent tables directly, violating the core platform principle that bounded contexts should have isolated databases enforced by Convex component boundaries. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-001-agent-action-handler-factory.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-001-agent-action-handler-factory.sdp.md new file mode 100644 index 00000000..e38d1c62 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-001-agent-action-handler-factory.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.agent-action-handler-factory +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Agent action handler factory + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Agent action handler factory" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-002-llm-integrated-on-complete-handler.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-002-llm-integrated-on-complete-handler.sdp.md new file mode 100644 index 00000000..fa0a0c67 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-002-llm-integrated-on-complete-handler.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.llm-integrated-on-complete-handler +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# LLM-integrated onComplete handler + +## Intent + +- outcome: Capture the still-unimplemented deliverable "LLM-integrated onComplete handler" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-003-rate-limiter-integration.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-003-rate-limiter-integration.sdp.md new file mode 100644 index 00000000..3595e697 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-003-rate-limiter-integration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.rate-limiter-integration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Rate limiter integration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Rate limiter integration" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-004-cost-budget-tracking.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-004-cost-budget-tracking.sdp.md new file mode 100644 index 00000000..fa861b99 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-004-cost-budget-tracking.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.cost-budget-tracking +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Cost budget tracking + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Cost budget tracking" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-005-convex-dev-agent-thread-adapter.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-005-convex-dev-agent-thread-adapter.sdp.md new file mode 100644 index 00000000..7f4f5e79 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-005-convex-dev-agent-thread-adapter.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.convex-dev-agent-thread-adapter +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# @convex-dev/agent thread adapter + +## Intent + +- outcome: Capture the still-unimplemented deliverable "@convex-dev/agent thread adapter" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-006-on-complete-in-create-agent-subscription-options.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-006-on-complete-in-create-agent-subscription-options.sdp.md new file mode 100644 index 00000000..95474196 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-006-on-complete-in-create-agent-subscription-options.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.on-complete-in-create-agent-subscription-options +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# onComplete in CreateAgentSubscriptionOptions + +## Intent + +- outcome: Capture the still-unimplemented deliverable "onComplete in CreateAgentSubscriptionOptions" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-007-circuit-breaker-for-llm.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-007-circuit-breaker-for-llm.sdp.md new file mode 100644 index 00000000..3e28049a --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-007-circuit-breaker-for-llm.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.circuit-breaker-for-llm +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Circuit breaker for LLM + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker for LLM" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-008-agent-workpool-configuration.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-008-agent-workpool-configuration.sdp.md new file mode 100644 index 00000000..1880e146 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-008-agent-workpool-configuration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.agent-workpool-configuration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Agent workpool configuration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Agent workpool configuration" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/agent-llm-integration/d-009-action-mutation-integration-test.sdp.md b/specs/unimplemented/deliverables/agent-llm-integration/d-009-action-mutation-integration-test.sdp.md new file mode 100644 index 00000000..51502d30 --- /dev/null +++ b/specs/unimplemented/deliverables/agent-llm-integration/d-009-action-mutation-integration-test.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.agent-llm-integration.action-mutation-integration-test +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.agent-llm-integration +--- +# Action/mutation integration test + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Action/mutation integration test" until it is authored to a higher readiness rung. +- problem: The agent event handler ('handleChurnRiskEvent') is a Convex mutation that cannot call external APIs. The LLM runtime ('_llm/runtime.ts') exists with OpenRouter integration but is never invoked because mutations cannot make HTTP calls. Additionally, rate limiting config exists as types only — no runtime enforcement protects against runaway LLM costs. diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-001-circuit-breaker-state-machine-pure.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-001-circuit-breaker-state-machine-pure.sdp.md new file mode 100644 index 00000000..f491e0a4 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-001-circuit-breaker-state-machine-pure.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.circuit-breaker-state-machine-pure +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# Circuit breaker state machine (pure) + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker state machine (pure)" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-002-circuit-breaker-types.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-002-circuit-breaker-types.sdp.md new file mode 100644 index 00000000..b3a142bd --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-002-circuit-breaker-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.circuit-breaker-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# Circuit breaker types + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker types" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-003-circuit-breakers-table-schema.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-003-circuit-breakers-table-schema.sdp.md new file mode 100644 index 00000000..f4fe90ab --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-003-circuit-breakers-table-schema.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.circuit-breakers-table-schema +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# circuitBreakers table schema + +## Intent + +- outcome: Capture the still-unimplemented deliverable "circuitBreakers table schema" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-004-with-circuit-breaker-wrapper.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-004-with-circuit-breaker-wrapper.sdp.md new file mode 100644 index 00000000..f0a75b91 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-004-with-circuit-breaker-wrapper.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.with-circuit-breaker-wrapper +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# withCircuitBreaker wrapper + +## Intent + +- outcome: Capture the still-unimplemented deliverable "withCircuitBreaker wrapper" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-005-load-circuit-state-query.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-005-load-circuit-state-query.sdp.md new file mode 100644 index 00000000..2ec933bb --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-005-load-circuit-state-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.load-circuit-state-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# loadCircuitState query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "loadCircuitState query" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-006-record-success-mutation.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-006-record-success-mutation.sdp.md new file mode 100644 index 00000000..28849b97 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-006-record-success-mutation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.record-success-mutation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# recordSuccess mutation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "recordSuccess mutation" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-007-record-failure-mutation.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-007-record-failure-mutation.sdp.md new file mode 100644 index 00000000..6c345a01 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-007-record-failure-mutation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.record-failure-mutation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# recordFailure mutation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "recordFailure mutation" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-008-check-half-open-scheduled-mutation.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-008-check-half-open-scheduled-mutation.sdp.md new file mode 100644 index 00000000..51b9eb6a --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-008-check-half-open-scheduled-mutation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.check-half-open-scheduled-mutation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# checkHalfOpen scheduled mutation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "checkHalfOpen scheduled mutation" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-009-on-circuit-probe-complete-handler.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-009-on-circuit-probe-complete-handler.sdp.md new file mode 100644 index 00000000..38447f23 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-009-on-circuit-probe-complete-handler.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.on-circuit-probe-complete-handler +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# onCircuitProbeComplete handler + +## Intent + +- outcome: Capture the still-unimplemented deliverable "onCircuitProbeComplete handler" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/circuit-breaker-pattern/d-010-circuit-breaker-metrics.sdp.md b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-010-circuit-breaker-metrics.sdp.md new file mode 100644 index 00000000..bf98a746 --- /dev/null +++ b/specs/unimplemented/deliverables/circuit-breaker-pattern/d-010-circuit-breaker-metrics.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.circuit-breaker-pattern.circuit-breaker-metrics +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.circuit-breaker-pattern +--- +# Circuit breaker metrics + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker metrics" until it is authored to a higher readiness rung. +- problem: External API failures (Stripe, SendGrid, webhooks) cascade through the system. Without automatic isolation: - Action budget is wasted on calls destined to fail - Users experience long timeouts instead of fast failures - Partial outages become full outages via resource exhaustion - No automatic recovery testing when service comes back diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-001-pdr-014-placeholder.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-001-pdr-014-placeholder.sdp.md new file mode 100644 index 00000000..87bf2f98 --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-001-pdr-014-placeholder.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.pdr-014-placeholder +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# PDR-014 placeholder + +## Intent + +- outcome: Capture the still-unimplemented deliverable "PDR-014 placeholder" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-002-canonical-verification-proof-contract.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-002-canonical-verification-proof-contract.sdp.md new file mode 100644 index 00000000..f6164338 --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-002-canonical-verification-proof-contract.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.canonical-verification-proof-contract +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# Canonical verificationProof contract + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Canonical verificationProof contract" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-003-verify-actor-helper.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-003-verify-actor-helper.sdp.md new file mode 100644 index 00000000..0fd1e65c --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-003-verify-actor-helper.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.verify-actor-helper +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# verifyActor helper + +## Intent + +- outcome: Capture the still-unimplemented deliverable "verifyActor helper" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-004-identity-bearing-mutation-migration.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-004-identity-bearing-mutation-migration.sdp.md new file mode 100644 index 00000000..f8ca25ab --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-004-identity-bearing-mutation-migration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.identity-bearing-mutation-migration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# Identity-bearing mutation migration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Identity-bearing mutation migration" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-005-contract-status-tagging-for-system-only-exceptions.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-005-contract-status-tagging-for-system-only-exceptions.sdp.md new file mode 100644 index 00000000..a26739ba --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-005-contract-status-tagging-for-system-only-exceptions.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.contract-status-tagging-for-system-only-exceptions +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# Contract-status tagging for system-only exceptions + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Contract-status tagging for system-only exceptions" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-006-component-boundary-auth-integration-suite.sdp.md b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-006-component-boundary-auth-integration-suite.sdp.md new file mode 100644 index 00000000..c94ab292 --- /dev/null +++ b/specs/unimplemented/deliverables/component-boundary-authentication-convention/d-006-component-boundary-auth-integration-suite.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.component-boundary-authentication-convention.component-boundary-auth-integration-suite +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.component-boundary-authentication-convention +--- +# Component-boundary auth integration suite + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Component-boundary auth integration suite" until it is authored to a higher readiness rung. +- problem: Identity-bearing component mutations still trust caller-provided actor fields without a canonical component-side proof contract. Fixing the affected mutations piecemeal would create drift and leave a mixed-trust window across approvals, audit, and event append flows. diff --git a/specs/unimplemented/deliverables/deterministic-id-hashing/d-001-deterministic-stream-id-function.sdp.md b/specs/unimplemented/deliverables/deterministic-id-hashing/d-001-deterministic-stream-id-function.sdp.md new file mode 100644 index 00000000..50181d89 --- /dev/null +++ b/specs/unimplemented/deliverables/deterministic-id-hashing/d-001-deterministic-stream-id-function.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.deterministic-id-hashing.deterministic-stream-id-function +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.deterministic-id-hashing +--- +# deterministicStreamId() function + +## Intent + +- outcome: Capture the still-unimplemented deliverable "deterministicStreamId() function" until it is authored to a higher readiness rung. +- problem: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. diff --git a/specs/unimplemented/deliverables/deterministic-id-hashing/d-002-hash-algorithm-selection.sdp.md b/specs/unimplemented/deliverables/deterministic-id-hashing/d-002-hash-algorithm-selection.sdp.md new file mode 100644 index 00000000..781827ef --- /dev/null +++ b/specs/unimplemented/deliverables/deterministic-id-hashing/d-002-hash-algorithm-selection.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.deterministic-id-hashing.hash-algorithm-selection +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.deterministic-id-hashing +--- +# Hash algorithm selection + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Hash algorithm selection" until it is authored to a higher readiness rung. +- problem: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. diff --git a/specs/unimplemented/deliverables/deterministic-id-hashing/d-003-conflict-error-handling.sdp.md b/specs/unimplemented/deliverables/deterministic-id-hashing/d-003-conflict-error-handling.sdp.md new file mode 100644 index 00000000..6735753f --- /dev/null +++ b/specs/unimplemented/deliverables/deterministic-id-hashing/d-003-conflict-error-handling.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.deterministic-id-hashing.conflict-error-handling +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.deterministic-id-hashing +--- +# Conflict error handling + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Conflict error handling" until it is authored to a higher readiness rung. +- problem: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. diff --git a/specs/unimplemented/deliverables/deterministic-id-hashing/d-004-pattern-documentation.sdp.md b/specs/unimplemented/deliverables/deterministic-id-hashing/d-004-pattern-documentation.sdp.md new file mode 100644 index 00000000..1e716f84 --- /dev/null +++ b/specs/unimplemented/deliverables/deterministic-id-hashing/d-004-pattern-documentation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.deterministic-id-hashing.pattern-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.deterministic-id-hashing +--- +# Pattern documentation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Pattern documentation" until it is authored to a higher readiness rung. +- problem: TTL-based reservations work well for multi-step flows (registration wizards), but add overhead for simple "create if unique" operations. Need a lighter-weight alternative. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-001-global-position-consumer-inventory.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-001-global-position-consumer-inventory.sdp.md new file mode 100644 index 00000000..bcef1dd3 --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-001-global-position-consumer-inventory.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.global-position-consumer-inventory +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# globalPosition consumer inventory + +## Intent + +- outcome: Capture the still-unimplemented deliverable "globalPosition consumer inventory" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-002-pdr-018-placeholder.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-002-pdr-018-placeholder.sdp.md new file mode 100644 index 00000000..9f22213d --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-002-pdr-018-placeholder.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.pdr-018-placeholder +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# PDR-018 placeholder + +## Intent + +- outcome: Capture the still-unimplemented deliverable "PDR-018 placeholder" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-003-pdr-015-placeholder.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-003-pdr-015-placeholder.sdp.md new file mode 100644 index 00000000..4a1a726d --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-003-pdr-015-placeholder.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.pdr-015-placeholder +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# PDR-015 placeholder + +## Intent + +- outcome: Capture the still-unimplemented deliverable "PDR-015 placeholder" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-004-append-to-stream-idempotency-migration.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-004-append-to-stream-idempotency-migration.sdp.md new file mode 100644 index 00000000..2c5df01e --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-004-append-to-stream-idempotency-migration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.append-to-stream-idempotency-migration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# appendToStream idempotency migration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "appendToStream idempotency migration" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-005-global-position-representation-migration-and-compat-reader.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-005-global-position-representation-migration-and-compat-reader.sdp.md new file mode 100644 index 00000000..9a326b22 --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-005-global-position-representation-migration-and-compat-reader.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.global-position-representation-migration-and-compat-reader +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# globalPosition representation migration and compat reader + +## Intent + +- outcome: Capture the still-unimplemented deliverable "globalPosition representation migration and compat reader" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-006-canonical-pm-transition-map-parity.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-006-canonical-pm-transition-map-parity.sdp.md new file mode 100644 index 00000000..34b151eb --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-006-canonical-pm-transition-map-parity.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.canonical-pm-transition-map-parity +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# Canonical PM transition map parity + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Canonical PM transition map parity" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/event-correctness-migration/d-007-event-correctness-integration-suite.sdp.md b/specs/unimplemented/deliverables/event-correctness-migration/d-007-event-correctness-integration-suite.sdp.md new file mode 100644 index 00000000..fb560495 --- /dev/null +++ b/specs/unimplemented/deliverables/event-correctness-migration/d-007-event-correctness-integration-suite.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.event-correctness-migration.event-correctness-integration-suite +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.event-correctness-migration +--- +# Event correctness integration suite + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Event correctness integration suite" until it is authored to a higher readiness rung. +- problem: 'appendToStream' idempotency semantics, 'globalPosition' precision, and process-manager lifecycle parity are coupled correctness concerns. Splitting them would create inconsistent event-store guarantees and leave downstream consumers migrating against moving contracts. diff --git a/specs/unimplemented/deliverables/health-observability/d-001-health-check-types.sdp.md b/specs/unimplemented/deliverables/health-observability/d-001-health-check-types.sdp.md new file mode 100644 index 00000000..420eedba --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-001-health-check-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.health-check-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# Health check types + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Health check types" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-002-check-readiness-query.sdp.md b/specs/unimplemented/deliverables/health-observability/d-002-check-readiness-query.sdp.md new file mode 100644 index 00000000..47dd02da --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-002-check-readiness-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.check-readiness-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# checkReadiness query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "checkReadiness query" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-003-check-liveness-query.sdp.md b/specs/unimplemented/deliverables/health-observability/d-003-check-liveness-query.sdp.md new file mode 100644 index 00000000..036fa2dc --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-003-check-liveness-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.check-liveness-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# checkLiveness query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "checkLiveness query" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-004-http-router-with-health-routes.sdp.md b/specs/unimplemented/deliverables/health-observability/d-004-http-router-with-health-routes.sdp.md new file mode 100644 index 00000000..ad2e3896 --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-004-http-router-with-health-routes.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.http-router-with-health-routes +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# HTTP router with /health/* routes + +## Intent + +- outcome: Capture the still-unimplemented deliverable "HTTP router with /health/* routes" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-005-metrics-types.sdp.md b/specs/unimplemented/deliverables/health-observability/d-005-metrics-types.sdp.md new file mode 100644 index 00000000..01dac24f --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-005-metrics-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.metrics-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# Metrics types + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Metrics types" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-006-metrics-collector.sdp.md b/specs/unimplemented/deliverables/health-observability/d-006-metrics-collector.sdp.md new file mode 100644 index 00000000..9722679c --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-006-metrics-collector.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.metrics-collector +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# MetricsCollector + +## Intent + +- outcome: Capture the still-unimplemented deliverable "MetricsCollector" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-007-projection-lag-calculator.sdp.md b/specs/unimplemented/deliverables/health-observability/d-007-projection-lag-calculator.sdp.md new file mode 100644 index 00000000..2851ee3d --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-007-projection-lag-calculator.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.projection-lag-calculator +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# Projection lag calculator + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Projection lag calculator" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-008-workpool-depth-query.sdp.md b/specs/unimplemented/deliverables/health-observability/d-008-workpool-depth-query.sdp.md new file mode 100644 index 00000000..87851f6a --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-008-workpool-depth-query.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.workpool-depth-query +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# Workpool depth query + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Workpool depth query" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/health-observability/d-009-system-health-aggregator.sdp.md b/specs/unimplemented/deliverables/health-observability/d-009-system-health-aggregator.sdp.md new file mode 100644 index 00000000..0f3b538e --- /dev/null +++ b/specs/unimplemented/deliverables/health-observability/d-009-system-health-aggregator.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.health-observability.system-health-aggregator +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.health-observability +--- +# System health aggregator + +## Intent + +- outcome: Capture the still-unimplemented deliverable "System health aggregator" until it is authored to a higher readiness rung. +- problem: No Kubernetes integration (readiness/liveness probes), no metrics for projection lag, event throughput, or system health. Operations team has no visibility into system state, cannot detect degradation before it becomes an outage, and cannot integrate with standard orchestration platforms. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-001-context-map-registry.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-001-context-map-registry.sdp.md new file mode 100644 index 00000000..e6f3771d --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-001-context-map-registry.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.context-map-registry +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# Context Map registry + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Context Map registry" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-002-context-map-documentation.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-002-context-map-documentation.sdp.md new file mode 100644 index 00000000..01bd9f91 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-002-context-map-documentation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.context-map-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# Context Map documentation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Context Map documentation" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-003-published-language-registry.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-003-published-language-registry.sdp.md new file mode 100644 index 00000000..e0d39607 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-003-published-language-registry.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.published-language-registry +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# Published Language registry + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Published Language registry" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-004-to-published-language-converter.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-004-to-published-language-converter.sdp.md new file mode 100644 index 00000000..c29eb29b --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-004-to-published-language-converter.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.to-published-language-converter +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# toPublishedLanguage() converter + +## Intent + +- outcome: Capture the still-unimplemented deliverable "toPublishedLanguage() converter" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-005-acl-builder-enhancement.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-005-acl-builder-enhancement.sdp.md new file mode 100644 index 00000000..db11d7de --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-005-acl-builder-enhancement.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.acl-builder-enhancement +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# ACL builder enhancement + +## Intent + +- outcome: Capture the still-unimplemented deliverable "ACL builder enhancement" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21a/d-006-integration-event-metadata-extension.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21a/d-006-integration-event-metadata-extension.sdp.md new file mode 100644 index 00000000..87ff6cae --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21a/d-006-integration-event-metadata-extension.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21a.integration-event-metadata-extension +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21a +--- +# IntegrationEventMetadata extension + +## Intent + +- outcome: Capture the still-unimplemented deliverable "IntegrationEventMetadata extension" until it is authored to a higher readiness rung. +- problem: Cross-context communication is ad-hoc. Domain events are used directly for integration without explicit contracts, leading to tight coupling. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-001-upcaster-implementation.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-001-upcaster-implementation.sdp.md new file mode 100644 index 00000000..72780c8a --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-001-upcaster-implementation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.upcaster-implementation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Upcaster implementation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Upcaster implementation" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-002-downcaster-implementation.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-002-downcaster-implementation.sdp.md new file mode 100644 index 00000000..f58ff155 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-002-downcaster-implementation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.downcaster-implementation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Downcaster implementation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Downcaster implementation" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-003-migration-path-validation.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-003-migration-path-validation.sdp.md new file mode 100644 index 00000000..72031bf5 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-003-migration-path-validation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.migration-path-validation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Migration path validation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Migration path validation" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-004-contract-sample-generation.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-004-contract-sample-generation.sdp.md new file mode 100644 index 00000000..779aa496 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-004-contract-sample-generation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.contract-sample-generation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Contract sample generation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Contract sample generation" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-005-producer-contract-tests.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-005-producer-contract-tests.sdp.md new file mode 100644 index 00000000..1b9b58ea --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-005-producer-contract-tests.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.producer-contract-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Producer contract tests + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Producer contract tests" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-006-consumer-contract-tests.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-006-consumer-contract-tests.sdp.md new file mode 100644 index 00000000..b940bea0 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-006-consumer-contract-tests.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.consumer-contract-tests +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Consumer contract tests + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Consumer contract tests" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-007-compatibility-verification.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-007-compatibility-verification.sdp.md new file mode 100644 index 00000000..d539503a --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-007-compatibility-verification.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.compatibility-verification +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Compatibility verification + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Compatibility verification" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/integration-patterns-21b/d-008-contract-violation-detection.sdp.md b/specs/unimplemented/deliverables/integration-patterns-21b/d-008-contract-violation-detection.sdp.md new file mode 100644 index 00000000..f7c89c01 --- /dev/null +++ b/specs/unimplemented/deliverables/integration-patterns-21b/d-008-contract-violation-detection.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.integration-patterns-21b.contract-violation-detection +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.integration-patterns-21b +--- +# Contract violation detection + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Contract violation detection" until it is authored to a higher readiness rung. +- problem: Schema evolution breaks consumers. No tooling validates producer-consumer compatibility, leading to runtime failures and integration bugs. diff --git a/specs/unimplemented/deliverables/production-hardening/d-001-metrics-collection-types.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-001-metrics-collection-types.sdp.md new file mode 100644 index 00000000..96182268 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-001-metrics-collection-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.metrics-collection-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Metrics collection types + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Metrics collection types" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-002-metrics-collector.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-002-metrics-collector.sdp.md new file mode 100644 index 00000000..b13c9578 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-002-metrics-collector.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.metrics-collector +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Metrics collector + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Metrics collector" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-003-health-check-queries.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-003-health-check-queries.sdp.md new file mode 100644 index 00000000..07c010e8 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-003-health-check-queries.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.health-check-queries +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Health check queries + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Health check queries" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-004-health-http-router.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-004-health-http-router.sdp.md new file mode 100644 index 00000000..ca4f59da --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-004-health-http-router.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.health-http-router +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Health HTTP router + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Health HTTP router" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-005-circuit-breaker-implementation.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-005-circuit-breaker-implementation.sdp.md new file mode 100644 index 00000000..1ff52238 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-005-circuit-breaker-implementation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.circuit-breaker-implementation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Circuit breaker implementation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker implementation" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-006-admin-projection-endpoints.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-006-admin-projection-endpoints.sdp.md new file mode 100644 index 00000000..2947ea6f --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-006-admin-projection-endpoints.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.admin-projection-endpoints +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Admin projection endpoints + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Admin projection endpoints" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-007-admin-dlq-endpoints.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-007-admin-dlq-endpoints.sdp.md new file mode 100644 index 00000000..6b247319 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-007-admin-dlq-endpoints.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.admin-dlq-endpoints +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Admin DLQ endpoints + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Admin DLQ endpoints" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-008-admin-diagnostics.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-008-admin-diagnostics.sdp.md new file mode 100644 index 00000000..9e5cd72f --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-008-admin-diagnostics.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.admin-diagnostics +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Admin diagnostics + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Admin diagnostics" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-009-durable-function-run-diagnostics.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-009-durable-function-run-diagnostics.sdp.md new file mode 100644 index 00000000..3bb4d90a --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-009-durable-function-run-diagnostics.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.durable-function-run-diagnostics +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Durable function run diagnostics + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Durable function run diagnostics" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-010-contract-violation-types.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-010-contract-violation-types.sdp.md new file mode 100644 index 00000000..11219b2f --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-010-contract-violation-types.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.contract-violation-types +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Contract violation types + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Contract violation types" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-011-grafana-dashboard-templates.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-011-grafana-dashboard-templates.sdp.md new file mode 100644 index 00000000..1a254d84 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-011-grafana-dashboard-templates.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.grafana-dashboard-templates +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Grafana dashboard templates + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Grafana dashboard templates" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-012-runbook-documentation.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-012-runbook-documentation.sdp.md new file mode 100644 index 00000000..e731d2da --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-012-runbook-documentation.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.runbook-documentation +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Runbook documentation + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Runbook documentation" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-013-circuit-breaker-retrier-integration.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-013-circuit-breaker-retrier-integration.sdp.md new file mode 100644 index 00000000..62604b6e --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-013-circuit-breaker-retrier-integration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.circuit-breaker-retrier-integration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Circuit breaker retrier integration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Circuit breaker retrier integration" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-014-dlq-action-retrier-pattern.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-014-dlq-action-retrier-pattern.sdp.md new file mode 100644 index 00000000..e2b63d25 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-014-dlq-action-retrier-pattern.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.dlq-action-retrier-pattern +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# DLQ action retrier pattern + +## Intent + +- outcome: Capture the still-unimplemented deliverable "DLQ action retrier pattern" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/production-hardening/d-015-durable-function-decision-guide.sdp.md b/specs/unimplemented/deliverables/production-hardening/d-015-durable-function-decision-guide.sdp.md new file mode 100644 index 00000000..43c82465 --- /dev/null +++ b/specs/unimplemented/deliverables/production-hardening/d-015-durable-function-decision-guide.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.production-hardening.durable-function-decision-guide +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.production-hardening +--- +# Durable function decision guide + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Durable function decision guide" until it is authored to a higher readiness rung. +- problem: Structured logging (Phase 13) exists but no metrics collection, distributed tracing, or admin tooling for production operations. Teams cannot monitor system health, trace event flows, or perform operational tasks like projection rebuilds without direct database access. diff --git a/specs/unimplemented/deliverables/themed-decision-architecture/d-001-add-adr-theme-tag-to-registry.sdp.md b/specs/unimplemented/deliverables/themed-decision-architecture/d-001-add-adr-theme-tag-to-registry.sdp.md new file mode 100644 index 00000000..1c5ba7f9 --- /dev/null +++ b/specs/unimplemented/deliverables/themed-decision-architecture/d-001-add-adr-theme-tag-to-registry.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:unimplemented.themed-decision-architecture.add-adr-theme-tag-to-registry +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.themed-decision-architecture +--- +# Add `adr-theme` tag to registry + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Add 'adr-theme' tag to registry" until it is authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/themed-decision-architecture/d-002-theme-grouped-decision-generator.sdp.md b/specs/unimplemented/deliverables/themed-decision-architecture/d-002-theme-grouped-decision-generator.sdp.md new file mode 100644 index 00000000..725002ae --- /dev/null +++ b/specs/unimplemented/deliverables/themed-decision-architecture/d-002-theme-grouped-decision-generator.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:unimplemented.themed-decision-architecture.theme-grouped-decision-generator +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.themed-decision-architecture +--- +# Theme-grouped decision generator + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Theme-grouped decision generator" until it is authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/themed-decision-architecture/d-003-dependency-graph-generator.sdp.md b/specs/unimplemented/deliverables/themed-decision-architecture/d-003-dependency-graph-generator.sdp.md new file mode 100644 index 00000000..950a0f3e --- /dev/null +++ b/specs/unimplemented/deliverables/themed-decision-architecture/d-003-dependency-graph-generator.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:unimplemented.themed-decision-architecture.dependency-graph-generator +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.themed-decision-architecture +--- +# Dependency graph generator + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dependency graph generator" until it is authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/themed-decision-architecture/d-004-adr-migration-scripts.sdp.md b/specs/unimplemented/deliverables/themed-decision-architecture/d-004-adr-migration-scripts.sdp.md new file mode 100644 index 00000000..68fd467a --- /dev/null +++ b/specs/unimplemented/deliverables/themed-decision-architecture/d-004-adr-migration-scripts.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:unimplemented.themed-decision-architecture.adr-migration-scripts +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.themed-decision-architecture +--- +# ADR migration scripts + +## Intent + +- outcome: Capture the still-unimplemented deliverable "ADR migration scripts" until it is authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/themed-decision-architecture/d-005-review-and-port-33-active-ad-rs.sdp.md b/specs/unimplemented/deliverables/themed-decision-architecture/d-005-review-and-port-33-active-ad-rs.sdp.md new file mode 100644 index 00000000..ab672760 --- /dev/null +++ b/specs/unimplemented/deliverables/themed-decision-architecture/d-005-review-and-port-33-active-ad-rs.sdp.md @@ -0,0 +1,13 @@ +--- +id: spec:unimplemented.themed-decision-architecture.review-and-port-33-active-ad-rs +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.themed-decision-architecture +--- +# Review and port 33 active ADRs + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Review and port 33 active ADRs" until it is authored to a higher readiness rung. diff --git a/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-001-dependency-delta-memo.sdp.md b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-001-dependency-delta-memo.sdp.md new file mode 100644 index 00000000..f7fd4fbf --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-001-dependency-delta-memo.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.dependency-delta-memo +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +--- +# Dependency delta memo + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dependency delta memo" until it is authored to a higher readiness rung. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. diff --git a/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-002-store-backend-integration-harness.sdp.md b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-002-store-backend-integration-harness.sdp.md new file mode 100644 index 00000000..e387419d --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-002-store-backend-integration-harness.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.store-backend-integration-harness +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +--- +# Store backend integration harness + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Store backend integration harness" until it is authored to a higher readiness rung. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. diff --git a/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-003-bus-backend-integration-harness.sdp.md b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-003-bus-backend-integration-harness.sdp.md new file mode 100644 index 00000000..1c71a6f6 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-003-bus-backend-integration-harness.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.bus-backend-integration-harness +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +--- +# Bus backend integration harness + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Bus backend integration harness" until it is authored to a higher readiness rung. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. diff --git a/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-004-typecheck-and-vitest-config-alignment.sdp.md b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-004-typecheck-and-vitest-config-alignment.sdp.md new file mode 100644 index 00000000..0a5cc4bf --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-004-typecheck-and-vitest-config-alignment.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.typecheck-and-vitest-config-alignment +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +--- +# Typecheck and Vitest config alignment + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Typecheck and Vitest config alignment" until it is authored to a higher readiness rung. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. diff --git a/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-005-strict-ts-and-es-lint-hardening.sdp.md b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-005-strict-ts-and-es-lint-hardening.sdp.md new file mode 100644 index 00000000..d1e39d73 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-readiness-harness-and-dependency-hardening/d-005-strict-ts-and-es-lint-hardening.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-readiness-harness-and-dependency-hardening.strict-ts-and-es-lint-hardening +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-readiness-harness-and-dependency-hardening +--- +# Strict TS and ESLint hardening + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Strict TS and ESLint hardening" until it is authored to a higher readiness rung. +- problem: The remediation program cannot safely begin security or correctness migrations while 'platform-store' lacks a real backend integration harness, 'platform-bus' relies on thin backend coverage, and package validation posture still permits configuration drift. diff --git a/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-001-release-automation-aligned-to-architect-releases.sdp.md b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-001-release-automation-aligned-to-architect-releases.sdp.md new file mode 100644 index 00000000..441e17fe --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-001-release-automation-aligned-to-architect-releases.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.release-automation-aligned-to-architect-releases +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +--- +# Release automation aligned to architect releases + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Release automation aligned to architect releases" until it is authored to a higher readiness rung. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. diff --git a/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-002-dependency-scanning-in-ci.sdp.md b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-002-dependency-scanning-in-ci.sdp.md new file mode 100644 index 00000000..f977f9d7 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-002-dependency-scanning-in-ci.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.dependency-scanning-in-ci +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +--- +# Dependency scanning in CI + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Dependency scanning in CI" until it is authored to a higher readiness rung. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. diff --git a/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-003-contract-status-convention-and-linting.sdp.md b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-003-contract-status-convention-and-linting.sdp.md new file mode 100644 index 00000000..2bf5686d --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-003-contract-status-convention-and-linting.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.contract-status-convention-and-linting +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +--- +# Contract-status convention and linting + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Contract-status convention and linting" until it is authored to a higher readiness rung. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. diff --git a/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-004-convex-es-rename-guard.sdp.md b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-004-convex-es-rename-guard.sdp.md new file mode 100644 index 00000000..d2972eb5 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-004-convex-es-rename-guard.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.convex-es-rename-guard +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +--- +# @convex-es rename guard + +## Intent + +- outcome: Capture the still-unimplemented deliverable "@convex-es rename guard" until it is authored to a higher readiness rung. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. diff --git a/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-005-docs-process-validation-workflow.sdp.md b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-005-docs-process-validation-workflow.sdp.md new file mode 100644 index 00000000..84741d67 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-0-release-ci-and-docs-process-guardrails/d-005-docs-process-validation-workflow.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-0-release-ci-and-docs-process-guardrails.docs-process-validation-workflow +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-0-release-ci-and-docs-process-guardrails +--- +# Docs/process validation workflow + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Docs/process validation workflow" until it is authored to a higher readiness rung. +- problem: 'test.yml' ignores markdown and docs-only changes, release automation is not yet normalized around architect release metadata, and new remediation contracts need an explicit advertised-vs-enforced convention before runtime fixes start landing. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-001-ensure-test-environment-fail-closed.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-001-ensure-test-environment-fail-closed.sdp.md new file mode 100644 index 00000000..bfaabc1c --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-001-ensure-test-environment-fail-closed.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.ensure-test-environment-fail-closed +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# ensureTestEnvironment fail-closed + +## Intent + +- outcome: Capture the still-unimplemented deliverable "ensureTestEnvironment fail-closed" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-002-correlation-id-required-at-validator-boundary.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-002-correlation-id-required-at-validator-boundary.sdp.md new file mode 100644 index 00000000..788b9e3a --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-002-correlation-id-required-at-validator-boundary.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.correlation-id-required-at-validator-boundary +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# correlationId required at validator boundary + +## Intent + +- outcome: Capture the still-unimplemented deliverable "correlationId required" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-003-full-length-uui-dv7-helper-centralization.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-003-full-length-uui-dv7-helper-centralization.sdp.md new file mode 100644 index 00000000..74bdf227 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-003-full-length-uui-dv7-helper-centralization.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.full-length-uui-dv7-helper-centralization +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# Full-length UUIDv7 helper centralization + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Full-length UUIDv7 helper centralization" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-004-reviewer-authorization-default-deny-migration.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-004-reviewer-authorization-default-deny-migration.sdp.md new file mode 100644 index 00000000..fcf0b1f2 --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-004-reviewer-authorization-default-deny-migration.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.reviewer-authorization-default-deny-migration +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# Reviewer authorization default-deny migration + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Reviewer authorization default-deny migration" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-005-approval-expiration-ordering-fix.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-005-approval-expiration-ordering-fix.sdp.md new file mode 100644 index 00000000..9edd353c --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-005-approval-expiration-ordering-fix.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.approval-expiration-ordering-fix +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# Approval expiration ordering fix + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Approval expiration ordering fix" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-006-lifecycle-stubs-throw-or-are-removed.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-006-lifecycle-stubs-throw-or-are-removed.sdp.md new file mode 100644 index 00000000..e88452ca --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-006-lifecycle-stubs-throw-or-are-removed.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.lifecycle-stubs-throw-or-are-removed +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# Lifecycle stubs throw or are removed + +## Intent + +- outcome: Capture the still-unimplemented deliverable "Lifecycle stubs throw or are removed" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-007-platform-store-dependency-decision-guardrails.sdp.md b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-007-platform-store-dependency-decision-guardrails.sdp.md new file mode 100644 index 00000000..c66318ed --- /dev/null +++ b/specs/unimplemented/deliverables/tranche-1-supporting-security-and-contract-sweep/d-007-platform-store-dependency-decision-guardrails.sdp.md @@ -0,0 +1,14 @@ +--- +id: spec:unimplemented.tranche-1-supporting-security-and-contract-sweep.platform-store-dependency-decision-guardrails +kind: behavior +altitude: story +readiness: idea +relations: + refines: spec:platform.tranche-1-supporting-security-and-contract-sweep +--- +# platform-store dependency decision + guardrails + +## Intent + +- outcome: Capture the still-unimplemented deliverable "platform-store dependency decision + guardrails" until it is authored to a higher readiness rung. +- problem: Several tranche-1 gaps remain after the auth keystone: test-mode checks fail open, correlation IDs can be fabricated, reviewer authorization still needs default-deny cleanup, lifecycle stubs leak placeholder behavior, and 'platform-store' still lacks a recorded decision for its constrained 'platform-core' runtime dependency. diff --git a/test/sdp-migration-guard.test.ts b/test/sdp-migration-guard.test.ts new file mode 100644 index 00000000..e6bb228a --- /dev/null +++ b/test/sdp-migration-guard.test.ts @@ -0,0 +1,130 @@ +import { readFileSync, existsSync, readdirSync, statSync } from "node:fs"; +import { join, relative } from "node:path"; +import { describe, expect, it } from "vitest"; + +const ROOT = join(import.meta.dirname, ".."); + +function readJson(path: string): Record { + return JSON.parse(readFileSync(path, "utf8")) as Record; +} + +function walkFiles(dir: string, out: string[] = []): string[] { + if (!existsSync(dir)) return out; + for (const name of readdirSync(dir)) { + if (name === "node_modules" || name === "dist" || name === "generated") continue; + const full = join(dir, name); + const st = statSync(full); + if (st.isDirectory()) { + if (name.startsWith(".")) continue; + walkFiles(full, out); + } else { + out.push(full); + } + } + return out; +} + +describe("SDP migration guard", () => { + it("does not depend on @libar-dev/architect and installs SDP", () => { + const pkg = readJson(join(ROOT, "package.json")); + const deps = { + ...(pkg.dependencies as Record | undefined), + ...(pkg.devDependencies as Record | undefined), + }; + expect(deps["@libar-dev/architect"]).toBeUndefined(); + expect(deps["@libar-dev/software-delivery-protocol"]).toBeTruthy(); + + const lock = readFileSync(join(ROOT, "pnpm-lock.yaml"), "utf8"); + expect(lock).not.toMatch(/['"]@libar-dev\/architect@/); + expect(lock).toMatch(/@libar-dev\/software-delivery-protocol/); + }); + + it("does not wire architect bins as live package scripts", () => { + const pkg = readJson(join(ROOT, "package.json")); + const scripts = pkg.scripts as Record; + const joined = Object.entries(scripts) + .map(([name, body]) => `${name}=${body}`) + .join("\n"); + + expect(joined).not.toMatch(/\barchitect-generate\b/); + expect(joined).not.toMatch(/\barchitect-guard\b/); + expect(joined).not.toMatch(/\barchitect-lint-patterns\b/); + expect(joined).not.toMatch(/\barchitect-validate\b/); + expect(joined).not.toMatch(/\barchitect-lint-/); + + expect(scripts["sdp:build"]).toMatch(/\bsdp build\b/); + expect(scripts["sdp:validate"]).toMatch(/\bsdp validate\b/); + }); + + it("has a designated SDP corpus with carriers under specs/", () => { + const specsRoot = join(ROOT, "specs"); + expect(existsSync(specsRoot)).toBe(true); + + const carriers = walkFiles(specsRoot).filter( + (f) => f.endsWith(".sdp.md") || f.endsWith(".pack.sdp.md"), + ); + expect(carriers.length).toBeGreaterThan(0); + + const packs = carriers.filter((f) => f.endsWith(".pack.sdp.md")); + expect(packs.length).toBeGreaterThan(0); + + const specs = carriers.filter((f) => f.endsWith(".sdp.md") && !f.endsWith(".pack.sdp.md")); + // Behavior Specs plus unimplemented backlog Specs. Mechanical per-scenario test + // mirrors were pruned; .feature files remain the carriers for unit-level scenarios, + // and example Specs are kept only for user-facing and cross-component business flows. + expect(specs.length).toBeGreaterThanOrEqual(500); + + const exampleFiles = walkFiles(join(ROOT, "specs")).filter( + (f) => f.endsWith(".sdp.md") && (f.includes(".examples") || f.includes("architect-scenarios")), + ); + expect(exampleFiles.length).toBeGreaterThanOrEqual(80); + const withGwt = exampleFiles.filter((f) => readFileSync(f, "utf8").includes("```gwt")); + expect(withGwt.length).toBeGreaterThanOrEqual(80); + expect(existsSync(join(ROOT, "specs", "unimplemented"))).toBe(true); + + // Live architect/ is a pointer; Gherkin corpus was relocated to lineage. + expect(existsSync(join(ROOT, "architect", "specs"))).toBe(false); + expect(existsSync(join(ROOT, "docs", "lineage", "architect"))).toBe(true); + + const bindings = join(specsRoot, "platform", "sdp-bindings.ts"); + expect(existsSync(bindings)).toBe(true); + const bindingsText = readFileSync(bindings, "utf8"); + expect(bindingsText).toMatch(/codeAnchor/); + expect(bindingsText).toMatch(/@libar-dev\/software-delivery-protocol/); + }); + + it("does not require @architect delivery tags on migrated package src bindings", () => { + const srcRoots = [ + join(ROOT, "packages"), + join(ROOT, "examples"), + join(ROOT, "apps"), + ]; + const offenders: string[] = []; + + for (const root of srcRoots) { + for (const file of walkFiles(root)) { + if (!file.endsWith(".ts") && !file.endsWith(".tsx")) continue; + // Skip tests and stories; delivery bindings live in src / convex implementation. + const rel = relative(ROOT, file).split("\\").join("/"); + if (rel.includes("/tests/") || rel.includes("/test/") || rel.includes("/stories/")) { + continue; + } + const text = readFileSync(file, "utf8"); + // Real tag lines only (JSDoc or lone tag), not historical prose mentions. + const lines = text.split("\n"); + for (let i = 0; i < lines.length; i++) { + const line = lines[i] ?? ""; + if (/^\s*\/\*\*\s*@architect(?:-[\w-]+)?(?:\s|\*|\/|$)/.test(line)) { + offenders.push(`${rel}:${i + 1}`); + continue; + } + if (/^\s*\*\s*@architect(?:-[\w-]+)?(?:\s|$|:)/.test(line)) { + offenders.push(`${rel}:${i + 1}`); + } + } + } + } + + expect(offenders, `remaining @architect tags:\n${offenders.join("\n")}`).toEqual([]); + }); +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index 4eb37fee..8d5ceafe 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,3 +1,28 @@ { - "extends": "../tsconfig.base.json" + "files": [], + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "exactOptionalPropertyTypes": true, + "preserveConstEnums": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "resolveJsonModule": true, + "useUnknownInCatchVariables": true, + "ignoreDeprecations": "6.0" + }, + "exclude": ["node_modules", "dist"] } diff --git a/vitest.migration.config.ts b/vitest.migration.config.ts new file mode 100644 index 00000000..6d624496 --- /dev/null +++ b/vitest.migration.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["test/sdp-migration-guard.test.ts"], + environment: "node", + }, +});