github-actions[bot] commited on
Commit Β·
63eda1f
1
Parent(s): e72f896
Deploy from GitHub Actions: Mon Feb 23 10:09:33 UTC 2026
Browse filesCommit: eab2d1232405e9e1c2bfa46ba5b72e966865f8ce
Run: https://github.com/TalkShopClub/morpheus/actions/runs/22301563869
This view is limited to 50 files because it contains too many changes. Β See raw diff
- .dockerignore +32 -0
- .gitattributes +1 -0
- .gitignore +64 -0
- .vscode/tasks.json +13 -0
- Dockerfile +43 -1
- deploy-public-hf.sh +60 -0
- docs/chaos/README.md +104 -0
- docs/chaos/chaos-management.md +808 -0
- docs/od-architecture/01-current-state.md +516 -0
- docs/od-architecture/02-conceptual-model.md +553 -0
- docs/od-architecture/03-knowledge-graph.md +689 -0
- docs/od-architecture/04-taxonomy-organization.md +619 -0
- docs/od-architecture/05-sampling-world-config.md +754 -0
- docs/od-architecture/06-open-questions.md +539 -0
- docs/od-architecture/07-chaos-integration.md +535 -0
- docs/od-architecture/08-implementation-roadmap.md +819 -0
- docs/od-architecture/09-implementation-tasks.md +1548 -0
- docs/od-architecture/README.md +181 -0
- morpheus.local.pwd.yaml +26 -0
- morpheus.pwd.yaml +61 -0
- nginx/nginx.conf +25 -0
- package.json +18 -0
- packages/controlmart/.dockerignore +33 -0
- packages/controlmart/.gitignore +37 -0
- packages/controlmart/.prettierignore +6 -0
- packages/controlmart/.prettierrc +17 -0
- packages/controlmart/Dockerfile +23 -0
- packages/controlmart/README.md +148 -0
- packages/controlmart/bootstrap.ts +22 -0
- packages/controlmart/config/chaos-presets/aggressive.json +109 -0
- packages/controlmart/config/chaos-presets/infra.json +33 -0
- packages/controlmart/config/chaos-presets/light.json +45 -0
- packages/controlmart/config/chaos-presets/moderate.json +68 -0
- packages/controlmart/config/chaos-presets/process.json +72 -0
- packages/controlmart/config/chaos-presets/realistic.json +76 -0
- packages/controlmart/docs/api/capabilities-api.md +484 -0
- packages/controlmart/docs/api/chaos-api.md +628 -0
- packages/controlmart/docs/api/persona-api.md +265 -0
- packages/controlmart/driver-service-mesh.ts +27 -0
- packages/controlmart/eslint.config.js +54 -0
- packages/controlmart/index.ts +17 -0
- packages/controlmart/main.ts +242 -0
- packages/controlmart/package.json +73 -0
- packages/controlmart/scripts/build-macos-app.ts +176 -0
- packages/controlmart/scripts/measure-performance.ts +207 -0
- packages/controlmart/scripts/migrate-capabilities-to-db.ts +163 -0
- packages/controlmart/scripts/migrate-knowledge-graph-to-db.ts +245 -0
- packages/controlmart/scripts/migrate-personas-to-db.ts +163 -0
- packages/controlmart/scripts/seed-dev-data.ts +436 -0
- packages/controlmart/scripts/validate-seed-data.ts +76 -0
.dockerignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ignore all node_modules everywhere
|
| 2 |
+
**/node_modules
|
| 3 |
+
**/.turbo
|
| 4 |
+
**/.next
|
| 5 |
+
**/dist
|
| 6 |
+
**/build
|
| 7 |
+
**/.bun
|
| 8 |
+
**/__pycache__
|
| 9 |
+
|
| 10 |
+
# Ignore VCS + metadata
|
| 11 |
+
.git
|
| 12 |
+
.gitignore
|
| 13 |
+
.vscode
|
| 14 |
+
.DS_Store
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
# Docker-specific junk
|
| 19 |
+
docker-compose*.yml
|
| 20 |
+
Dockerfile
|
| 21 |
+
**/Dockerfile
|
| 22 |
+
|
| 23 |
+
# Ignore environment files
|
| 24 |
+
.env
|
| 25 |
+
.env.*
|
| 26 |
+
!.env.example
|
| 27 |
+
|
| 28 |
+
# Logs + temp
|
| 29 |
+
*.log
|
| 30 |
+
tmp
|
| 31 |
+
coverage
|
| 32 |
+
data
|
.gitattributes
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
*.{icns,png,jpg,zip,bin,model,pt} filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# dependencies (bun install)
|
| 2 |
+
node_modules
|
| 3 |
+
|
| 4 |
+
# output
|
| 5 |
+
out
|
| 6 |
+
dist
|
| 7 |
+
*.tgz
|
| 8 |
+
|
| 9 |
+
# code coverage
|
| 10 |
+
coverage
|
| 11 |
+
*.lcov
|
| 12 |
+
|
| 13 |
+
# logs
|
| 14 |
+
logs
|
| 15 |
+
_.log
|
| 16 |
+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
| 17 |
+
|
| 18 |
+
# dotenv environment variable files
|
| 19 |
+
.env
|
| 20 |
+
.env.development.local
|
| 21 |
+
.env.test.local
|
| 22 |
+
.env.production.local
|
| 23 |
+
.env.local
|
| 24 |
+
|
| 25 |
+
# caches
|
| 26 |
+
.eslintcache
|
| 27 |
+
.cache
|
| 28 |
+
*.tsbuildinfo
|
| 29 |
+
|
| 30 |
+
# IntelliJ based IDEs
|
| 31 |
+
.idea
|
| 32 |
+
|
| 33 |
+
# Finder (MacOS) folder config
|
| 34 |
+
.DS_Store
|
| 35 |
+
|
| 36 |
+
# Claude
|
| 37 |
+
CLAUDE.md
|
| 38 |
+
.claude/
|
| 39 |
+
|
| 40 |
+
*.pdf
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
.nx/cache
|
| 44 |
+
.nx/workspace-data
|
| 45 |
+
.cursor/rules/nx-rules.mdc
|
| 46 |
+
.github/instructions/nx.instructions.md
|
| 47 |
+
|
| 48 |
+
**/*.log*
|
| 49 |
+
**/files/*
|
| 50 |
+
|
| 51 |
+
/scripts/*
|
| 52 |
+
/docs/*
|
| 53 |
+
!/docs/od-architecture
|
| 54 |
+
/docs/od-architecture/implementation
|
| 55 |
+
!/docs/chaos
|
| 56 |
+
morpheus-data
|
| 57 |
+
/packages/controlmart/ui/docs
|
| 58 |
+
packages/controlmart/test_ods.sh
|
| 59 |
+
bun.lock
|
| 60 |
+
packages/controlmart/ui/bun.lock
|
| 61 |
+
.postman/
|
| 62 |
+
postman/
|
| 63 |
+
packages/controlmart/scripts/test-index-sync.sh
|
| 64 |
+
/packages/controlmart/src/docs/plans
|
.vscode/tasks.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "2.0.0",
|
| 3 |
+
"tasks": [
|
| 4 |
+
{
|
| 5 |
+
"label": "Start ControlMart Dev Server",
|
| 6 |
+
"type": "shell",
|
| 7 |
+
"command": "bun run dev",
|
| 8 |
+
"group": "build",
|
| 9 |
+
"isBackground": true,
|
| 10 |
+
"problemMatcher": []
|
| 11 |
+
}
|
| 12 |
+
]
|
| 13 |
+
}
|
Dockerfile
CHANGED
|
@@ -1 +1,43 @@
|
|
| 1 |
-
FROM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM oven/bun:latest AS builder
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY package.json bun.lock ./
|
| 6 |
+
COPY packages/controlmart/package.json ./packages/controlmart/
|
| 7 |
+
COPY packages/controlmart/ui/package.json ./packages/controlmart/ui/
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
RUN bun install
|
| 11 |
+
|
| 12 |
+
COPY . .
|
| 13 |
+
|
| 14 |
+
WORKDIR /app/packages/controlmart/ui
|
| 15 |
+
RUN bun install
|
| 16 |
+
RUN bun run build
|
| 17 |
+
|
| 18 |
+
WORKDIR /app/packages/controlmart
|
| 19 |
+
|
| 20 |
+
RUN bun run build:binary
|
| 21 |
+
|
| 22 |
+
FROM mongo:7
|
| 23 |
+
|
| 24 |
+
RUN apt-get update && apt-get install -y \
|
| 25 |
+
curl \
|
| 26 |
+
ca-certificates \
|
| 27 |
+
netcat-openbsd \
|
| 28 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 29 |
+
|
| 30 |
+
WORKDIR /app
|
| 31 |
+
|
| 32 |
+
COPY --from=builder /app/packages/controlmart/morpheus-server ./morpheus-server
|
| 33 |
+
COPY --from=builder /app/packages/controlmart/dist/ui ./ui
|
| 34 |
+
COPY --from=builder /app/start-hf.sh ./start-hf.sh
|
| 35 |
+
RUN chmod +x start-hf.sh
|
| 36 |
+
|
| 37 |
+
ENV NODE_ENV=production
|
| 38 |
+
ENV PORT=7860
|
| 39 |
+
ENV HOST=0.0.0.0
|
| 40 |
+
ENV MONGO_URI=mongodb://localhost:27017
|
| 41 |
+
ENV DB_NAME=morpheus
|
| 42 |
+
EXPOSE 7860
|
| 43 |
+
CMD ["./start-hf.sh"]
|
deploy-public-hf.sh
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
ECR_REGISTRY="public.ecr.aws/w3z5w3s0/skyfall"
|
| 5 |
+
IMAGE_NAME="morpheus"
|
| 6 |
+
IMAGE_TAG="latest"
|
| 7 |
+
FULL_IMAGE_URI="$ECR_REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
PUBLIC_REPO_DIR="../morpheus_public"
|
| 11 |
+
SOURCE_README="README.md"
|
| 12 |
+
DEST_README="$PUBLIC_REPO_DIR/README.md"
|
| 13 |
+
|
| 14 |
+
echo "==============================================="
|
| 15 |
+
echo " Morpheus Public Deployment Script"
|
| 16 |
+
echo "==============================================="
|
| 17 |
+
|
| 18 |
+
echo "[1/3] Building and Publishing to ECR..."
|
| 19 |
+
echo "Target: $FULL_IMAGE_URI"
|
| 20 |
+
|
| 21 |
+
echo "Note: Ensure you are logged into ECR Public."
|
| 22 |
+
|
| 23 |
+
echo "Building image..."
|
| 24 |
+
docker build --platform linux/amd64 -f Dockerfile.hf -t "$FULL_IMAGE_URI" .
|
| 25 |
+
|
| 26 |
+
echo "Pushing image..."
|
| 27 |
+
docker push "$FULL_IMAGE_URI"
|
| 28 |
+
echo "ECR Publish Complete."
|
| 29 |
+
|
| 30 |
+
echo "[2/3] Syncing Documentation..."
|
| 31 |
+
if [ -f "$SOURCE_README" ]; then
|
| 32 |
+
cp "$SOURCE_README" "$DEST_README"
|
| 33 |
+
echo "Copied $SOURCE_README to $DEST_README"
|
| 34 |
+
else
|
| 35 |
+
echo "Warning: $SOURCE_README not found in current directory."
|
| 36 |
+
fi
|
| 37 |
+
|
| 38 |
+
echo "[3/3] Updating Public Repository..."
|
| 39 |
+
|
| 40 |
+
if [ ! -d "$PUBLIC_REPO_DIR" ]; then
|
| 41 |
+
echo "Error: Directory $PUBLIC_REPO_DIR does not exist."
|
| 42 |
+
echo "Please clone the Hugging Face repository to $PUBLIC_REPO_DIR first."
|
| 43 |
+
exit 1
|
| 44 |
+
fi
|
| 45 |
+
|
| 46 |
+
cd "$PUBLIC_REPO_DIR" || exit
|
| 47 |
+
|
| 48 |
+
if [[ -n $(git status -s) ]]; then
|
| 49 |
+
echo "Changes detected. Committing and pushing..."
|
| 50 |
+
git add .
|
| 51 |
+
git commit -m "Deploy update: $(date)"
|
| 52 |
+
git push
|
| 53 |
+
echo "Public Repo Updated."
|
| 54 |
+
else
|
| 55 |
+
echo "No changes to public repo files."
|
| 56 |
+
fi
|
| 57 |
+
|
| 58 |
+
echo "==============================================="
|
| 59 |
+
echo " Deployment Complete!"
|
| 60 |
+
echo "==============================================="
|
docs/chaos/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Chaos Engineering & Management
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This directory contains documentation for Morpheus's chaos engineering system - a comprehensive framework for injecting realistic failures into workflows to test AI agent resilience.
|
| 6 |
+
|
| 7 |
+
## The Problem
|
| 8 |
+
|
| 9 |
+
Currently, chaos configuration is scattered across 14+ files with:
|
| 10 |
+
- Hardcoded probabilities in builders (0.0 to 0.8)
|
| 11 |
+
- Step-level inline configs with inconsistent values
|
| 12 |
+
- No central configuration or master kill-switch
|
| 13 |
+
- No environment-specific profiles
|
| 14 |
+
- Same workflow having different chaos in different places
|
| 15 |
+
|
| 16 |
+
## The Solution
|
| 17 |
+
|
| 18 |
+
A comprehensive chaos management system with:
|
| 19 |
+
- **Centralized Configuration**: Preset library with reusable chaos configurations
|
| 20 |
+
- **Environment Control**: Master kill-switch and environment-specific profiles
|
| 21 |
+
- **Multi-Level Configuration**: World β Capability β OD β Step cascade
|
| 22 |
+
- **Reproducibility**: Seeded randomness for deterministic chaos
|
| 23 |
+
- **Integration**: Seamlessly integrated with OD architecture
|
| 24 |
+
|
| 25 |
+
## Documentation
|
| 26 |
+
|
| 27 |
+
### [Chaos Management](./chaos-management.md)
|
| 28 |
+
Complete chaos management system design:
|
| 29 |
+
- Current problems and gaps
|
| 30 |
+
- Proposed architecture with priority cascade
|
| 31 |
+
- Centralized preset library (light, moderate, aggressive, realistic)
|
| 32 |
+
- Environment variables and master kill-switch
|
| 33 |
+
- World, capability, and OD-level configuration
|
| 34 |
+
- API endpoints for chaos control
|
| 35 |
+
- Migration strategy from scattered configs
|
| 36 |
+
- Best practices for researchers
|
| 37 |
+
|
| 38 |
+
## Current Chaos Capabilities
|
| 39 |
+
|
| 40 |
+
### 11 Chaos Scenario Types
|
| 41 |
+
|
| 42 |
+
1. **data_corruption** - Corrupt field values (null, wrong type, invalid format, random value)
|
| 43 |
+
2. **missing_data** - Remove fields or records
|
| 44 |
+
3. **stale_data** - Age timestamps (simulate eventual consistency)
|
| 45 |
+
4. **format_change** - Schema evolution (rename fields, change types)
|
| 46 |
+
5. **permission_denied** - Authorization errors
|
| 47 |
+
6. **rate_limit** - API throttling with delays
|
| 48 |
+
7. **partial_data** - Return subset of results (pagination issues)
|
| 49 |
+
8. **duplicate_data** - Inject duplicate records
|
| 50 |
+
9. **invalid_state** - Set records to invalid states (deleted, suspended)
|
| 51 |
+
10. **dependency_failure** - Downstream service unavailability
|
| 52 |
+
11. **timing_issue** - Future timestamps (clock skew)
|
| 53 |
+
|
| 54 |
+
## Quick Start
|
| 55 |
+
|
| 56 |
+
### Using Presets
|
| 57 |
+
|
| 58 |
+
```yaml
|
| 59 |
+
world:
|
| 60 |
+
chaos:
|
| 61 |
+
preset: "moderate" # Options: light, moderate, aggressive, realistic
|
| 62 |
+
seed: "reproducible-123"
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
### Custom Configuration
|
| 66 |
+
|
| 67 |
+
```yaml
|
| 68 |
+
world:
|
| 69 |
+
chaos:
|
| 70 |
+
globalPolicy:
|
| 71 |
+
enabled: true
|
| 72 |
+
probability: 0.15
|
| 73 |
+
scenarios:
|
| 74 |
+
- type: stale_data
|
| 75 |
+
weight: 10
|
| 76 |
+
- type: rate_limit
|
| 77 |
+
weight: 5
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
### Master Kill-Switch
|
| 81 |
+
|
| 82 |
+
```bash
|
| 83 |
+
# Disable all chaos globally
|
| 84 |
+
export CHAOS_ENABLED=false
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
## Related Documentation
|
| 88 |
+
|
| 89 |
+
- [Current Chaos Implementation](../03-chaos-engineering.md) - Existing chaos engine details
|
| 90 |
+
- [OD Architecture](../od-architecture/) - How chaos integrates with OD system
|
| 91 |
+
- [World Configuration](../od-architecture/05-sampling-world-config.md) - Configuring chaos per world
|
| 92 |
+
|
| 93 |
+
## Status
|
| 94 |
+
|
| 95 |
+
**Phase**: Design & Planning
|
| 96 |
+
**Last Updated**: 2025-11-14
|
| 97 |
+
|
| 98 |
+
## Next Steps
|
| 99 |
+
|
| 100 |
+
1. Review chaos management design
|
| 101 |
+
2. Implement centralized registry and presets
|
| 102 |
+
3. Add environment variable controls
|
| 103 |
+
4. Migrate scattered chaos configs
|
| 104 |
+
5. Build chaos configuration API
|
docs/chaos/chaos-management.md
ADDED
|
@@ -0,0 +1,808 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 07. Chaos Management
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
Chaos engineering in Morpheus allows researchers to inject realistic failures into workflows to test AI agent resilience. However, the current chaos configuration is scattered across 14+ files, making it unmanageable. This document proposes a comprehensive chaos management system integrated with the broader OD architecture.
|
| 6 |
+
|
| 7 |
+
## Current Problems
|
| 8 |
+
|
| 9 |
+
### 1. Scattered Configuration
|
| 10 |
+
|
| 11 |
+
**Hardcoded Probabilities**:
|
| 12 |
+
```typescript
|
| 13 |
+
// In different files:
|
| 14 |
+
GenericODBuilder: chaosProbability: 0.0
|
| 15 |
+
EDI builder: chaosProbability: 0.1
|
| 16 |
+
ERP builder: chaosProbability: 0.05
|
| 17 |
+
CRM builder: chaosProbability: 0.05
|
| 18 |
+
WMS builder: chaosProbability: 0.05
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
**Step-Level Inline Configs**:
|
| 22 |
+
```typescript
|
| 23 |
+
// od-builders.edi.util.ts
|
| 24 |
+
EDI 850 generation: probability: 0.0
|
| 25 |
+
Invoice generation: probability: 0.05
|
| 26 |
+
Advanced ship notice: probability: 0.1
|
| 27 |
+
|
| 28 |
+
// od-builders-refactored.edi.util.ts
|
| 29 |
+
Refactored EDI 850: probability: 0.2 // Different value!
|
| 30 |
+
Invoice step: probability: 0.1
|
| 31 |
+
ASN step: probability: 0.1
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
**Demo/Test Specific**:
|
| 35 |
+
```typescript
|
| 36 |
+
// chaos-edi-demo.ts
|
| 37 |
+
probability: 0.8 // Very aggressive for demo
|
| 38 |
+
scenarios: 7 different chaos types
|
| 39 |
+
|
| 40 |
+
// simple-edi-demo.ts
|
| 41 |
+
chaosProbability: 0.0 // Disabled
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
### 2. No Central Configuration
|
| 45 |
+
|
| 46 |
+
- No single source of truth
|
| 47 |
+
- Same workflow has different chaos in different files
|
| 48 |
+
- No reusable scenario library
|
| 49 |
+
- Must edit code to change chaos
|
| 50 |
+
|
| 51 |
+
### 3. No Environment Awareness
|
| 52 |
+
|
| 53 |
+
- Same chaos runs in all environments
|
| 54 |
+
- No way to disable in production
|
| 55 |
+
- No environment-specific profiles (dev/staging/prod)
|
| 56 |
+
|
| 57 |
+
### 4. No Master Kill-Switch
|
| 58 |
+
|
| 59 |
+
- Can't globally disable chaos
|
| 60 |
+
- Must manually set probability to 0 everywhere
|
| 61 |
+
- Risk of leaving chaos enabled accidentally
|
| 62 |
+
|
| 63 |
+
### 5. Inconsistent Behavior
|
| 64 |
+
|
| 65 |
+
- Duplication: Similar scenarios defined multiple times
|
| 66 |
+
- Variation: Same operation has different chaos values
|
| 67 |
+
- Maintenance: Changing chaos requires editing multiple files
|
| 68 |
+
|
| 69 |
+
## Chaos in the OD Architecture
|
| 70 |
+
|
| 71 |
+
### Chaos as a Cross-Cutting Concern
|
| 72 |
+
|
| 73 |
+
Chaos configuration exists at multiple levels:
|
| 74 |
+
|
| 75 |
+
```
|
| 76 |
+
βββββββββββββββββββββββββββββββββββ
|
| 77 |
+
β WORLD β Global chaos policy
|
| 78 |
+
β ββ Global Chaos Policy β (affects all capabilities in world)
|
| 79 |
+
β ββ Chaos Presets β
|
| 80 |
+
ββββββββββββββββ¬βββββββββββββββββββ
|
| 81 |
+
β
|
| 82 |
+
β
|
| 83 |
+
βββββββββββββββββββββββββββββββββββ
|
| 84 |
+
β CAPABILITY β Capability-level overrides
|
| 85 |
+
β ββ Chaos Override (optional) β (e.g., Order Fulfillment always has 0.3 chaos)
|
| 86 |
+
ββββββββββββββββ¬βββββββββββββββββββ
|
| 87 |
+
β
|
| 88 |
+
β
|
| 89 |
+
βββββββββββββββββββββββββββββββββββ
|
| 90 |
+
β OD (Workflow) β OD-level chaos config
|
| 91 |
+
β ββ Global OD Chaos Policy β (applies to all steps in OD)
|
| 92 |
+
β ββ Step-Level Overrides β
|
| 93 |
+
ββββββββββββββββ¬βββββββββββββββββββ
|
| 94 |
+
β
|
| 95 |
+
β
|
| 96 |
+
βββββββββββββββββββββββββββββββββββ
|
| 97 |
+
β STEP β Step-level chaos override
|
| 98 |
+
β ββ Step Chaos Override β (most specific, highest priority)
|
| 99 |
+
βββββββββββββββββββββββββββββββββββ
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
**Priority (highest to lowest)**:
|
| 103 |
+
1. Step-level override
|
| 104 |
+
2. OD-level policy
|
| 105 |
+
3. Capability-level override
|
| 106 |
+
4. World-level global policy
|
| 107 |
+
5. System defaults
|
| 108 |
+
|
| 109 |
+
**Master Kill-Switch**: Environment variable overrides everything
|
| 110 |
+
|
| 111 |
+
## Proposed Architecture
|
| 112 |
+
|
| 113 |
+
### 1. Environment Variables (Master Control)
|
| 114 |
+
|
| 115 |
+
```bash
|
| 116 |
+
# Master kill-switch
|
| 117 |
+
CHAOS_ENABLED=true|false # Override all chaos config
|
| 118 |
+
|
| 119 |
+
# Global settings
|
| 120 |
+
CHAOS_ENV=development|staging|production
|
| 121 |
+
CHAOS_GLOBAL_PROBABILITY=0.1 # Default probability if not specified
|
| 122 |
+
CHAOS_GLOBAL_SEED=seed-123 # For reproducibility
|
| 123 |
+
|
| 124 |
+
# Preset selection
|
| 125 |
+
CHAOS_PRESET=light|moderate|aggressive|custom
|
| 126 |
+
CHAOS_PRESET_FILE=/path/to/custom-preset.json
|
| 127 |
+
|
| 128 |
+
# Telemetry
|
| 129 |
+
CHAOS_TELEMETRY_LEVEL=basic|detailed|verbose
|
| 130 |
+
```
|
| 131 |
+
|
| 132 |
+
**Priority**: Environment variables override all file-based configuration.
|
| 133 |
+
|
| 134 |
+
### 2. Centralized Preset Library
|
| 135 |
+
|
| 136 |
+
#### File Structure
|
| 137 |
+
```
|
| 138 |
+
/config/
|
| 139 |
+
/chaos-presets/
|
| 140 |
+
default.json # System default
|
| 141 |
+
light.json # Low probability, common scenarios
|
| 142 |
+
moderate.json # Medium probability, diverse scenarios
|
| 143 |
+
aggressive.json # High probability, all scenarios
|
| 144 |
+
realistic.json # Real-world distribution
|
| 145 |
+
/domain/
|
| 146 |
+
fulfillment.json # Fulfillment-specific chaos
|
| 147 |
+
inventory.json # Inventory-specific chaos
|
| 148 |
+
transportation.json # Transportation-specific chaos
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
#### Preset Format
|
| 152 |
+
|
| 153 |
+
**Example: `light.json`**
|
| 154 |
+
```json
|
| 155 |
+
{
|
| 156 |
+
"id": "light",
|
| 157 |
+
"name": "Light Chaos",
|
| 158 |
+
"description": "Low probability chaos for basic resilience testing",
|
| 159 |
+
"globalProbability": 0.05,
|
| 160 |
+
"scenarios": [
|
| 161 |
+
{
|
| 162 |
+
"type": "stale_data",
|
| 163 |
+
"weight": 10,
|
| 164 |
+
"description": "Simulate eventual consistency delays",
|
| 165 |
+
"config": {
|
| 166 |
+
"staleDataAge": 30
|
| 167 |
+
}
|
| 168 |
+
},
|
| 169 |
+
{
|
| 170 |
+
"type": "rate_limit",
|
| 171 |
+
"weight": 5,
|
| 172 |
+
"description": "API throttling",
|
| 173 |
+
"config": {
|
| 174 |
+
"rateLimitDelay": 1000,
|
| 175 |
+
"rateLimitMessage": "Rate limit exceeded"
|
| 176 |
+
}
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"type": "missing_data",
|
| 180 |
+
"weight": 3,
|
| 181 |
+
"description": "Occasional missing records",
|
| 182 |
+
"config": {
|
| 183 |
+
"missingRecords": true
|
| 184 |
+
}
|
| 185 |
+
}
|
| 186 |
+
]
|
| 187 |
+
}
|
| 188 |
+
```
|
| 189 |
+
|
| 190 |
+
**Example: `aggressive.json`**
|
| 191 |
+
```json
|
| 192 |
+
{
|
| 193 |
+
"id": "aggressive",
|
| 194 |
+
"name": "Aggressive Chaos",
|
| 195 |
+
"description": "High probability chaos with all scenario types",
|
| 196 |
+
"globalProbability": 0.3,
|
| 197 |
+
"scenarios": [
|
| 198 |
+
{
|
| 199 |
+
"type": "data_corruption",
|
| 200 |
+
"weight": 8,
|
| 201 |
+
"config": {
|
| 202 |
+
"corruptFields": ["*"],
|
| 203 |
+
"corruptionType": "random"
|
| 204 |
+
}
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"type": "missing_data",
|
| 208 |
+
"weight": 7,
|
| 209 |
+
"config": {
|
| 210 |
+
"missingFields": ["*"],
|
| 211 |
+
"missingRecords": true
|
| 212 |
+
}
|
| 213 |
+
},
|
| 214 |
+
{
|
| 215 |
+
"type": "stale_data",
|
| 216 |
+
"weight": 6,
|
| 217 |
+
"config": {
|
| 218 |
+
"staleDataAge": 120
|
| 219 |
+
}
|
| 220 |
+
},
|
| 221 |
+
{
|
| 222 |
+
"type": "format_change",
|
| 223 |
+
"weight": 5,
|
| 224 |
+
"config": {
|
| 225 |
+
"changeType": "all"
|
| 226 |
+
}
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"type": "permission_denied",
|
| 230 |
+
"weight": 4,
|
| 231 |
+
"config": {}
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"type": "rate_limit",
|
| 235 |
+
"weight": 7,
|
| 236 |
+
"config": {
|
| 237 |
+
"rateLimitDelay": 3000
|
| 238 |
+
}
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"type": "partial_data",
|
| 242 |
+
"weight": 6,
|
| 243 |
+
"config": {
|
| 244 |
+
"returnCount": 5
|
| 245 |
+
}
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"type": "duplicate_data",
|
| 249 |
+
"weight": 5,
|
| 250 |
+
"config": {
|
| 251 |
+
"duplicateCount": 3
|
| 252 |
+
}
|
| 253 |
+
},
|
| 254 |
+
{
|
| 255 |
+
"type": "invalid_state",
|
| 256 |
+
"weight": 4,
|
| 257 |
+
"config": {
|
| 258 |
+
"invalidStates": ["deleted", "suspended"]
|
| 259 |
+
}
|
| 260 |
+
},
|
| 261 |
+
{
|
| 262 |
+
"type": "dependency_failure",
|
| 263 |
+
"weight": 3,
|
| 264 |
+
"config": {}
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"type": "timing_issue",
|
| 268 |
+
"weight": 2,
|
| 269 |
+
"config": {
|
| 270 |
+
"timeSkewMinutes": 30
|
| 271 |
+
}
|
| 272 |
+
}
|
| 273 |
+
]
|
| 274 |
+
}
|
| 275 |
+
```
|
| 276 |
+
|
| 277 |
+
**Example: `realistic.json`** (based on real-world failure rates)
|
| 278 |
+
```json
|
| 279 |
+
{
|
| 280 |
+
"id": "realistic",
|
| 281 |
+
"name": "Realistic Chaos",
|
| 282 |
+
"description": "Chaos distribution matching real-world failure rates",
|
| 283 |
+
"globalProbability": 0.08,
|
| 284 |
+
"scenarios": [
|
| 285 |
+
{
|
| 286 |
+
"type": "stale_data",
|
| 287 |
+
"weight": 40,
|
| 288 |
+
"description": "Most common: eventual consistency"
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"type": "rate_limit",
|
| 292 |
+
"weight": 20,
|
| 293 |
+
"description": "Common: API throttling"
|
| 294 |
+
},
|
| 295 |
+
{
|
| 296 |
+
"type": "timeout",
|
| 297 |
+
"weight": 15,
|
| 298 |
+
"description": "Common: network delays"
|
| 299 |
+
},
|
| 300 |
+
{
|
| 301 |
+
"type": "partial_data",
|
| 302 |
+
"weight": 10,
|
| 303 |
+
"description": "Occasional: pagination issues"
|
| 304 |
+
},
|
| 305 |
+
{
|
| 306 |
+
"type": "data_corruption",
|
| 307 |
+
"weight": 7,
|
| 308 |
+
"description": "Rare: data quality issues"
|
| 309 |
+
},
|
| 310 |
+
{
|
| 311 |
+
"type": "missing_data",
|
| 312 |
+
"weight": 5,
|
| 313 |
+
"description": "Rare: data loss"
|
| 314 |
+
},
|
| 315 |
+
{
|
| 316 |
+
"type": "permission_denied",
|
| 317 |
+
"weight": 2,
|
| 318 |
+
"description": "Very rare: auth failures"
|
| 319 |
+
},
|
| 320 |
+
{
|
| 321 |
+
"type": "dependency_failure",
|
| 322 |
+
"weight": 1,
|
| 323 |
+
"description": "Very rare: service outages"
|
| 324 |
+
}
|
| 325 |
+
]
|
| 326 |
+
}
|
| 327 |
+
```
|
| 328 |
+
|
| 329 |
+
### 3. Chaos Configuration Registry
|
| 330 |
+
|
| 331 |
+
**TypeScript Service**:
|
| 332 |
+
```typescript
|
| 333 |
+
// src/config/chaos-config.registry.ts
|
| 334 |
+
|
| 335 |
+
interface ChaosConfigRegistry {
|
| 336 |
+
// Presets
|
| 337 |
+
loadPreset(presetId: string): ChaosPolicy;
|
| 338 |
+
listPresets(): PresetMetadata[];
|
| 339 |
+
createPreset(preset: ChaosPreset): void;
|
| 340 |
+
|
| 341 |
+
// World-level
|
| 342 |
+
getWorldChaosPolicy(worldId: string): ChaosPolicy;
|
| 343 |
+
setWorldChaosPolicy(worldId: string, policy: ChaosPolicy): void;
|
| 344 |
+
|
| 345 |
+
// Capability-level
|
| 346 |
+
getCapabilityChaos(capabilityId: string): ChaosPolicy | null;
|
| 347 |
+
setCapabilityChaos(capabilityId: string, policy: ChaosPolicy): void;
|
| 348 |
+
|
| 349 |
+
// OD-level (runtime overrides)
|
| 350 |
+
getODChaos(odId: string): ChaosPolicy | null;
|
| 351 |
+
setODChaos(odId: string, policy: ChaosPolicy): void;
|
| 352 |
+
|
| 353 |
+
// Resolution (apply priority rules)
|
| 354 |
+
resolveChaosPolicy(context: ChaosContext): ChaosPolicy;
|
| 355 |
+
|
| 356 |
+
// Master switch
|
| 357 |
+
isChaosEnabled(): boolean;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
interface ChaosContext {
|
| 361 |
+
worldId: string;
|
| 362 |
+
capabilityId?: string;
|
| 363 |
+
odId: string;
|
| 364 |
+
stepId: string;
|
| 365 |
+
service?: string;
|
| 366 |
+
tool?: string;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
class ChaosConfigRegistryImpl implements ChaosConfigRegistry {
|
| 370 |
+
private presets: Map<string, ChaosPreset> = new Map();
|
| 371 |
+
private worldPolicies: Map<string, ChaosPolicy> = new Map();
|
| 372 |
+
private capabilityOverrides: Map<string, ChaosPolicy> = new Map();
|
| 373 |
+
private odOverrides: Map<string, ChaosPolicy> = new Map();
|
| 374 |
+
|
| 375 |
+
constructor() {
|
| 376 |
+
this.loadPresetsFromDisk();
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
resolveChaosPolicy(context: ChaosContext): ChaosPolicy {
|
| 380 |
+
// 0. Check master kill-switch
|
| 381 |
+
if (!this.isChaosEnabled()) {
|
| 382 |
+
return { enabled: false, probability: 0, scenarios: [] };
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
// Priority cascade (highest to lowest)
|
| 386 |
+
const policies = [
|
| 387 |
+
// 1. Step-level (from OD definition)
|
| 388 |
+
this.getStepChaos(context.odId, context.stepId),
|
| 389 |
+
|
| 390 |
+
// 2. OD-level
|
| 391 |
+
this.odOverrides.get(context.odId),
|
| 392 |
+
|
| 393 |
+
// 3. Capability-level
|
| 394 |
+
context.capabilityId ? this.capabilityOverrides.get(context.capabilityId) : null,
|
| 395 |
+
|
| 396 |
+
// 4. World-level
|
| 397 |
+
this.worldPolicies.get(context.worldId),
|
| 398 |
+
|
| 399 |
+
// 5. Global preset (from env or default)
|
| 400 |
+
this.getGlobalPreset(),
|
| 401 |
+
];
|
| 402 |
+
|
| 403 |
+
// Return first non-null policy
|
| 404 |
+
return policies.find(p => p !== null) || this.getDefaultPolicy();
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
isChaosEnabled(): boolean {
|
| 408 |
+
const envFlag = process.env.CHAOS_ENABLED;
|
| 409 |
+
if (envFlag !== undefined) {
|
| 410 |
+
return envFlag.toLowerCase() === 'true';
|
| 411 |
+
}
|
| 412 |
+
return true; // Default: enabled
|
| 413 |
+
}
|
| 414 |
+
}
|
| 415 |
+
```
|
| 416 |
+
|
| 417 |
+
### 4. World Configuration Integration
|
| 418 |
+
|
| 419 |
+
**World Chaos Config**:
|
| 420 |
+
```yaml
|
| 421 |
+
world:
|
| 422 |
+
id: "warehouse-research-001"
|
| 423 |
+
name: "Warehouse Automation Research"
|
| 424 |
+
|
| 425 |
+
chaos:
|
| 426 |
+
# Option 1: Use preset
|
| 427 |
+
preset: "moderate"
|
| 428 |
+
|
| 429 |
+
# Option 2: Custom global policy
|
| 430 |
+
globalPolicy:
|
| 431 |
+
enabled: true
|
| 432 |
+
probability: 0.15
|
| 433 |
+
seed: "reproducible-seed-123"
|
| 434 |
+
scenarios:
|
| 435 |
+
- type: stale_data
|
| 436 |
+
weight: 10
|
| 437 |
+
- type: rate_limit
|
| 438 |
+
weight: 5
|
| 439 |
+
|
| 440 |
+
# Option 3: Per-capability overrides
|
| 441 |
+
capabilityOverrides:
|
| 442 |
+
order-fulfillment:
|
| 443 |
+
probability: 0.3 # Higher chaos for this capability
|
| 444 |
+
scenarios:
|
| 445 |
+
- type: missing_data
|
| 446 |
+
weight: 10
|
| 447 |
+
|
| 448 |
+
inventory-check:
|
| 449 |
+
probability: 0.0 # No chaos for this capability
|
| 450 |
+
|
| 451 |
+
# Option 4: Per-OD overrides (runtime)
|
| 452 |
+
odOverrides:
|
| 453 |
+
order-fulfillment-v1:
|
| 454 |
+
probability: 0.25
|
| 455 |
+
```
|
| 456 |
+
|
| 457 |
+
### 5. API Endpoints
|
| 458 |
+
|
| 459 |
+
```typescript
|
| 460 |
+
// Presets
|
| 461 |
+
GET /api/chaos/presets # List all presets
|
| 462 |
+
GET /api/chaos/presets/:presetId # Get preset details
|
| 463 |
+
POST /api/chaos/presets # Create custom preset
|
| 464 |
+
PUT /api/chaos/presets/:presetId # Update preset
|
| 465 |
+
DELETE /api/chaos/presets/:presetId # Delete preset
|
| 466 |
+
|
| 467 |
+
// World-level chaos
|
| 468 |
+
GET /api/worlds/:worldId/chaos # Get world chaos config
|
| 469 |
+
PUT /api/worlds/:worldId/chaos # Update world chaos
|
| 470 |
+
POST /api/worlds/:worldId/chaos/preset/:presetId # Apply preset to world
|
| 471 |
+
|
| 472 |
+
// Capability-level chaos
|
| 473 |
+
GET /api/capabilities/:capId/chaos # Get capability chaos override
|
| 474 |
+
PUT /api/capabilities/:capId/chaos # Set capability chaos override
|
| 475 |
+
DELETE /api/capabilities/:capId/chaos # Remove override
|
| 476 |
+
|
| 477 |
+
// Runtime OD chaos
|
| 478 |
+
GET /api/ods/:odId/chaos # Get OD chaos config
|
| 479 |
+
PUT /api/ods/:odId/chaos # Set OD chaos override (runtime)
|
| 480 |
+
DELETE /api/ods/:odId/chaos # Remove override
|
| 481 |
+
|
| 482 |
+
// Chaos status and testing
|
| 483 |
+
GET /api/chaos/status # Is chaos enabled? Global settings
|
| 484 |
+
POST /api/chaos/test # Test chaos injection (dry run)
|
| 485 |
+
GET /api/chaos/scenarios # List all scenario types
|
| 486 |
+
```
|
| 487 |
+
|
| 488 |
+
### 6. Migration Strategy
|
| 489 |
+
|
| 490 |
+
#### Phase 1: Add Central Registry (No Breaking Changes)
|
| 491 |
+
1. Create `ChaosConfigRegistry` service
|
| 492 |
+
2. Load presets from JSON files
|
| 493 |
+
3. Add environment variable support
|
| 494 |
+
4. Keep existing inline configs working (backward compatible)
|
| 495 |
+
|
| 496 |
+
#### Phase 2: Update Chaos Engine
|
| 497 |
+
1. Modify `chaos-engine.od.ts` to use registry
|
| 498 |
+
2. Implement priority cascade logic
|
| 499 |
+
3. Add master kill-switch check
|
| 500 |
+
4. Log which chaos policy was applied
|
| 501 |
+
|
| 502 |
+
#### Phase 3: Migrate Existing Configs
|
| 503 |
+
1. Extract inline chaos configs to presets
|
| 504 |
+
2. Remove hardcoded probabilities from builders
|
| 505 |
+
3. Update tests to use registry
|
| 506 |
+
4. Add deprecation warnings for old patterns
|
| 507 |
+
|
| 508 |
+
#### Phase 4: Cleanup
|
| 509 |
+
1. Remove old builder chaos parameters
|
| 510 |
+
2. Delete duplicate scenario definitions
|
| 511 |
+
3. Document new patterns
|
| 512 |
+
4. Provide migration guide
|
| 513 |
+
|
| 514 |
+
## Example Usage Patterns
|
| 515 |
+
|
| 516 |
+
### Pattern 1: Default Chaos (Preset)
|
| 517 |
+
|
| 518 |
+
**Environment**:
|
| 519 |
+
```bash
|
| 520 |
+
CHAOS_ENABLED=true
|
| 521 |
+
CHAOS_PRESET=moderate
|
| 522 |
+
```
|
| 523 |
+
|
| 524 |
+
**Result**: All worlds use "moderate" preset unless overridden.
|
| 525 |
+
|
| 526 |
+
---
|
| 527 |
+
|
| 528 |
+
### Pattern 2: Per-World Customization
|
| 529 |
+
|
| 530 |
+
**World Config**:
|
| 531 |
+
```yaml
|
| 532 |
+
world:
|
| 533 |
+
name: "High Chaos Test"
|
| 534 |
+
chaos:
|
| 535 |
+
preset: "aggressive"
|
| 536 |
+
```
|
| 537 |
+
|
| 538 |
+
**Result**: This world has aggressive chaos, others use default.
|
| 539 |
+
|
| 540 |
+
---
|
| 541 |
+
|
| 542 |
+
### Pattern 3: Capability-Specific Chaos
|
| 543 |
+
|
| 544 |
+
**Capability Override**:
|
| 545 |
+
```typescript
|
| 546 |
+
chaosRegistry.setCapabilityChaos('order-fulfillment', {
|
| 547 |
+
enabled: true,
|
| 548 |
+
probability: 0.3,
|
| 549 |
+
scenarios: [
|
| 550 |
+
{ type: 'missing_data', weight: 10, config: { missingRecords: true } },
|
| 551 |
+
{ type: 'stale_data', weight: 8, config: { staleDataAge: 60 } },
|
| 552 |
+
]
|
| 553 |
+
});
|
| 554 |
+
```
|
| 555 |
+
|
| 556 |
+
**Result**: Order fulfillment always has 30% chaos, other capabilities use world default.
|
| 557 |
+
|
| 558 |
+
---
|
| 559 |
+
|
| 560 |
+
### Pattern 4: Environment-Based Profiles
|
| 561 |
+
|
| 562 |
+
**Environment Variables**:
|
| 563 |
+
```bash
|
| 564 |
+
# Development
|
| 565 |
+
CHAOS_ENABLED=true
|
| 566 |
+
CHAOS_PRESET=aggressive
|
| 567 |
+
CHAOS_GLOBAL_PROBABILITY=0.3
|
| 568 |
+
|
| 569 |
+
# Staging
|
| 570 |
+
CHAOS_ENABLED=true
|
| 571 |
+
CHAOS_PRESET=moderate
|
| 572 |
+
CHAOS_GLOBAL_PROBABILITY=0.1
|
| 573 |
+
|
| 574 |
+
# Production
|
| 575 |
+
CHAOS_ENABLED=false
|
| 576 |
+
```
|
| 577 |
+
|
| 578 |
+
**Result**: Chaos automatically adjusts based on environment.
|
| 579 |
+
|
| 580 |
+
---
|
| 581 |
+
|
| 582 |
+
### Pattern 5: Reproducible Experiments
|
| 583 |
+
|
| 584 |
+
**Configuration**:
|
| 585 |
+
```yaml
|
| 586 |
+
world:
|
| 587 |
+
chaos:
|
| 588 |
+
preset: "moderate"
|
| 589 |
+
seed: "experiment-001-seed"
|
| 590 |
+
```
|
| 591 |
+
|
| 592 |
+
**Result**: Same seed produces identical chaos injections across runs.
|
| 593 |
+
|
| 594 |
+
---
|
| 595 |
+
|
| 596 |
+
### Pattern 6: Emergency Disable
|
| 597 |
+
|
| 598 |
+
**Command**:
|
| 599 |
+
```bash
|
| 600 |
+
# Set environment variable and restart
|
| 601 |
+
export CHAOS_ENABLED=false
|
| 602 |
+
|
| 603 |
+
# Or via API (if running)
|
| 604 |
+
curl -X PUT /api/chaos/status -d '{"enabled": false}'
|
| 605 |
+
```
|
| 606 |
+
|
| 607 |
+
**Result**: All chaos immediately disabled without code changes.
|
| 608 |
+
|
| 609 |
+
## Chaos Telemetry & Observability
|
| 610 |
+
|
| 611 |
+
### Chaos Injection Logging
|
| 612 |
+
|
| 613 |
+
**Enhanced Logging**:
|
| 614 |
+
```typescript
|
| 615 |
+
{
|
| 616 |
+
timestamp: "2025-11-14T10:30:45Z",
|
| 617 |
+
level: "info",
|
| 618 |
+
service: "ODFlow",
|
| 619 |
+
msg: "Chaos injected",
|
| 620 |
+
chaos: {
|
| 621 |
+
worldId: "world-123",
|
| 622 |
+
capabilityId: "order-fulfillment",
|
| 623 |
+
odId: "order-fulfillment-v1",
|
| 624 |
+
stepId: "step-2",
|
| 625 |
+
scenarioType: "stale_data",
|
| 626 |
+
configSource: "capability-override", // where policy came from
|
| 627 |
+
probability: 0.3,
|
| 628 |
+
seed: "experiment-001-seed",
|
| 629 |
+
modifications: {
|
| 630 |
+
staleDataAge: 60,
|
| 631 |
+
fieldsAffected: ["timestamp", "lastUpdated"]
|
| 632 |
+
}
|
| 633 |
+
}
|
| 634 |
+
}
|
| 635 |
+
```
|
| 636 |
+
|
| 637 |
+
### Chaos Metrics
|
| 638 |
+
|
| 639 |
+
**Track**:
|
| 640 |
+
- Total chaos injections per world/capability/OD
|
| 641 |
+
- Injection rate over time
|
| 642 |
+
- Scenario type distribution
|
| 643 |
+
- Success/failure correlation with chaos
|
| 644 |
+
- Mean time between chaos events
|
| 645 |
+
|
| 646 |
+
**API**:
|
| 647 |
+
```typescript
|
| 648 |
+
GET /api/chaos/metrics?worldId=world-123
|
| 649 |
+
{
|
| 650 |
+
totalInjections: 150,
|
| 651 |
+
injectionRate: 0.12, // actual vs configured
|
| 652 |
+
scenarioDistribution: {
|
| 653 |
+
stale_data: 60,
|
| 654 |
+
missing_data: 45,
|
| 655 |
+
rate_limit: 30,
|
| 656 |
+
...
|
| 657 |
+
},
|
| 658 |
+
impactAnalysis: {
|
| 659 |
+
odSuccessRate: 0.75, // with chaos enabled
|
| 660 |
+
odSuccessRateWithoutChaos: 0.95, // estimated baseline
|
| 661 |
+
meanRecoveryTimeMs: 1500
|
| 662 |
+
}
|
| 663 |
+
}
|
| 664 |
+
```
|
| 665 |
+
|
| 666 |
+
## Best Practices for Researchers
|
| 667 |
+
|
| 668 |
+
### 1. Start with Presets
|
| 669 |
+
```yaml
|
| 670 |
+
# Begin with pre-defined presets
|
| 671 |
+
chaos:
|
| 672 |
+
preset: "light" # Start simple
|
| 673 |
+
|
| 674 |
+
# Progress to more chaos
|
| 675 |
+
chaos:
|
| 676 |
+
preset: "moderate"
|
| 677 |
+
|
| 678 |
+
# Advanced testing
|
| 679 |
+
chaos:
|
| 680 |
+
preset: "aggressive"
|
| 681 |
+
```
|
| 682 |
+
|
| 683 |
+
### 2. Use Reproducible Seeds
|
| 684 |
+
```yaml
|
| 685 |
+
# Always specify seed for reproducibility
|
| 686 |
+
chaos:
|
| 687 |
+
preset: "moderate"
|
| 688 |
+
seed: "experiment-20251114-001"
|
| 689 |
+
```
|
| 690 |
+
|
| 691 |
+
### 3. Override Selectively
|
| 692 |
+
```yaml
|
| 693 |
+
# Use presets as baseline, override specific capabilities
|
| 694 |
+
chaos:
|
| 695 |
+
preset: "moderate"
|
| 696 |
+
capabilityOverrides:
|
| 697 |
+
critical-capability:
|
| 698 |
+
probability: 0.0 # No chaos for critical path
|
| 699 |
+
```
|
| 700 |
+
|
| 701 |
+
### 4. Document Chaos Configuration
|
| 702 |
+
```yaml
|
| 703 |
+
world:
|
| 704 |
+
name: "Experiment: Agent Resilience Test"
|
| 705 |
+
description: "Testing AI agent with realistic failure rates"
|
| 706 |
+
chaos:
|
| 707 |
+
preset: "realistic"
|
| 708 |
+
seed: "resilience-test-001"
|
| 709 |
+
# Document why this chaos config
|
| 710 |
+
chaosRationale: "Using realistic preset to match production failure rates"
|
| 711 |
+
```
|
| 712 |
+
|
| 713 |
+
### 5. Compare With and Without Chaos
|
| 714 |
+
```typescript
|
| 715 |
+
// Run baseline (no chaos)
|
| 716 |
+
const baselineWorld = {
|
| 717 |
+
chaos: { enabled: false }
|
| 718 |
+
};
|
| 719 |
+
|
| 720 |
+
// Run with chaos
|
| 721 |
+
const chaosWorld = {
|
| 722 |
+
chaos: { preset: "moderate", seed: "compare-001" }
|
| 723 |
+
};
|
| 724 |
+
|
| 725 |
+
// Compare results
|
| 726 |
+
const impact = compareChaosImpact(baselineResults, chaosResults);
|
| 727 |
+
```
|
| 728 |
+
|
| 729 |
+
## Implementation Checklist
|
| 730 |
+
|
| 731 |
+
### Phase 1: Foundation (Week 1-2)
|
| 732 |
+
- [ ] Create `ChaosConfigRegistry` service
|
| 733 |
+
- [ ] Define preset JSON schema
|
| 734 |
+
- [ ] Create 5 standard presets (light, moderate, aggressive, realistic, custom)
|
| 735 |
+
- [ ] Add environment variable support
|
| 736 |
+
- [ ] Implement master kill-switch
|
| 737 |
+
|
| 738 |
+
### Phase 2: Integration (Week 3-4)
|
| 739 |
+
- [ ] Update `chaos-engine.od.ts` to use registry
|
| 740 |
+
- [ ] Implement priority cascade logic
|
| 741 |
+
- [ ] Add world-level chaos configuration
|
| 742 |
+
- [ ] Add capability-level overrides
|
| 743 |
+
- [ ] Enhance chaos telemetry logging
|
| 744 |
+
|
| 745 |
+
### Phase 3: API (Week 5)
|
| 746 |
+
- [ ] Build chaos configuration API endpoints
|
| 747 |
+
- [ ] Add preset management endpoints
|
| 748 |
+
- [ ] Add chaos status/testing endpoints
|
| 749 |
+
- [ ] Create metrics aggregation endpoint
|
| 750 |
+
|
| 751 |
+
### Phase 4: Migration (Week 6-7)
|
| 752 |
+
- [ ] Extract inline chaos to presets
|
| 753 |
+
- [ ] Update all builders to use registry
|
| 754 |
+
- [ ] Migrate test files
|
| 755 |
+
- [ ] Add backward compatibility layer
|
| 756 |
+
- [ ] Add deprecation warnings
|
| 757 |
+
|
| 758 |
+
### Phase 5: Documentation (Week 8)
|
| 759 |
+
- [ ] Write chaos configuration guide
|
| 760 |
+
- [ ] Create preset cookbook
|
| 761 |
+
- [ ] Document migration path
|
| 762 |
+
- [ ] Add API documentation
|
| 763 |
+
- [ ] Create tutorial videos/examples
|
| 764 |
+
|
| 765 |
+
## Open Questions
|
| 766 |
+
|
| 767 |
+
### Q1: Preset Versioning
|
| 768 |
+
**Question**: Should presets be versioned?
|
| 769 |
+
|
| 770 |
+
**Options**:
|
| 771 |
+
- A. No versioning (mutable presets)
|
| 772 |
+
- B. Semantic versioning (e.g., `moderate-v1.2.0`)
|
| 773 |
+
- C. Immutable presets (new ID for changes)
|
| 774 |
+
|
| 775 |
+
**Impact**: Reproducibility, backward compatibility
|
| 776 |
+
|
| 777 |
+
---
|
| 778 |
+
|
| 779 |
+
### Q2: Custom Scenario Creation
|
| 780 |
+
**Question**: Can researchers create custom chaos scenarios (new types)?
|
| 781 |
+
|
| 782 |
+
**Options**:
|
| 783 |
+
- A. No - limited to 11 existing types
|
| 784 |
+
- B. Yes - via preprocessInput/postprocessOutput hooks
|
| 785 |
+
- C. Yes - full extension API for new scenario types
|
| 786 |
+
|
| 787 |
+
**Impact**: Flexibility vs complexity
|
| 788 |
+
|
| 789 |
+
---
|
| 790 |
+
|
| 791 |
+
### Q3: Chaos Scheduling
|
| 792 |
+
**Question**: Should chaos be time-based or event-based?
|
| 793 |
+
|
| 794 |
+
**Options**:
|
| 795 |
+
- A. Probabilistic only (current approach)
|
| 796 |
+
- B. Add temporal patterns (increase chaos over time, specific time windows)
|
| 797 |
+
- C. Event-driven (inject chaos after N successful operations)
|
| 798 |
+
|
| 799 |
+
**Impact**: Research sophistication, implementation complexity
|
| 800 |
+
|
| 801 |
+
---
|
| 802 |
+
|
| 803 |
+
## Related Documents
|
| 804 |
+
|
| 805 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - OD architecture
|
| 806 |
+
- [05. Sampling & World Config](./05-sampling-world-config.md) - World configuration
|
| 807 |
+
- [06. Open Questions](./06-open-questions.md) - Unresolved decisions
|
| 808 |
+
- Main docs: [03-chaos-engineering.md](../03-chaos-engineering.md) - Current chaos implementation
|
docs/od-architecture/01-current-state.md
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 01. Current State Analysis
|
| 2 |
+
|
| 3 |
+
## System Inventory
|
| 4 |
+
|
| 5 |
+
### Services & Tools
|
| 6 |
+
|
| 7 |
+
Morpheus currently simulates 4 main enterprise services with approximately **162 tools/APIs**:
|
| 8 |
+
|
| 9 |
+
| Service | Tool Count | Purpose |
|
| 10 |
+
|---------|-----------|---------|
|
| 11 |
+
| **WMS** (Warehouse Management) | 64 | Inventory, receiving, picking, packing, putaway, cycle counting |
|
| 12 |
+
| **ERP** (Enterprise Resource Planning) | 34 | Orders, products, customers, pricing, purchase orders |
|
| 13 |
+
| **TMS** (Transportation Management) | 33 | Shipments, carriers, routes, tracking |
|
| 14 |
+
| **EDI** (Electronic Data Interchange) | 15 | Document generation (850, 810, 856), parsing, acknowledgments |
|
| 15 |
+
| **Logs** | 5 | Log querying and analysis |
|
| 16 |
+
| **OD Management** | 4 | OD execution and status |
|
| 17 |
+
| **World/Registry** | 7 | World management, service registration |
|
| 18 |
+
|
| 19 |
+
**Service Registration**: `/packages/controlmart/src/routes/registry.route.ts`
|
| 20 |
+
- Routes mounted by domain: `/:worldId/wms`, `/:worldId/tms`, `/:worldId/edi`
|
| 21 |
+
- Services exposed as REST endpoints (not pure MCP servers yet)
|
| 22 |
+
|
| 23 |
+
### Example Service Tools
|
| 24 |
+
|
| 25 |
+
**WMS Sample Tools:**
|
| 26 |
+
```
|
| 27 |
+
- inventory/get-all
|
| 28 |
+
- inventory/get-by-id
|
| 29 |
+
- inventory/update-quantity
|
| 30 |
+
- receiving/create-appointment
|
| 31 |
+
- receiving/process-receipt
|
| 32 |
+
- picking/create-wave
|
| 33 |
+
- picking/assign-picker
|
| 34 |
+
- putaway/create-task
|
| 35 |
+
- cycle-count/initiate
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
**ERP Sample Tools:**
|
| 39 |
+
```
|
| 40 |
+
- companies/create-company
|
| 41 |
+
- companies/get-by-id
|
| 42 |
+
- companies/get-mpc-company
|
| 43 |
+
- companies/bulk-upsert
|
| 44 |
+
- products/create-product
|
| 45 |
+
- products/get-by-sku
|
| 46 |
+
- products/get-random
|
| 47 |
+
- products/bulk-upsert
|
| 48 |
+
- orders/create-order
|
| 49 |
+
- orders/get-by-po-number
|
| 50 |
+
- orders/update-status
|
| 51 |
+
- orders/delete-order
|
| 52 |
+
- invoices/create-invoice
|
| 53 |
+
- invoices/get-by-number
|
| 54 |
+
- invoices/update-status
|
| 55 |
+
- shipments/create-shipment
|
| 56 |
+
- shipments/update-tracking
|
| 57 |
+
- shipments/add-event
|
| 58 |
+
- shipments/add-document
|
| 59 |
+
- payments/create-payment
|
| 60 |
+
- payments/apply-allocations
|
| 61 |
+
- payments/update-status
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
**TMS Sample Tools:**
|
| 65 |
+
```
|
| 66 |
+
- shipments/create
|
| 67 |
+
- shipments/track
|
| 68 |
+
- carriers/assign
|
| 69 |
+
- routes/optimize
|
| 70 |
+
- deliveries/schedule
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
## Current OD Patterns
|
| 74 |
+
|
| 75 |
+
### Existing Operational Descriptors
|
| 76 |
+
|
| 77 |
+
ODs are currently defined programmatically using builder patterns. Here are representative examples:
|
| 78 |
+
|
| 79 |
+
#### 1. Inbound Receiving Workflow
|
| 80 |
+
**Location**: `/packages/controlmart/src/examples/simple-wms-od.ts`
|
| 81 |
+
|
| 82 |
+
**Purpose**: Complete inbound receiving process from shipment to putaway
|
| 83 |
+
|
| 84 |
+
**Flow**:
|
| 85 |
+
```
|
| 86 |
+
TMS: Shipment Tender
|
| 87 |
+
β
|
| 88 |
+
TMS: In-Transit Tracking
|
| 89 |
+
β
|
| 90 |
+
WMS: Dock Appointment
|
| 91 |
+
β
|
| 92 |
+
WMS: Receiving
|
| 93 |
+
β
|
| 94 |
+
WMS: Putaway
|
| 95 |
+
```
|
| 96 |
+
|
| 97 |
+
**Characteristics**:
|
| 98 |
+
- Multi-service orchestration (TMS β WMS)
|
| 99 |
+
- Sequential steps with dependencies
|
| 100 |
+
- Data flows between services
|
| 101 |
+
- ~5-7 steps total
|
| 102 |
+
|
| 103 |
+
#### 2. Purchase Order EDI Processing
|
| 104 |
+
**Location**: `/packages/controlmart/src/utils/edi/od-builders-refactored.edi.util.ts`
|
| 105 |
+
|
| 106 |
+
**Purpose**: Process EDI 850 purchase order documents
|
| 107 |
+
|
| 108 |
+
**Flow**:
|
| 109 |
+
```
|
| 110 |
+
Generate PO Data
|
| 111 |
+
β
|
| 112 |
+
Generate EDI 850 Document
|
| 113 |
+
β
|
| 114 |
+
Send EDI Acknowledgment (997)
|
| 115 |
+
β
|
| 116 |
+
Generate Invoice (EDI 810)
|
| 117 |
+
```
|
| 118 |
+
|
| 119 |
+
**Characteristics**:
|
| 120 |
+
- Data transformation heavy
|
| 121 |
+
- Multi-format handling (JSON β EDI)
|
| 122 |
+
- Document validation
|
| 123 |
+
- ~4-6 steps
|
| 124 |
+
|
| 125 |
+
#### 3. Generic WMS Workflows
|
| 126 |
+
**Location**: `/packages/controlmart/src/utils/wms/od-builder.wms.util.ts`
|
| 127 |
+
|
| 128 |
+
**Purpose**: Template-based WMS operations
|
| 129 |
+
|
| 130 |
+
**Workflow Types**:
|
| 131 |
+
- `inbound`: Receiving and putaway
|
| 132 |
+
- `outbound`: Picking and shipping
|
| 133 |
+
- `cycle_count`: Inventory auditing
|
| 134 |
+
- `replenishment`: Stock transfer
|
| 135 |
+
|
| 136 |
+
**Characteristics**:
|
| 137 |
+
- Builder pattern with fluent API
|
| 138 |
+
- Configurable chaos injection
|
| 139 |
+
- Service-specific (WMS only)
|
| 140 |
+
|
| 141 |
+
#### 4. Business Rules Triggered OD
|
| 142 |
+
**Location**: `/packages/controlmart/src/business-rules/actions/trigger-od.action.ts`
|
| 143 |
+
|
| 144 |
+
**Purpose**: Execute OD when business rule fires
|
| 145 |
+
|
| 146 |
+
**Example**: Auto-allocate inventory when new order created
|
| 147 |
+
|
| 148 |
+
**Characteristics**:
|
| 149 |
+
- Event-driven
|
| 150 |
+
- Connects business rules β OD execution
|
| 151 |
+
- Async execution
|
| 152 |
+
|
| 153 |
+
### OD Structure & Components
|
| 154 |
+
|
| 155 |
+
**Core Files**:
|
| 156 |
+
- `/packages/controlmart/src/operational-descriptor/executor.od.ts` - Main executor
|
| 157 |
+
- `/packages/controlmart/src/operational-descriptor/run-step.od.ts` - Step execution logic
|
| 158 |
+
- `/packages/controlmart/src/operational-descriptor/generic-builder.od.ts` - Builder pattern
|
| 159 |
+
- `/packages/controlmart/src/operational-descriptor/schema.od.ts` - JSON schema validation
|
| 160 |
+
- `/packages/controlmart/src/operational-descriptor/chaos-engine.od.ts` - Chaos injection
|
| 161 |
+
|
| 162 |
+
**Step Types**:
|
| 163 |
+
1. **MCP Step**: Call service tool (most common)
|
| 164 |
+
2. **Map Step**: Parallel iteration over arrays
|
| 165 |
+
3. **Script Step**: Execute JavaScript code
|
| 166 |
+
4. **Noop Step**: No-op placeholder
|
| 167 |
+
|
| 168 |
+
**OD Properties**:
|
| 169 |
+
```typescript
|
| 170 |
+
{
|
| 171 |
+
id: string,
|
| 172 |
+
name: string,
|
| 173 |
+
version: string,
|
| 174 |
+
description?: string,
|
| 175 |
+
|
| 176 |
+
// Global chaos config
|
| 177 |
+
chaos?: ChaosPolicy,
|
| 178 |
+
|
| 179 |
+
// Workflow steps
|
| 180 |
+
steps: Step[],
|
| 181 |
+
|
| 182 |
+
// Success criteria
|
| 183 |
+
assertions?: Assertion[],
|
| 184 |
+
|
| 185 |
+
// Metadata
|
| 186 |
+
tags?: string[],
|
| 187 |
+
metadata?: Record<string, any>
|
| 188 |
+
}
|
| 189 |
+
```
|
| 190 |
+
|
| 191 |
+
**Step Properties**:
|
| 192 |
+
```typescript
|
| 193 |
+
{
|
| 194 |
+
id: string,
|
| 195 |
+
type: "mcp" | "map" | "script" | "noop",
|
| 196 |
+
|
| 197 |
+
// For MCP steps
|
| 198 |
+
service?: string,
|
| 199 |
+
tool?: string,
|
| 200 |
+
input?: InputBinding,
|
| 201 |
+
output?: OutputBinding,
|
| 202 |
+
|
| 203 |
+
// Resilience
|
| 204 |
+
retry?: RetryPolicy,
|
| 205 |
+
chaos?: ChaosPolicy, // Step-level override
|
| 206 |
+
|
| 207 |
+
// Conditional execution
|
| 208 |
+
condition?: string,
|
| 209 |
+
|
| 210 |
+
// Validation
|
| 211 |
+
assertions?: Assertion[]
|
| 212 |
+
}
|
| 213 |
+
```
|
| 214 |
+
|
| 215 |
+
## Current Organization Patterns
|
| 216 |
+
|
| 217 |
+
### 1. By Service (Primary)
|
| 218 |
+
|
| 219 |
+
ODs and tools are primarily organized by which service they interact with:
|
| 220 |
+
|
| 221 |
+
```
|
| 222 |
+
/packages/controlmart/src/
|
| 223 |
+
/routes/
|
| 224 |
+
wms.route.ts # All WMS endpoints
|
| 225 |
+
erp.routes.ts # All ERP endpoints
|
| 226 |
+
tms.route.ts # All TMS endpoints
|
| 227 |
+
edi.route.ts # All EDI endpoints
|
| 228 |
+
/utils/
|
| 229 |
+
/wms/
|
| 230 |
+
service-tools.wms.util.ts
|
| 231 |
+
od-builder.wms.util.ts
|
| 232 |
+
/edi/
|
| 233 |
+
service-tools.edi.util.ts
|
| 234 |
+
od-builders.edi.util.ts
|
| 235 |
+
od-builders-refactored.edi.util.ts
|
| 236 |
+
/tms/
|
| 237 |
+
service-tools.tms.util.ts
|
| 238 |
+
```
|
| 239 |
+
|
| 240 |
+
**Pros**:
|
| 241 |
+
- Clear ownership
|
| 242 |
+
- Easy to find service-specific logic
|
| 243 |
+
- Modular structure
|
| 244 |
+
|
| 245 |
+
**Cons**:
|
| 246 |
+
- Cross-service workflows scattered
|
| 247 |
+
- No semantic grouping
|
| 248 |
+
- Hard to discover "what can I do?"
|
| 249 |
+
|
| 250 |
+
### 2. By Workflow Type (Secondary)
|
| 251 |
+
|
| 252 |
+
Some OD builders organize by workflow category:
|
| 253 |
+
|
| 254 |
+
**WmsODBuilderFactory** workflows:
|
| 255 |
+
- `inbound`: Receiving operations
|
| 256 |
+
- `outbound`: Fulfillment operations
|
| 257 |
+
- `cycle_count`: Audit operations
|
| 258 |
+
- `replenishment`: Transfer operations
|
| 259 |
+
|
| 260 |
+
**GenericODBuilderFactory** services:
|
| 261 |
+
- `edi`: EDI document processing
|
| 262 |
+
- `erp`: Order management
|
| 263 |
+
- `wms`: Warehouse operations
|
| 264 |
+
- `tms`: Transportation operations
|
| 265 |
+
- `multi-service`: Cross-service workflows
|
| 266 |
+
|
| 267 |
+
**Pros**:
|
| 268 |
+
- Some semantic meaning
|
| 269 |
+
- Groups related operations
|
| 270 |
+
|
| 271 |
+
**Cons**:
|
| 272 |
+
- Limited vocabulary
|
| 273 |
+
- Inconsistent across services
|
| 274 |
+
- Not extensible
|
| 275 |
+
|
| 276 |
+
### 3. By Business Domain (Emerging)
|
| 277 |
+
|
| 278 |
+
Business rules show domain-based organization:
|
| 279 |
+
|
| 280 |
+
**Domains**: `WMS`, `ERP`, `TMS`, `EDI`
|
| 281 |
+
|
| 282 |
+
**Target Collections**:
|
| 283 |
+
- WMS: `Inventory`, `Order`, `Receiving`, `Picking`
|
| 284 |
+
- ERP: `Order`, `Product`, `Customer`, `PurchaseOrder`
|
| 285 |
+
- TMS: `Shipment`, `Carrier`, `Route`
|
| 286 |
+
|
| 287 |
+
**Pros**:
|
| 288 |
+
- Aligns with business concepts
|
| 289 |
+
- Clear data ownership
|
| 290 |
+
|
| 291 |
+
**Cons**:
|
| 292 |
+
- Only used in business rules
|
| 293 |
+
- Not extended to ODs
|
| 294 |
+
- No cross-domain taxonomy
|
| 295 |
+
|
| 296 |
+
## Critical Gaps
|
| 297 |
+
|
| 298 |
+
### 1. No Persona Model
|
| 299 |
+
|
| 300 |
+
**Current State**:
|
| 301 |
+
- No formal persona or role system
|
| 302 |
+
- Some role attributes scattered in models:
|
| 303 |
+
- `personality` field in customer/employee types
|
| 304 |
+
- `role` field in WMS labor user model
|
| 305 |
+
- Hardcoded "Skyfall Automation Bot" reference
|
| 306 |
+
|
| 307 |
+
**Missing**:
|
| 308 |
+
- Persona definitions (Store Manager, Warehouse Worker, etc.)
|
| 309 |
+
- Capability matrix (who can do what)
|
| 310 |
+
- Access control model
|
| 311 |
+
- Persona-based OD filtering
|
| 312 |
+
|
| 313 |
+
**Impact**:
|
| 314 |
+
- Can't answer: "What can a store manager do?"
|
| 315 |
+
- No way to configure worlds by persona
|
| 316 |
+
- Unclear authorization model
|
| 317 |
+
|
| 318 |
+
### 2. No OD Registry/Catalog
|
| 319 |
+
|
| 320 |
+
**Current State**:
|
| 321 |
+
- ODs scattered across builder files
|
| 322 |
+
- No central inventory
|
| 323 |
+
- Must read code to discover ODs
|
| 324 |
+
- No metadata or discoverability
|
| 325 |
+
|
| 326 |
+
**Missing**:
|
| 327 |
+
- Centralized OD registry
|
| 328 |
+
- Searchable catalog
|
| 329 |
+
- Metadata (tags, description, inputs, outputs)
|
| 330 |
+
- Version management
|
| 331 |
+
|
| 332 |
+
**Impact**:
|
| 333 |
+
- Can't answer: "What ODs exist?"
|
| 334 |
+
- Researchers must know code structure
|
| 335 |
+
- No programmatic discovery
|
| 336 |
+
- Hard to share/reuse ODs
|
| 337 |
+
|
| 338 |
+
### 3. No Capability Mapping
|
| 339 |
+
|
| 340 |
+
**Current State**:
|
| 341 |
+
- Tools exist but not semantically organized
|
| 342 |
+
- ODs exist but not categorized by function
|
| 343 |
+
- No mapping of tool β capability β persona
|
| 344 |
+
|
| 345 |
+
**Missing**:
|
| 346 |
+
- Capability taxonomy
|
| 347 |
+
- Tool-to-capability mapping
|
| 348 |
+
- Capability-to-persona mapping
|
| 349 |
+
- Dependency analysis
|
| 350 |
+
|
| 351 |
+
**Impact**:
|
| 352 |
+
- Can't answer: "What capabilities exist?"
|
| 353 |
+
- Can't suggest ODs based on available tools
|
| 354 |
+
- No validation of OD feasibility
|
| 355 |
+
- Manual OD creation only
|
| 356 |
+
|
| 357 |
+
### 4. No Semantic Organization
|
| 358 |
+
|
| 359 |
+
**Current State**:
|
| 360 |
+
- Organization by service/workflow type only
|
| 361 |
+
- No domain taxonomy (procurement, fulfillment, etc.)
|
| 362 |
+
- No complexity classification
|
| 363 |
+
- No tags or metadata
|
| 364 |
+
|
| 365 |
+
**Missing**:
|
| 366 |
+
- Multi-dimensional taxonomy
|
| 367 |
+
- Tag system
|
| 368 |
+
- Filtering/search capabilities
|
| 369 |
+
- Hierarchical organization
|
| 370 |
+
|
| 371 |
+
**Impact**:
|
| 372 |
+
- Hard to browse/discover
|
| 373 |
+
- No researcher-friendly navigation
|
| 374 |
+
- Can't filter by domain, complexity, etc.
|
| 375 |
+
- Overwhelming for newcomers
|
| 376 |
+
|
| 377 |
+
### 5. Chaos Configuration Scattered
|
| 378 |
+
|
| 379 |
+
**Current State**:
|
| 380 |
+
- Hardcoded probabilities in 14+ files
|
| 381 |
+
- Different values for similar workflows
|
| 382 |
+
- No central configuration
|
| 383 |
+
- No master kill-switch
|
| 384 |
+
|
| 385 |
+
**Specific Issues**:
|
| 386 |
+
- EDI builder: `chaosProbability: 0.1`
|
| 387 |
+
- ERP builder: `chaosProbability: 0.05`
|
| 388 |
+
- EDI 850 step: `probability: 0.0`
|
| 389 |
+
- Refactored EDI 850: `probability: 0.2`
|
| 390 |
+
- Chaos demo: `probability: 0.8` with 7 scenarios
|
| 391 |
+
|
| 392 |
+
**Missing**:
|
| 393 |
+
- Centralized chaos presets
|
| 394 |
+
- Environment-based configuration
|
| 395 |
+
- Global master switch
|
| 396 |
+
- Reusable scenario library
|
| 397 |
+
|
| 398 |
+
**Impact**:
|
| 399 |
+
- Chaos management unmanageable (original problem!)
|
| 400 |
+
- Inconsistent behavior
|
| 401 |
+
- Hard to reproduce experiments
|
| 402 |
+
- Must edit code to change chaos
|
| 403 |
+
|
| 404 |
+
### 6. No World Configuration System
|
| 405 |
+
|
| 406 |
+
**Current State**:
|
| 407 |
+
- Worlds have all services/tools available
|
| 408 |
+
- No way to limit scope
|
| 409 |
+
- No sampling mechanism
|
| 410 |
+
- All-or-nothing approach
|
| 411 |
+
|
| 412 |
+
**Missing**:
|
| 413 |
+
- Capability filtering
|
| 414 |
+
- OD sampling strategies
|
| 415 |
+
- Domain-specific worlds
|
| 416 |
+
- Complexity-based filtering
|
| 417 |
+
|
| 418 |
+
**Impact**:
|
| 419 |
+
- Can't create specialized worlds (warehouse-only, retail-only)
|
| 420 |
+
- Can't simplify for experiments
|
| 421 |
+
- No way to control scope
|
| 422 |
+
- Overwhelming for simple tests
|
| 423 |
+
|
| 424 |
+
### 7. No Experiment Tracking
|
| 425 |
+
|
| 426 |
+
**Current State**:
|
| 427 |
+
- OD execution results returned via API
|
| 428 |
+
- No persistent run history
|
| 429 |
+
- Manual metrics tracking in demo scripts
|
| 430 |
+
- No configuration snapshots
|
| 431 |
+
|
| 432 |
+
**Missing**:
|
| 433 |
+
- Run history database
|
| 434 |
+
- Configuration versioning
|
| 435 |
+
- Result comparison tools
|
| 436 |
+
- Reproducibility support
|
| 437 |
+
|
| 438 |
+
**Impact**:
|
| 439 |
+
- Can't compare experiments
|
| 440 |
+
- Hard to reproduce issues
|
| 441 |
+
- No learning from past runs
|
| 442 |
+
- Manual data collection required
|
| 443 |
+
|
| 444 |
+
## Technology Stack
|
| 445 |
+
|
| 446 |
+
**Language**: TypeScript/Node.js
|
| 447 |
+
|
| 448 |
+
**Framework**: Express.js
|
| 449 |
+
|
| 450 |
+
**Database**: MongoDB (Mongoose ODM)
|
| 451 |
+
|
| 452 |
+
**Validation**: JSON Schema, Zod (partial), JMESPath, JSONata, CEL
|
| 453 |
+
|
| 454 |
+
**Logging**: Pino (structured logging)
|
| 455 |
+
|
| 456 |
+
**Architecture**: Monorepo (packages/controlmart)
|
| 457 |
+
|
| 458 |
+
## Key Codebase Locations
|
| 459 |
+
|
| 460 |
+
### Type Definitions
|
| 461 |
+
- `/packages/controlmart/src/types/od.type.ts` - OD types, chaos types, step types
|
| 462 |
+
- `/packages/controlmart/src/types/service-tools.type.ts` - Service tool definitions
|
| 463 |
+
|
| 464 |
+
### Core OD System
|
| 465 |
+
- `/packages/controlmart/src/operational-descriptor/executor.od.ts` - Main executor
|
| 466 |
+
- `/packages/controlmart/src/operational-descriptor/run-step.od.ts` - Step runner
|
| 467 |
+
- `/packages/controlmart/src/operational-descriptor/chaos-engine.od.ts` - Chaos injection
|
| 468 |
+
- `/packages/controlmart/src/operational-descriptor/generic-builder.od.ts` - Builder API
|
| 469 |
+
- `/packages/controlmart/src/operational-descriptor/schema.od.ts` - Schema validation
|
| 470 |
+
|
| 471 |
+
### Service Implementations
|
| 472 |
+
- `/packages/controlmart/src/routes/wms.route.ts` - WMS REST API
|
| 473 |
+
- `/packages/controlmart/src/routes/erp.routes.ts` - ERP REST API
|
| 474 |
+
- `/packages/controlmart/src/routes/tms.route.ts` - TMS REST API
|
| 475 |
+
- `/packages/controlmart/src/routes/edi.route.ts` - EDI REST API
|
| 476 |
+
|
| 477 |
+
### Service Tools
|
| 478 |
+
- `/packages/controlmart/src/utils/wms/service-tools.wms.util.ts` - WMS operations
|
| 479 |
+
- `/packages/controlmart/src/utils/edi/service-tools.edi.util.ts` - EDI operations
|
| 480 |
+
- `/packages/controlmart/src/utils/tms/service-tools.tms.util.ts` - TMS operations
|
| 481 |
+
|
| 482 |
+
### OD Builders
|
| 483 |
+
- `/packages/controlmart/src/utils/wms/od-builder.wms.util.ts` - WMS OD builder
|
| 484 |
+
- `/packages/controlmart/src/utils/edi/od-builders.edi.util.ts` - EDI OD builders
|
| 485 |
+
- `/packages/controlmart/src/utils/edi/od-builders-refactored.edi.util.ts` - Refactored EDI builders
|
| 486 |
+
|
| 487 |
+
### Business Rules
|
| 488 |
+
- `/packages/controlmart/src/business-rules/rule-engine.ts` - Rule execution engine
|
| 489 |
+
- `/packages/controlmart/src/business-rules/rules/wms-rules.ts` - WMS-specific rules
|
| 490 |
+
- `/packages/controlmart/src/business-rules/actions/trigger-od.action.ts` - OD triggering
|
| 491 |
+
|
| 492 |
+
### Examples & Tests
|
| 493 |
+
- `/packages/controlmart/src/examples/simple-wms-od.ts` - Simple WMS example
|
| 494 |
+
- `/packages/controlmart/src/examples/generic-builder-examples.ts` - Generic builder examples
|
| 495 |
+
- `/packages/controlmart/src/edi-demos/chaos-edi-demo.ts` - Chaos demo
|
| 496 |
+
- `/packages/controlmart/tests/generic-builder.test.ts` - Builder tests
|
| 497 |
+
- `/packages/controlmart/tests/chaos.od.test.ts` - Chaos tests
|
| 498 |
+
|
| 499 |
+
## Summary
|
| 500 |
+
|
| 501 |
+
**Strengths**:
|
| 502 |
+
- Robust OD execution engine
|
| 503 |
+
- Sophisticated chaos injection framework
|
| 504 |
+
- Multiple services with realistic operations
|
| 505 |
+
- Business rules integration
|
| 506 |
+
- Comprehensive logging
|
| 507 |
+
|
| 508 |
+
**Weaknesses**:
|
| 509 |
+
- No persona model or capability mapping
|
| 510 |
+
- ODs scattered with no central registry
|
| 511 |
+
- No semantic organization or taxonomy
|
| 512 |
+
- Chaos configuration unmanageable
|
| 513 |
+
- No world configuration/sampling
|
| 514 |
+
- No experiment tracking
|
| 515 |
+
|
| 516 |
+
**Next Steps**: Define conceptual model to address these gaps (see [02-conceptual-model.md](./02-conceptual-model.md))
|
docs/od-architecture/02-conceptual-model.md
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 02. Conceptual Model
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This document proposes a conceptual model for organizing Operational Descriptors (ODs) around **capabilities** and **personas**, rather than just services and workflows.
|
| 6 |
+
|
| 7 |
+
## Proposed Architecture Layers
|
| 8 |
+
|
| 9 |
+
```
|
| 10 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 11 |
+
β PERSONA β Who performs actions
|
| 12 |
+
β (Store Manager, Warehouse Worker) β
|
| 13 |
+
ββββββββββββββββββββ¬βββββββββββββββββββββββ
|
| 14 |
+
β has access to
|
| 15 |
+
β
|
| 16 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 17 |
+
β CAPABILITY β What can be done
|
| 18 |
+
β (Order Fulfillment, Inventory Mgmt) β
|
| 19 |
+
ββββββββββββββββββββ¬βββββββββββββββββββββββ
|
| 20 |
+
β implemented by
|
| 21 |
+
β
|
| 22 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 23 |
+
β OPERATIONAL DESCRIPTOR (OD) β How it's done
|
| 24 |
+
β (Workflow definition) β
|
| 25 |
+
ββββββββββββββββββββ¬βββββββββββββββββββββββ
|
| 26 |
+
β composed of
|
| 27 |
+
β
|
| 28 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 29 |
+
β TOOL / API β Atomic operations
|
| 30 |
+
β (getOrder, updateInventory) β
|
| 31 |
+
ββββββββββββββββββββ¬βββββββββββββββββββββββ
|
| 32 |
+
β exposed by
|
| 33 |
+
β
|
| 34 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 35 |
+
β SERVICE β System boundaries
|
| 36 |
+
β (ERP, WMS, TMS, EDI) β
|
| 37 |
+
βββββββββββββββββββββββββββββββββββββββββββ
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
## Layer Definitions
|
| 41 |
+
|
| 42 |
+
### 1. Service Layer
|
| 43 |
+
|
| 44 |
+
**Definition**: A simulated enterprise system that provides tools/APIs.
|
| 45 |
+
|
| 46 |
+
**Examples**:
|
| 47 |
+
- ERP (Enterprise Resource Planning)
|
| 48 |
+
- WMS (Warehouse Management System)
|
| 49 |
+
- TMS (Transportation Management System)
|
| 50 |
+
- EDI (Electronic Data Interchange)
|
| 51 |
+
|
| 52 |
+
**Responsibilities**:
|
| 53 |
+
- Data storage (MongoDB collections)
|
| 54 |
+
- Business logic enforcement
|
| 55 |
+
- API exposure
|
| 56 |
+
- State management
|
| 57 |
+
|
| 58 |
+
**Current Implementation**: β
Well-defined
|
| 59 |
+
- Each service has its own routes, models, and utilities
|
| 60 |
+
- ~162 tools across 4 main services
|
| 61 |
+
|
| 62 |
+
### 2. Tool Layer
|
| 63 |
+
|
| 64 |
+
**Definition**: An atomic API operation that reads or modifies data in a single service.
|
| 65 |
+
|
| 66 |
+
**Examples**:
|
| 67 |
+
- WMS: `inventory/update-quantity`
|
| 68 |
+
- ERP: `orders/create`
|
| 69 |
+
- TMS: `shipments/track`
|
| 70 |
+
- EDI: `generate-850-document`
|
| 71 |
+
|
| 72 |
+
**Characteristics**:
|
| 73 |
+
- Single responsibility
|
| 74 |
+
- Service-scoped
|
| 75 |
+
- Stateless operation
|
| 76 |
+
- Input/output contract
|
| 77 |
+
|
| 78 |
+
**Current Implementation**: β
Well-defined
|
| 79 |
+
- Exposed as REST endpoints
|
| 80 |
+
- Clear input/output schemas
|
| 81 |
+
- Comprehensive coverage
|
| 82 |
+
|
| 83 |
+
### 3. Operational Descriptor (OD) Layer
|
| 84 |
+
|
| 85 |
+
**Definition**: A declarative workflow that orchestrates multiple tools to accomplish an end-to-end business process.
|
| 86 |
+
|
| 87 |
+
**Examples**:
|
| 88 |
+
- "Inbound Receiving Workflow" (TMS shipment β WMS receiving β WMS putaway)
|
| 89 |
+
- "Order Fulfillment" (ERP order β WMS picking β WMS packing β TMS shipping)
|
| 90 |
+
- "EDI 850 Processing" (Generate PO β Create EDI doc β Send ACK β Create invoice)
|
| 91 |
+
|
| 92 |
+
**Characteristics**:
|
| 93 |
+
- Multi-tool orchestration
|
| 94 |
+
- Can span multiple services
|
| 95 |
+
- Contains steps, assertions, retry logic, chaos config
|
| 96 |
+
- Declarative (can be serialized to JSON/YAML)
|
| 97 |
+
|
| 98 |
+
**Current Implementation**: β οΈ Partially defined
|
| 99 |
+
- Strong execution engine
|
| 100 |
+
- Builder patterns for construction
|
| 101 |
+
- **Missing**: Central registry, versioning, metadata
|
| 102 |
+
|
| 103 |
+
### 4. Capability Layer
|
| 104 |
+
|
| 105 |
+
**Definition**: A semantic business function or process that has meaning to domain experts and end users.
|
| 106 |
+
|
| 107 |
+
**Examples**:
|
| 108 |
+
- "Order Fulfillment"
|
| 109 |
+
- "Inventory Management"
|
| 110 |
+
- "Shipment Tracking"
|
| 111 |
+
- "Purchase Order Processing"
|
| 112 |
+
- "Cycle Counting"
|
| 113 |
+
|
| 114 |
+
**Characteristics**:
|
| 115 |
+
- Business-oriented naming
|
| 116 |
+
- Domain-specific
|
| 117 |
+
- May have multiple implementations (simple vs complex)
|
| 118 |
+
- Discoverable and browsable
|
| 119 |
+
|
| 120 |
+
**Relationship to ODs**:
|
| 121 |
+
- **Option A (1:1)**: Each capability has exactly one canonical OD
|
| 122 |
+
- **Option B (1:N)**: One capability can have multiple OD variants
|
| 123 |
+
- Example: "Order Fulfillment" could have:
|
| 124 |
+
- `order-fulfillment-standard` (5 steps, 2 services)
|
| 125 |
+
- `order-fulfillment-express` (3 steps, aggressive SLAs)
|
| 126 |
+
- `order-fulfillment-with-validation` (8 steps, extensive checks)
|
| 127 |
+
- **Option C (N:M)**: Capabilities can share ODs or be composed
|
| 128 |
+
|
| 129 |
+
**Current Implementation**: β Not defined
|
| 130 |
+
- Capabilities are implicit in OD names
|
| 131 |
+
- No formal capability model
|
| 132 |
+
- No metadata or taxonomy
|
| 133 |
+
|
| 134 |
+
### 5. Persona Layer
|
| 135 |
+
|
| 136 |
+
**Definition**: A role or actor in the system that has access to specific capabilities.
|
| 137 |
+
|
| 138 |
+
**Examples**:
|
| 139 |
+
- **Store Manager**: Order management, inventory oversight, staff coordination
|
| 140 |
+
- **Warehouse Worker**: Receiving, picking, packing, putaway
|
| 141 |
+
- **Logistics Coordinator**: Shipment planning, carrier management, route optimization
|
| 142 |
+
- **Purchasing Agent**: Purchase order creation, supplier management
|
| 143 |
+
- **Inventory Auditor**: Cycle counting, variance resolution
|
| 144 |
+
|
| 145 |
+
**Characteristics**:
|
| 146 |
+
- Represents real-world roles
|
| 147 |
+
- Has capability permissions
|
| 148 |
+
- Can be used for access control
|
| 149 |
+
- Enables persona-based world configuration
|
| 150 |
+
|
| 151 |
+
**Relationship to Capabilities**:
|
| 152 |
+
- Personas have many capabilities
|
| 153 |
+
- Capabilities can be shared across personas
|
| 154 |
+
- Permission matrix: `Persona Γ Capability β Boolean`
|
| 155 |
+
|
| 156 |
+
**Current Implementation**: β Not defined
|
| 157 |
+
- No persona model
|
| 158 |
+
- Some role attributes scattered in data models
|
| 159 |
+
- No permission system
|
| 160 |
+
|
| 161 |
+
## Key Relationships
|
| 162 |
+
|
| 163 |
+
### Persona β Capability
|
| 164 |
+
|
| 165 |
+
**Relationship Type**: Many-to-Many
|
| 166 |
+
|
| 167 |
+
**Examples**:
|
| 168 |
+
```
|
| 169 |
+
Store Manager has:
|
| 170 |
+
- Order Fulfillment β
|
| 171 |
+
- Inventory Management β
|
| 172 |
+
- Staff Coordination β
|
| 173 |
+
- Warehouse Receiving β
|
| 174 |
+
|
| 175 |
+
Warehouse Worker has:
|
| 176 |
+
- Warehouse Receiving β
|
| 177 |
+
- Picking & Packing β
|
| 178 |
+
- Putaway β
|
| 179 |
+
- Order Fulfillment β (limited scope)
|
| 180 |
+
```
|
| 181 |
+
|
| 182 |
+
**Implementation Options**:
|
| 183 |
+
- **Static**: Hardcoded in configuration files
|
| 184 |
+
- **Dynamic**: Stored in database, configurable via API
|
| 185 |
+
- **Hybrid**: Default mappings with override capability
|
| 186 |
+
|
| 187 |
+
### Capability β OD
|
| 188 |
+
|
| 189 |
+
**Relationship Type**: TBD (see options above)
|
| 190 |
+
|
| 191 |
+
**Option A: 1:1 Mapping**
|
| 192 |
+
```
|
| 193 |
+
Capability "Order Fulfillment" β OD "order-fulfillment-v1"
|
| 194 |
+
```
|
| 195 |
+
|
| 196 |
+
**Pros**:
|
| 197 |
+
- Simple
|
| 198 |
+
- Clear ownership
|
| 199 |
+
- Easy to reason about
|
| 200 |
+
|
| 201 |
+
**Cons**:
|
| 202 |
+
- Inflexible
|
| 203 |
+
- Can't have variants
|
| 204 |
+
- Complexity hidden inside OD
|
| 205 |
+
|
| 206 |
+
**Option B: 1:N Mapping (Variants)**
|
| 207 |
+
```
|
| 208 |
+
Capability "Order Fulfillment" β [
|
| 209 |
+
OD "order-fulfillment-standard",
|
| 210 |
+
OD "order-fulfillment-express",
|
| 211 |
+
OD "order-fulfillment-international"
|
| 212 |
+
]
|
| 213 |
+
```
|
| 214 |
+
|
| 215 |
+
**Pros**:
|
| 216 |
+
- Flexible
|
| 217 |
+
- Can optimize for different scenarios
|
| 218 |
+
- Clear trade-offs between variants
|
| 219 |
+
|
| 220 |
+
**Cons**:
|
| 221 |
+
- More complex
|
| 222 |
+
- Need selection logic
|
| 223 |
+
- Versioning challenges
|
| 224 |
+
|
| 225 |
+
**Option C: N:M Mapping (Composition)**
|
| 226 |
+
```
|
| 227 |
+
Capability "Order Fulfillment" β OD "order-fulfillment"
|
| 228 |
+
Capability "Inventory Check" β OD "inventory-check"
|
| 229 |
+
|
| 230 |
+
OD "order-fulfillment" uses OD "inventory-check" as sub-workflow
|
| 231 |
+
```
|
| 232 |
+
|
| 233 |
+
**Pros**:
|
| 234 |
+
- Maximum reusability
|
| 235 |
+
- Modular design
|
| 236 |
+
- Hierarchical composition
|
| 237 |
+
|
| 238 |
+
**Cons**:
|
| 239 |
+
- Most complex
|
| 240 |
+
- Circular dependency risk
|
| 241 |
+
- Harder to reason about
|
| 242 |
+
|
| 243 |
+
### OD β Tool
|
| 244 |
+
|
| 245 |
+
**Relationship Type**: Many-to-Many
|
| 246 |
+
|
| 247 |
+
**Characteristics**:
|
| 248 |
+
- ODs reference tools in steps
|
| 249 |
+
- Same tool can be used in multiple ODs
|
| 250 |
+
- Tools can appear multiple times in same OD
|
| 251 |
+
|
| 252 |
+
**Current Implementation**: β
Well-defined
|
| 253 |
+
```typescript
|
| 254 |
+
{
|
| 255 |
+
step: {
|
| 256 |
+
type: "mcp",
|
| 257 |
+
service: "wms",
|
| 258 |
+
tool: "inventory/update-quantity",
|
| 259 |
+
input: { ... }
|
| 260 |
+
}
|
| 261 |
+
}
|
| 262 |
+
```
|
| 263 |
+
|
| 264 |
+
### Tool β Service
|
| 265 |
+
|
| 266 |
+
**Relationship Type**: Many-to-One
|
| 267 |
+
|
| 268 |
+
**Characteristics**:
|
| 269 |
+
- Each tool belongs to exactly one service
|
| 270 |
+
- Services expose many tools
|
| 271 |
+
- Clear boundary
|
| 272 |
+
|
| 273 |
+
**Current Implementation**: β
Well-defined
|
| 274 |
+
|
| 275 |
+
## Data Entities & Dependencies
|
| 276 |
+
|
| 277 |
+
### Data Flow
|
| 278 |
+
|
| 279 |
+
Tools produce and consume **data entities**:
|
| 280 |
+
|
| 281 |
+
**Common Entities**:
|
| 282 |
+
- Order
|
| 283 |
+
- Product
|
| 284 |
+
- Inventory
|
| 285 |
+
- Shipment
|
| 286 |
+
- Customer
|
| 287 |
+
- Location
|
| 288 |
+
- Document (EDI)
|
| 289 |
+
|
| 290 |
+
**Dependencies**:
|
| 291 |
+
```
|
| 292 |
+
Tool "orders/create" produces: Order
|
| 293 |
+
Tool "inventory/allocate" requires: Order, Product
|
| 294 |
+
Tool "picking/create-wave" requires: Order, Inventory
|
| 295 |
+
Tool "shipments/create" requires: Order, Location
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
**Use Case**: Knowledge graph can validate OD feasibility
|
| 299 |
+
- Can we execute this OD with available tools?
|
| 300 |
+
- What data is needed to start this workflow?
|
| 301 |
+
- What data will be produced?
|
| 302 |
+
|
| 303 |
+
## Metadata & Attributes
|
| 304 |
+
|
| 305 |
+
### Capability Metadata
|
| 306 |
+
|
| 307 |
+
**Proposed Schema**:
|
| 308 |
+
```typescript
|
| 309 |
+
{
|
| 310 |
+
id: string, // "order-fulfillment"
|
| 311 |
+
name: string, // "Order Fulfillment"
|
| 312 |
+
description: string, // "Process customer orders..."
|
| 313 |
+
domain: string, // "fulfillment"
|
| 314 |
+
complexity: "simple" | "medium" | "complex",
|
| 315 |
+
tags: string[], // ["retail", "b2c", "warehouse"]
|
| 316 |
+
personas: string[], // ["store-manager", "fulfillment-specialist"]
|
| 317 |
+
ods: string[], // ["order-fulfillment-v1", ...]
|
| 318 |
+
requiredServices: string[], // ["erp", "wms", "tms"]
|
| 319 |
+
estimatedDuration: number, // milliseconds
|
| 320 |
+
version: string // "1.0.0"
|
| 321 |
+
}
|
| 322 |
+
```
|
| 323 |
+
|
| 324 |
+
### OD Metadata
|
| 325 |
+
|
| 326 |
+
**Current Schema** (from od.type.ts):
|
| 327 |
+
```typescript
|
| 328 |
+
{
|
| 329 |
+
id: string,
|
| 330 |
+
name: string,
|
| 331 |
+
version: string,
|
| 332 |
+
description?: string,
|
| 333 |
+
steps: Step[],
|
| 334 |
+
chaos?: ChaosPolicy,
|
| 335 |
+
assertions?: Assertion[],
|
| 336 |
+
metadata?: Record<string, any>
|
| 337 |
+
}
|
| 338 |
+
```
|
| 339 |
+
|
| 340 |
+
**Proposed Additions**:
|
| 341 |
+
```typescript
|
| 342 |
+
{
|
| 343 |
+
// ... existing fields ...
|
| 344 |
+
|
| 345 |
+
// New metadata
|
| 346 |
+
capability?: string, // "order-fulfillment"
|
| 347 |
+
domain?: string, // "fulfillment"
|
| 348 |
+
complexity?: "simple" | "medium" | "complex",
|
| 349 |
+
tags?: string[], // ["retail", "standard-shipping"]
|
| 350 |
+
requiredServices?: string[], // ["erp", "wms"]
|
| 351 |
+
personas?: string[], // ["store-manager"]
|
| 352 |
+
estimatedDuration?: number, // milliseconds
|
| 353 |
+
author?: string, // "system" or researcher name
|
| 354 |
+
createdAt?: Date,
|
| 355 |
+
updatedAt?: Date
|
| 356 |
+
}
|
| 357 |
+
```
|
| 358 |
+
|
| 359 |
+
### Persona Metadata
|
| 360 |
+
|
| 361 |
+
**Proposed Schema**:
|
| 362 |
+
```typescript
|
| 363 |
+
{
|
| 364 |
+
id: string, // "store-manager"
|
| 365 |
+
name: string, // "Store Manager"
|
| 366 |
+
description: string, // "Manages store operations..."
|
| 367 |
+
department: string, // "retail"
|
| 368 |
+
capabilities: string[], // ["order-fulfillment", ...]
|
| 369 |
+
accessLevel: "basic" | "advanced" | "admin",
|
| 370 |
+
tags: string[] // ["management", "retail"]
|
| 371 |
+
}
|
| 372 |
+
```
|
| 373 |
+
|
| 374 |
+
## Design Questions
|
| 375 |
+
|
| 376 |
+
### 1. Capability Definition
|
| 377 |
+
|
| 378 |
+
**Question**: What exactly is a capability?
|
| 379 |
+
|
| 380 |
+
**Options**:
|
| 381 |
+
- **A. Business Function**: High-level processes ("Order Management")
|
| 382 |
+
- **B. User Story**: Goal-oriented tasks ("Fulfill a customer order")
|
| 383 |
+
- **C. Domain Process**: Technical workflows ("Inbound Receiving Flow")
|
| 384 |
+
|
| 385 |
+
**Trade-offs**:
|
| 386 |
+
- A: Too broad, may contain multiple workflows
|
| 387 |
+
- B: Very specific, may explode in count
|
| 388 |
+
- C: Technical, less accessible to non-engineers
|
| 389 |
+
|
| 390 |
+
**Recommendation Needed**: Which resonates with your target users (AI researchers)?
|
| 391 |
+
|
| 392 |
+
### 2. Capability β OD Mapping
|
| 393 |
+
|
| 394 |
+
**Question**: Can one capability have multiple OD implementations?
|
| 395 |
+
|
| 396 |
+
**Scenarios**:
|
| 397 |
+
- Simple vs complex variants
|
| 398 |
+
- Different optimization targets (speed vs accuracy)
|
| 399 |
+
- Evolution over time (v1, v2, v3)
|
| 400 |
+
|
| 401 |
+
**Options**:
|
| 402 |
+
- **A. 1:1**: One capability = one canonical OD
|
| 403 |
+
- **B. 1:N**: One capability = multiple OD variants (with selection logic)
|
| 404 |
+
- **C. N:M**: Capabilities compose and share ODs
|
| 405 |
+
|
| 406 |
+
**Recommendation Needed**: Which provides the right flexibility vs complexity?
|
| 407 |
+
|
| 408 |
+
### 3. Persona Granularity
|
| 409 |
+
|
| 410 |
+
**Question**: How detailed should personas be?
|
| 411 |
+
|
| 412 |
+
**Options**:
|
| 413 |
+
- **A. Broad** (5-10 personas): Manager, Worker, Coordinator, Analyst
|
| 414 |
+
- **B. Detailed** (20-50 personas): Store Manager, DC Manager, Warehouse Manager, etc.
|
| 415 |
+
- **C. Functional** (50+ personas): Receiving Clerk, Picking Specialist, QA Inspector
|
| 416 |
+
|
| 417 |
+
**Trade-offs**:
|
| 418 |
+
- A: Simple, easy to configure, coarse-grained permissions
|
| 419 |
+
- B: Balance of specificity and manageability
|
| 420 |
+
- C: Highly realistic, but complex to manage
|
| 421 |
+
|
| 422 |
+
**Recommendation Needed**: What level of detail is useful for research?
|
| 423 |
+
|
| 424 |
+
### 4. Static vs Dynamic Configuration
|
| 425 |
+
|
| 426 |
+
**Question**: Should persona β capability mappings be configurable?
|
| 427 |
+
|
| 428 |
+
**Options**:
|
| 429 |
+
- **A. Static**: Hardcoded in config files, version controlled
|
| 430 |
+
- **B. Dynamic**: Stored in database, editable via API
|
| 431 |
+
- **C. Hybrid**: Defaults in config, overridable per world
|
| 432 |
+
|
| 433 |
+
**Use Cases**:
|
| 434 |
+
- Researcher wants custom persona for experiment
|
| 435 |
+
- Need to restrict capabilities for specific test
|
| 436 |
+
- Want to evolve personas without code changes
|
| 437 |
+
|
| 438 |
+
**Recommendation Needed**: How much runtime configurability is needed?
|
| 439 |
+
|
| 440 |
+
### 5. Hierarchy & Composition
|
| 441 |
+
|
| 442 |
+
**Question**: Should capabilities have hierarchies or compositions?
|
| 443 |
+
|
| 444 |
+
**Examples**:
|
| 445 |
+
```
|
| 446 |
+
Parent: "Order Management"
|
| 447 |
+
Children:
|
| 448 |
+
- "Create Order"
|
| 449 |
+
- "Fulfill Order"
|
| 450 |
+
- "Cancel Order"
|
| 451 |
+
- "Track Order"
|
| 452 |
+
```
|
| 453 |
+
|
| 454 |
+
or
|
| 455 |
+
|
| 456 |
+
```
|
| 457 |
+
Capability: "Fulfill Order"
|
| 458 |
+
Requires:
|
| 459 |
+
- "Check Inventory" (sub-capability)
|
| 460 |
+
- "Create Shipment" (sub-capability)
|
| 461 |
+
```
|
| 462 |
+
|
| 463 |
+
**Trade-offs**:
|
| 464 |
+
- Hierarchies: Better organization, but more complex
|
| 465 |
+
- Flat: Simpler, but harder to browse
|
| 466 |
+
- Composition: Enables reuse, but adds dependencies
|
| 467 |
+
|
| 468 |
+
**Recommendation Needed**: Is flat structure sufficient, or do we need hierarchies?
|
| 469 |
+
|
| 470 |
+
## Example: Order Fulfillment
|
| 471 |
+
|
| 472 |
+
Let's walk through a concrete example:
|
| 473 |
+
|
| 474 |
+
### Personas
|
| 475 |
+
```
|
| 476 |
+
Store Manager:
|
| 477 |
+
- Can execute order fulfillment
|
| 478 |
+
- Can view inventory
|
| 479 |
+
- Can manage staff
|
| 480 |
+
|
| 481 |
+
Warehouse Worker:
|
| 482 |
+
- Can pick orders
|
| 483 |
+
- Can pack shipments
|
| 484 |
+
- Cannot create orders
|
| 485 |
+
```
|
| 486 |
+
|
| 487 |
+
### Capability
|
| 488 |
+
```
|
| 489 |
+
ID: order-fulfillment
|
| 490 |
+
Name: Order Fulfillment
|
| 491 |
+
Description: Process a customer order from creation to shipment
|
| 492 |
+
Domain: fulfillment
|
| 493 |
+
Complexity: medium
|
| 494 |
+
Tags: [retail, standard-shipping]
|
| 495 |
+
Personas: [store-manager]
|
| 496 |
+
```
|
| 497 |
+
|
| 498 |
+
### ODs (Variant Approach)
|
| 499 |
+
```
|
| 500 |
+
OD: order-fulfillment-standard
|
| 501 |
+
Steps:
|
| 502 |
+
1. ERP: Create order
|
| 503 |
+
2. WMS: Allocate inventory
|
| 504 |
+
3. WMS: Create pick wave
|
| 505 |
+
4. WMS: Assign picker
|
| 506 |
+
5. WMS: Create shipment
|
| 507 |
+
6. TMS: Assign carrier
|
| 508 |
+
7. TMS: Generate shipping label
|
| 509 |
+
|
| 510 |
+
OD: order-fulfillment-express
|
| 511 |
+
Steps:
|
| 512 |
+
1. ERP: Create order (skip validation)
|
| 513 |
+
2. WMS: Auto-allocate
|
| 514 |
+
3. WMS: Create priority shipment
|
| 515 |
+
4. TMS: Assign premium carrier
|
| 516 |
+
```
|
| 517 |
+
|
| 518 |
+
### Tools Used
|
| 519 |
+
```
|
| 520 |
+
- erp/companies/create-company
|
| 521 |
+
- erp/orders/create-order
|
| 522 |
+
- erp/invoices/create-invoice
|
| 523 |
+
- erp/shipments/create-shipment
|
| 524 |
+
- erp/payments/create-payment
|
| 525 |
+
- wms/inventory/allocate
|
| 526 |
+
- wms/picking/create-wave
|
| 527 |
+
- wms/picking/assign-picker
|
| 528 |
+
- wms/shipments/create
|
| 529 |
+
- tms/carriers/assign
|
| 530 |
+
- tms/labels/generate
|
| 531 |
+
```
|
| 532 |
+
|
| 533 |
+
### Services Required
|
| 534 |
+
```
|
| 535 |
+
- ERP
|
| 536 |
+
- WMS
|
| 537 |
+
- TMS
|
| 538 |
+
```
|
| 539 |
+
|
| 540 |
+
## Next Steps
|
| 541 |
+
|
| 542 |
+
1. **Answer design questions** (see above)
|
| 543 |
+
2. **Define capability taxonomy** (see [04-taxonomy-organization.md](./04-taxonomy-organization.md))
|
| 544 |
+
3. **Design knowledge graph** (see [03-knowledge-graph.md](./03-knowledge-graph.md))
|
| 545 |
+
4. **Create persona catalog** (define 10-20 personas)
|
| 546 |
+
5. **Map existing ODs** to capabilities
|
| 547 |
+
|
| 548 |
+
## Related Documents
|
| 549 |
+
|
| 550 |
+
- [01. Current State](./01-current-state.md) - What exists today
|
| 551 |
+
- [03. Knowledge Graph](./03-knowledge-graph.md) - Relationship modeling
|
| 552 |
+
- [04. Taxonomy & Organization](./04-taxonomy-organization.md) - Categorization strategy
|
| 553 |
+
- [06. Open Questions](./06-open-questions.md) - Unresolved decisions
|
docs/od-architecture/03-knowledge-graph.md
ADDED
|
@@ -0,0 +1,689 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 03. Knowledge Graph
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
A **knowledge graph** can model relationships between services, tools, data entities, ODs, capabilities, and personas. This enables intelligent features like:
|
| 6 |
+
- Auto-discovery of valid OD compositions
|
| 7 |
+
- Validation of OD feasibility
|
| 8 |
+
- Suggestion of capabilities based on available tools
|
| 9 |
+
- Dependency analysis
|
| 10 |
+
|
| 11 |
+
## Graph Structure
|
| 12 |
+
|
| 13 |
+
### Node Types
|
| 14 |
+
|
| 15 |
+
```
|
| 16 |
+
βββββββββββββββ
|
| 17 |
+
β PERSONA β Role/actor (e.g., Store Manager)
|
| 18 |
+
βββββββββββββββ
|
| 19 |
+
β
|
| 20 |
+
β can_perform
|
| 21 |
+
β
|
| 22 |
+
βββββββββββββββ
|
| 23 |
+
β CAPABILITY β Business function (e.g., Order Fulfillment)
|
| 24 |
+
βββββββββββββββ
|
| 25 |
+
β
|
| 26 |
+
β implemented_by
|
| 27 |
+
β
|
| 28 |
+
βββββββββββββββ
|
| 29 |
+
β OD β Workflow definition
|
| 30 |
+
βββββββββββββββ
|
| 31 |
+
β
|
| 32 |
+
β uses
|
| 33 |
+
β
|
| 34 |
+
βββββββββββββββ
|
| 35 |
+
β TOOL β API operation (e.g., createOrder)
|
| 36 |
+
βββββββββββββββ
|
| 37 |
+
β
|
| 38 |
+
β exposed_by
|
| 39 |
+
β
|
| 40 |
+
βββββββββββββββ
|
| 41 |
+
β SERVICE β System boundary (e.g., ERP, WMS)
|
| 42 |
+
βββββββββββββββ
|
| 43 |
+
β
|
| 44 |
+
β manages
|
| 45 |
+
β
|
| 46 |
+
βββββββββββββββ
|
| 47 |
+
β ENTITY β Data object (e.g., Order, Product)
|
| 48 |
+
βββββββββββββββ
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
### Node Definitions
|
| 52 |
+
|
| 53 |
+
#### 1. Persona Node
|
| 54 |
+
```typescript
|
| 55 |
+
{
|
| 56 |
+
type: "persona",
|
| 57 |
+
id: "store-manager",
|
| 58 |
+
name: "Store Manager",
|
| 59 |
+
description: "Manages store operations",
|
| 60 |
+
department: "retail",
|
| 61 |
+
accessLevel: "advanced"
|
| 62 |
+
}
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
+
#### 2. Capability Node
|
| 66 |
+
```typescript
|
| 67 |
+
{
|
| 68 |
+
type: "capability",
|
| 69 |
+
id: "order-fulfillment",
|
| 70 |
+
name: "Order Fulfillment",
|
| 71 |
+
description: "Process customer orders end-to-end",
|
| 72 |
+
domain: "fulfillment",
|
| 73 |
+
complexity: "medium"
|
| 74 |
+
}
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
#### 3. OD Node
|
| 78 |
+
```typescript
|
| 79 |
+
{
|
| 80 |
+
type: "od",
|
| 81 |
+
id: "order-fulfillment-standard-v1",
|
| 82 |
+
name: "Standard Order Fulfillment",
|
| 83 |
+
version: "1.0.0",
|
| 84 |
+
complexity: "medium",
|
| 85 |
+
estimatedDuration: 5000 // ms
|
| 86 |
+
}
|
| 87 |
+
```
|
| 88 |
+
|
| 89 |
+
#### 4. Tool Node
|
| 90 |
+
```typescript
|
| 91 |
+
{
|
| 92 |
+
type: "tool",
|
| 93 |
+
id: "wms:inventory:allocate",
|
| 94 |
+
name: "Allocate Inventory",
|
| 95 |
+
service: "wms",
|
| 96 |
+
endpoint: "/inventory/allocate",
|
| 97 |
+
inputSchema: { ... },
|
| 98 |
+
outputSchema: { ... }
|
| 99 |
+
}
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
#### 5. Service Node
|
| 103 |
+
```typescript
|
| 104 |
+
{
|
| 105 |
+
type: "service",
|
| 106 |
+
id: "wms",
|
| 107 |
+
name: "Warehouse Management System",
|
| 108 |
+
baseUrl: "/:worldId/wms"
|
| 109 |
+
}
|
| 110 |
+
```
|
| 111 |
+
|
| 112 |
+
#### 6. Entity Node
|
| 113 |
+
```typescript
|
| 114 |
+
{
|
| 115 |
+
type: "entity",
|
| 116 |
+
id: "order",
|
| 117 |
+
name: "Order",
|
| 118 |
+
collection: "orders",
|
| 119 |
+
schema: { ... }
|
| 120 |
+
}
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
### Edge Types
|
| 124 |
+
|
| 125 |
+
#### Persona β Capability
|
| 126 |
+
```typescript
|
| 127 |
+
{
|
| 128 |
+
source: "store-manager",
|
| 129 |
+
target: "order-fulfillment",
|
| 130 |
+
type: "can_perform",
|
| 131 |
+
permission: "execute" // or "read", "write"
|
| 132 |
+
}
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
#### Capability β OD
|
| 136 |
+
```typescript
|
| 137 |
+
{
|
| 138 |
+
source: "order-fulfillment",
|
| 139 |
+
target: "order-fulfillment-standard-v1",
|
| 140 |
+
type: "implemented_by",
|
| 141 |
+
variant: "standard" // or "express", "international"
|
| 142 |
+
}
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
#### OD β Tool
|
| 146 |
+
```typescript
|
| 147 |
+
{
|
| 148 |
+
source: "order-fulfillment-standard-v1",
|
| 149 |
+
target: "wms:inventory:allocate",
|
| 150 |
+
type: "uses",
|
| 151 |
+
stepIndex: 2,
|
| 152 |
+
required: true
|
| 153 |
+
}
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
#### Tool β Service
|
| 157 |
+
```typescript
|
| 158 |
+
{
|
| 159 |
+
source: "wms:inventory:allocate",
|
| 160 |
+
target: "wms",
|
| 161 |
+
type: "exposed_by"
|
| 162 |
+
}
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
#### Service β Entity
|
| 166 |
+
```typescript
|
| 167 |
+
{
|
| 168 |
+
source: "wms",
|
| 169 |
+
target: "inventory",
|
| 170 |
+
type: "manages"
|
| 171 |
+
}
|
| 172 |
+
```
|
| 173 |
+
|
| 174 |
+
#### Tool β Entity (Data Flow)
|
| 175 |
+
|
| 176 |
+
**Produces**:
|
| 177 |
+
```typescript
|
| 178 |
+
{
|
| 179 |
+
source: "erp:orders:create",
|
| 180 |
+
target: "order",
|
| 181 |
+
type: "produces"
|
| 182 |
+
}
|
| 183 |
+
```
|
| 184 |
+
|
| 185 |
+
**Requires**:
|
| 186 |
+
```typescript
|
| 187 |
+
{
|
| 188 |
+
source: "wms:inventory:allocate",
|
| 189 |
+
target: "order",
|
| 190 |
+
type: "requires"
|
| 191 |
+
}
|
| 192 |
+
```
|
| 193 |
+
|
| 194 |
+
**Modifies**:
|
| 195 |
+
```typescript
|
| 196 |
+
{
|
| 197 |
+
source: "wms:inventory:update-quantity",
|
| 198 |
+
target: "inventory",
|
| 199 |
+
type: "modifies"
|
| 200 |
+
}
|
| 201 |
+
```
|
| 202 |
+
|
| 203 |
+
#### Tool β Tool (Sequencing)
|
| 204 |
+
|
| 205 |
+
**Prerequisite**:
|
| 206 |
+
```typescript
|
| 207 |
+
{
|
| 208 |
+
source: "erp:orders:create",
|
| 209 |
+
target: "wms:inventory:allocate",
|
| 210 |
+
type: "prerequisite",
|
| 211 |
+
reason: "Order must exist before allocation"
|
| 212 |
+
}
|
| 213 |
+
```
|
| 214 |
+
|
| 215 |
+
**Conflicts With**:
|
| 216 |
+
```typescript
|
| 217 |
+
{
|
| 218 |
+
source: "wms:inventory:allocate",
|
| 219 |
+
target: "wms:inventory:deallocate",
|
| 220 |
+
type: "conflicts_with",
|
| 221 |
+
reason: "Cannot allocate and deallocate simultaneously"
|
| 222 |
+
}
|
| 223 |
+
```
|
| 224 |
+
|
| 225 |
+
#### Entity β Entity (Data Relationships)
|
| 226 |
+
|
| 227 |
+
**Contains**:
|
| 228 |
+
```typescript
|
| 229 |
+
{
|
| 230 |
+
source: "order",
|
| 231 |
+
target: "order-line",
|
| 232 |
+
type: "contains",
|
| 233 |
+
cardinality: "one-to-many"
|
| 234 |
+
}
|
| 235 |
+
```
|
| 236 |
+
|
| 237 |
+
**References**:
|
| 238 |
+
```typescript
|
| 239 |
+
{
|
| 240 |
+
source: "order",
|
| 241 |
+
target: "customer",
|
| 242 |
+
type: "references",
|
| 243 |
+
cardinality: "many-to-one"
|
| 244 |
+
}
|
| 245 |
+
```
|
| 246 |
+
|
| 247 |
+
## Use Cases
|
| 248 |
+
|
| 249 |
+
### 1. OD Discovery: "What ODs can I create?"
|
| 250 |
+
|
| 251 |
+
**Scenario**: Given available tools, suggest possible ODs.
|
| 252 |
+
|
| 253 |
+
**Query**:
|
| 254 |
+
```
|
| 255 |
+
Given tools: [erp:orders:create, wms:inventory:allocate, tms:shipments:create]
|
| 256 |
+
Find: Valid OD sequences
|
| 257 |
+
```
|
| 258 |
+
|
| 259 |
+
**Graph Traversal**:
|
| 260 |
+
1. Start with tools
|
| 261 |
+
2. Find entities they produce/require
|
| 262 |
+
3. Identify valid tool chains (where outputs match inputs)
|
| 263 |
+
4. Suggest OD templates
|
| 264 |
+
|
| 265 |
+
**Example Result**:
|
| 266 |
+
```
|
| 267 |
+
Suggested OD: "Simple Order Fulfillment"
|
| 268 |
+
Steps:
|
| 269 |
+
1. erp:orders:create (produces: Order)
|
| 270 |
+
2. wms:inventory:allocate (requires: Order, produces: Allocation)
|
| 271 |
+
3. tms:shipments:create (requires: Order, Allocation)
|
| 272 |
+
```
|
| 273 |
+
|
| 274 |
+
### 2. OD Validation: "Is this OD valid?"
|
| 275 |
+
|
| 276 |
+
**Scenario**: Validate that an OD can actually execute.
|
| 277 |
+
|
| 278 |
+
**Checks**:
|
| 279 |
+
1. **Tool Availability**: Do all referenced tools exist?
|
| 280 |
+
2. **Service Dependencies**: Are required services available?
|
| 281 |
+
3. **Data Flow**: Does each step have required input data?
|
| 282 |
+
4. **Sequencing**: Are there any conflicting operations?
|
| 283 |
+
|
| 284 |
+
**Example Validation**:
|
| 285 |
+
```
|
| 286 |
+
OD: "order-fulfillment-v1"
|
| 287 |
+
Step 1: erp:orders:create β
|
| 288 |
+
- Produces: Order
|
| 289 |
+
Step 2: wms:inventory:allocate β
|
| 290 |
+
- Requires: Order β (produced by step 1)
|
| 291 |
+
- Produces: Allocation
|
| 292 |
+
Step 3: wms:inventory:deallocate β
|
| 293 |
+
- Conflicts with: wms:inventory:allocate (step 2)
|
| 294 |
+
|
| 295 |
+
Result: INVALID - Conflicting operations
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
### 3. Capability Suggestion: "What capabilities are possible?"
|
| 299 |
+
|
| 300 |
+
**Scenario**: Given available services, suggest capabilities.
|
| 301 |
+
|
| 302 |
+
**Query**:
|
| 303 |
+
```
|
| 304 |
+
Given services: [wms, tms]
|
| 305 |
+
Find: Capabilities that only need these services
|
| 306 |
+
```
|
| 307 |
+
|
| 308 |
+
**Graph Traversal**:
|
| 309 |
+
1. Find all tools from these services
|
| 310 |
+
2. Find all ODs that only use these tools
|
| 311 |
+
3. Find all capabilities implemented by these ODs
|
| 312 |
+
|
| 313 |
+
**Example Result**:
|
| 314 |
+
```
|
| 315 |
+
Possible Capabilities:
|
| 316 |
+
- Inbound Receiving (WMS only)
|
| 317 |
+
- Warehouse Transfer (WMS only)
|
| 318 |
+
- Shipment Tracking (TMS only)
|
| 319 |
+
- Outbound Shipping (WMS + TMS)
|
| 320 |
+
|
| 321 |
+
Not Possible:
|
| 322 |
+
- Order Fulfillment (requires ERP)
|
| 323 |
+
- EDI Processing (requires EDI service)
|
| 324 |
+
```
|
| 325 |
+
|
| 326 |
+
### 4. Dependency Analysis: "What does this OD need?"
|
| 327 |
+
|
| 328 |
+
**Scenario**: Understand prerequisites for an OD.
|
| 329 |
+
|
| 330 |
+
**Query**:
|
| 331 |
+
```
|
| 332 |
+
For OD: "order-fulfillment-standard-v1"
|
| 333 |
+
Find: All dependencies
|
| 334 |
+
```
|
| 335 |
+
|
| 336 |
+
**Graph Traversal**:
|
| 337 |
+
1. Find all tools used by OD
|
| 338 |
+
2. Find all services hosting those tools
|
| 339 |
+
3. Find all entities required by tools
|
| 340 |
+
4. Find all prerequisite data
|
| 341 |
+
|
| 342 |
+
**Example Result**:
|
| 343 |
+
```
|
| 344 |
+
OD: "order-fulfillment-standard-v1"
|
| 345 |
+
|
| 346 |
+
Required Services:
|
| 347 |
+
- ERP
|
| 348 |
+
- WMS
|
| 349 |
+
- TMS
|
| 350 |
+
|
| 351 |
+
Required Entities (Input):
|
| 352 |
+
- Customer (must pre-exist)
|
| 353 |
+
- Product (must pre-exist)
|
| 354 |
+
- Inventory (must have stock)
|
| 355 |
+
|
| 356 |
+
Produced Entities (Output):
|
| 357 |
+
- Order
|
| 358 |
+
- Allocation
|
| 359 |
+
- Shipment
|
| 360 |
+
```
|
| 361 |
+
|
| 362 |
+
### 5. Impact Analysis: "What breaks if I change this?"
|
| 363 |
+
|
| 364 |
+
**Scenario**: Understand impact of removing/changing a tool or service.
|
| 365 |
+
|
| 366 |
+
**Query**:
|
| 367 |
+
```
|
| 368 |
+
If we remove tool: "wms:inventory:allocate"
|
| 369 |
+
What is affected?
|
| 370 |
+
```
|
| 371 |
+
|
| 372 |
+
**Graph Traversal**:
|
| 373 |
+
1. Find all ODs using this tool
|
| 374 |
+
2. Find all capabilities implemented by those ODs
|
| 375 |
+
3. Find all personas with access to those capabilities
|
| 376 |
+
|
| 377 |
+
**Example Result**:
|
| 378 |
+
```
|
| 379 |
+
Removing "wms:inventory:allocate" affects:
|
| 380 |
+
|
| 381 |
+
ODs (3):
|
| 382 |
+
- order-fulfillment-standard-v1 (step 2)
|
| 383 |
+
- order-fulfillment-express-v1 (step 2)
|
| 384 |
+
- inventory-reservation-v1 (step 1)
|
| 385 |
+
|
| 386 |
+
Capabilities (2):
|
| 387 |
+
- Order Fulfillment
|
| 388 |
+
- Inventory Reservation
|
| 389 |
+
|
| 390 |
+
Personas (3):
|
| 391 |
+
- Store Manager
|
| 392 |
+
- Fulfillment Specialist
|
| 393 |
+
- Inventory Manager
|
| 394 |
+
|
| 395 |
+
Recommendation: High impact - find alternative or create substitute
|
| 396 |
+
```
|
| 397 |
+
|
| 398 |
+
### 6. Path Finding: "How do I get from A to B?"
|
| 399 |
+
|
| 400 |
+
**Scenario**: Find tool sequences to transform one entity into another.
|
| 401 |
+
|
| 402 |
+
**Query**:
|
| 403 |
+
```
|
| 404 |
+
Start: Customer (exists)
|
| 405 |
+
Goal: Shipment (with tracking number)
|
| 406 |
+
Find: Shortest tool path
|
| 407 |
+
```
|
| 408 |
+
|
| 409 |
+
**Graph Traversal**:
|
| 410 |
+
1. Start with Customer entity
|
| 411 |
+
2. Find tools that require Customer (produces Order)
|
| 412 |
+
3. Continue until Shipment is produced
|
| 413 |
+
4. Return shortest path
|
| 414 |
+
|
| 415 |
+
**Example Result**:
|
| 416 |
+
```
|
| 417 |
+
Path:
|
| 418 |
+
Customer β [erp:orders:create] β Order
|
| 419 |
+
Order β [wms:inventory:allocate] β Allocation
|
| 420 |
+
Order + Allocation β [wms:shipments:create] β Shipment
|
| 421 |
+
Shipment β [tms:carriers:assign] β Shipment (with carrier)
|
| 422 |
+
Shipment β [tms:labels:generate] β Shipment (with tracking)
|
| 423 |
+
|
| 424 |
+
Suggested OD: 5 steps, 3 services (ERP, WMS, TMS)
|
| 425 |
+
```
|
| 426 |
+
|
| 427 |
+
## Implementation Approaches
|
| 428 |
+
|
| 429 |
+
### Option A: Static Analysis (Build Time)
|
| 430 |
+
|
| 431 |
+
**How**: Analyze code/config files to build graph.
|
| 432 |
+
|
| 433 |
+
**Process**:
|
| 434 |
+
1. Parse TypeScript types and service tool definitions
|
| 435 |
+
2. Extract input/output schemas from tools
|
| 436 |
+
3. Build graph from static information
|
| 437 |
+
4. Generate graph file (JSON/GraphML)
|
| 438 |
+
|
| 439 |
+
**Pros**:
|
| 440 |
+
- No runtime overhead
|
| 441 |
+
- Version controlled
|
| 442 |
+
- Can be part of CI/CD
|
| 443 |
+
|
| 444 |
+
**Cons**:
|
| 445 |
+
- Doesn't capture runtime behavior
|
| 446 |
+
- Misses dynamic relationships
|
| 447 |
+
- Requires manual annotation for data flow
|
| 448 |
+
|
| 449 |
+
**Tools**:
|
| 450 |
+
- TypeScript compiler API
|
| 451 |
+
- JSON schema analysis
|
| 452 |
+
- Custom AST traversal
|
| 453 |
+
|
| 454 |
+
### Option B: Dynamic Learning (Runtime)
|
| 455 |
+
|
| 456 |
+
**How**: Learn relationships from actual OD executions.
|
| 457 |
+
|
| 458 |
+
**Process**:
|
| 459 |
+
1. Start with basic graph (services, tools)
|
| 460 |
+
2. Monitor OD executions
|
| 461 |
+
3. Record which tools are called together
|
| 462 |
+
4. Infer data flow from step outputs β inputs
|
| 463 |
+
5. Update graph weights based on frequency
|
| 464 |
+
|
| 465 |
+
**Pros**:
|
| 466 |
+
- Discovers actual usage patterns
|
| 467 |
+
- Adapts over time
|
| 468 |
+
- Captures implicit dependencies
|
| 469 |
+
|
| 470 |
+
**Cons**:
|
| 471 |
+
- Requires execution history
|
| 472 |
+
- Slow to bootstrap
|
| 473 |
+
- May learn anti-patterns
|
| 474 |
+
|
| 475 |
+
**Data Sources**:
|
| 476 |
+
- OD execution logs
|
| 477 |
+
- Step input/output traces
|
| 478 |
+
- Success/failure rates
|
| 479 |
+
|
| 480 |
+
### Option C: Hybrid (Static + Runtime)
|
| 481 |
+
|
| 482 |
+
**How**: Start with static analysis, refine with runtime data.
|
| 483 |
+
|
| 484 |
+
**Process**:
|
| 485 |
+
1. Build initial graph from code (static)
|
| 486 |
+
2. Annotate tools with produces/requires/modifies (manual or inferred)
|
| 487 |
+
3. Validate and refine during execution (runtime)
|
| 488 |
+
4. Update edge weights based on usage
|
| 489 |
+
|
| 490 |
+
**Pros**:
|
| 491 |
+
- Best of both worlds
|
| 492 |
+
- Quick bootstrap
|
| 493 |
+
- Improves over time
|
| 494 |
+
|
| 495 |
+
**Cons**:
|
| 496 |
+
- More complex
|
| 497 |
+
- Need to reconcile conflicts
|
| 498 |
+
- Schema evolution challenges
|
| 499 |
+
|
| 500 |
+
**Recommendation**: Start with static, add runtime as phase 2.
|
| 501 |
+
|
| 502 |
+
## Graph Technology Options
|
| 503 |
+
|
| 504 |
+
### Option 1: In-Memory Graph (JavaScript)
|
| 505 |
+
|
| 506 |
+
**Libraries**:
|
| 507 |
+
- `graphlib` (lightweight, simple)
|
| 508 |
+
- `cytoscape.js` (visualization support)
|
| 509 |
+
- Custom adjacency list
|
| 510 |
+
|
| 511 |
+
**Pros**:
|
| 512 |
+
- Simple
|
| 513 |
+
- Fast for small graphs
|
| 514 |
+
- No external dependencies
|
| 515 |
+
|
| 516 |
+
**Cons**:
|
| 517 |
+
- Not persistent
|
| 518 |
+
- Limited query capabilities
|
| 519 |
+
- Rebuild on every startup
|
| 520 |
+
|
| 521 |
+
### Option 2: Graph Database (Neo4j, ArangoDB)
|
| 522 |
+
|
| 523 |
+
**Pros**:
|
| 524 |
+
- Purpose-built for graphs
|
| 525 |
+
- Powerful query language (Cypher, AQL)
|
| 526 |
+
- Scales to large graphs
|
| 527 |
+
- Persistent
|
| 528 |
+
|
| 529 |
+
**Cons**:
|
| 530 |
+
- Additional infrastructure
|
| 531 |
+
- Complexity
|
| 532 |
+
- Overkill for initial version
|
| 533 |
+
|
| 534 |
+
### Option 3: MongoDB (Document + Relationships)
|
| 535 |
+
|
| 536 |
+
**Pros**:
|
| 537 |
+
- Already using MongoDB
|
| 538 |
+
- Can store nodes and edges as documents
|
| 539 |
+
- Familiar query language
|
| 540 |
+
- Good for hybrid approach
|
| 541 |
+
|
| 542 |
+
**Cons**:
|
| 543 |
+
- Not optimized for graph traversal
|
| 544 |
+
- Complex queries for deep traversals
|
| 545 |
+
- Manual relationship management
|
| 546 |
+
|
| 547 |
+
**Recommendation**: Start with in-memory (Option 1), migrate to MongoDB (Option 3) when persistence needed.
|
| 548 |
+
|
| 549 |
+
## Practical Example: Order Fulfillment Graph
|
| 550 |
+
|
| 551 |
+
### Nodes
|
| 552 |
+
```javascript
|
| 553 |
+
// Persona
|
| 554 |
+
{ type: "persona", id: "store-manager", name: "Store Manager" }
|
| 555 |
+
|
| 556 |
+
// Capability
|
| 557 |
+
{ type: "capability", id: "order-fulfillment", name: "Order Fulfillment" }
|
| 558 |
+
|
| 559 |
+
// OD
|
| 560 |
+
{ type: "od", id: "order-fulfillment-v1", name: "Standard Order Fulfillment" }
|
| 561 |
+
|
| 562 |
+
// Tools
|
| 563 |
+
{ type: "tool", id: "erp:orders:create", service: "erp" }
|
| 564 |
+
{ type: "tool", id: "wms:inventory:allocate", service: "wms" }
|
| 565 |
+
{ type: "tool", id: "tms:shipments:create", service: "tms" }
|
| 566 |
+
|
| 567 |
+
// Services
|
| 568 |
+
{ type: "service", id: "erp", name: "ERP" }
|
| 569 |
+
{ type: "service", id: "wms", name: "WMS" }
|
| 570 |
+
{ type: "service", id: "tms", name: "TMS" }
|
| 571 |
+
|
| 572 |
+
// Entities
|
| 573 |
+
{ type: "entity", id: "order", collection: "orders" }
|
| 574 |
+
{ type: "entity", id: "inventory", collection: "inventory" }
|
| 575 |
+
{ type: "entity", id: "shipment", collection: "shipments" }
|
| 576 |
+
```
|
| 577 |
+
|
| 578 |
+
### Edges
|
| 579 |
+
```javascript
|
| 580 |
+
// Persona β Capability
|
| 581 |
+
{ from: "store-manager", to: "order-fulfillment", type: "can_perform" }
|
| 582 |
+
|
| 583 |
+
// Capability β OD
|
| 584 |
+
{ from: "order-fulfillment", to: "order-fulfillment-v1", type: "implemented_by" }
|
| 585 |
+
|
| 586 |
+
// OD β Tools
|
| 587 |
+
{ from: "order-fulfillment-v1", to: "erp:orders:create", type: "uses", step: 1 }
|
| 588 |
+
{ from: "order-fulfillment-v1", to: "wms:inventory:allocate", type: "uses", step: 2 }
|
| 589 |
+
{ from: "order-fulfillment-v1", to: "tms:shipments:create", type: "uses", step: 3 }
|
| 590 |
+
|
| 591 |
+
// Tools β Services
|
| 592 |
+
{ from: "erp:orders:create", to: "erp", type: "exposed_by" }
|
| 593 |
+
{ from: "wms:inventory:allocate", to: "wms", type: "exposed_by" }
|
| 594 |
+
{ from: "tms:shipments:create", to: "tms", type: "exposed_by" }
|
| 595 |
+
|
| 596 |
+
// Tools β Entities (Data Flow)
|
| 597 |
+
{ from: "erp:orders:create", to: "order", type: "produces" }
|
| 598 |
+
{ from: "wms:inventory:allocate", to: "order", type: "requires" }
|
| 599 |
+
{ from: "wms:inventory:allocate", to: "inventory", type: "modifies" }
|
| 600 |
+
{ from: "tms:shipments:create", to: "order", type: "requires" }
|
| 601 |
+
{ from: "tms:shipments:create", to: "shipment", type: "produces" }
|
| 602 |
+
```
|
| 603 |
+
|
| 604 |
+
### Queries
|
| 605 |
+
|
| 606 |
+
**Query 1: What can a store manager do?**
|
| 607 |
+
```javascript
|
| 608 |
+
// Traverse: Persona β Capability
|
| 609 |
+
getOutgoingEdges("store-manager", "can_perform")
|
| 610 |
+
// Result: ["order-fulfillment", "inventory-management", ...]
|
| 611 |
+
```
|
| 612 |
+
|
| 613 |
+
**Query 2: How is order fulfillment implemented?**
|
| 614 |
+
```javascript
|
| 615 |
+
// Traverse: Capability β OD β Tool
|
| 616 |
+
getOutgoingEdges("order-fulfillment", "implemented_by") // ODs
|
| 617 |
+
.flatMap(od => getOutgoingEdges(od, "uses")) // Tools
|
| 618 |
+
// Result: ["erp:orders:create", "wms:inventory:allocate", "tms:shipments:create"]
|
| 619 |
+
```
|
| 620 |
+
|
| 621 |
+
**Query 3: What entities does order fulfillment require?**
|
| 622 |
+
```javascript
|
| 623 |
+
// Get OD's tools, then find entities they require
|
| 624 |
+
const tools = getOutgoingEdges("order-fulfillment-v1", "uses")
|
| 625 |
+
const requiredEntities = tools
|
| 626 |
+
.flatMap(tool => getOutgoingEdges(tool, "requires"))
|
| 627 |
+
.filter(node => node.type === "entity")
|
| 628 |
+
// Result: ["order", "inventory"]
|
| 629 |
+
```
|
| 630 |
+
|
| 631 |
+
## Open Questions
|
| 632 |
+
|
| 633 |
+
### 1. Graph Granularity
|
| 634 |
+
|
| 635 |
+
**Question**: How detailed should the graph be?
|
| 636 |
+
|
| 637 |
+
**Options**:
|
| 638 |
+
- **Coarse**: Just services, capabilities, personas
|
| 639 |
+
- **Medium**: + tools, entities
|
| 640 |
+
- **Fine**: + tool parameters, entity fields, step-level details
|
| 641 |
+
|
| 642 |
+
**Trade-off**: Detail vs maintainability
|
| 643 |
+
|
| 644 |
+
### 2. Data Flow Inference
|
| 645 |
+
|
| 646 |
+
**Question**: How do we know which entities a tool produces/requires?
|
| 647 |
+
|
| 648 |
+
**Options**:
|
| 649 |
+
- **Manual Annotation**: Developers specify in code comments or metadata
|
| 650 |
+
- **Schema Analysis**: Infer from input/output TypeScript types
|
| 651 |
+
- **Runtime Learning**: Monitor actual executions
|
| 652 |
+
|
| 653 |
+
**Recommendation Needed**: Feasibility of each approach?
|
| 654 |
+
|
| 655 |
+
### 3. Graph Updates
|
| 656 |
+
|
| 657 |
+
**Question**: When does the graph get updated?
|
| 658 |
+
|
| 659 |
+
**Options**:
|
| 660 |
+
- **Build Time**: Regenerated on every deployment
|
| 661 |
+
- **Startup**: Built when service starts
|
| 662 |
+
- **Runtime**: Updated as ODs execute
|
| 663 |
+
|
| 664 |
+
**Recommendation Needed**: What's the update frequency requirement?
|
| 665 |
+
|
| 666 |
+
### 4. Query Performance
|
| 667 |
+
|
| 668 |
+
**Question**: Do we need to optimize for specific query patterns?
|
| 669 |
+
|
| 670 |
+
**Common Queries**:
|
| 671 |
+
- "What can persona X do?" (1-hop traversal)
|
| 672 |
+
- "What ODs use tool Y?" (reverse lookup)
|
| 673 |
+
- "Find path from A to B" (shortest path, can be expensive)
|
| 674 |
+
|
| 675 |
+
**Recommendation Needed**: Which queries are most critical?
|
| 676 |
+
|
| 677 |
+
## Next Steps
|
| 678 |
+
|
| 679 |
+
1. **Choose implementation approach** (static/dynamic/hybrid)
|
| 680 |
+
2. **Select graph technology** (in-memory/Neo4j/MongoDB)
|
| 681 |
+
3. **Define annotation format** for manual metadata
|
| 682 |
+
4. **Build proof-of-concept** for one use case (e.g., OD validation)
|
| 683 |
+
5. **Evaluate query performance** on realistic graph size
|
| 684 |
+
|
| 685 |
+
## Related Documents
|
| 686 |
+
|
| 687 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - Defines nodes (Persona, Capability, OD)
|
| 688 |
+
- [04. Taxonomy & Organization](./04-taxonomy-organization.md) - How to categorize nodes
|
| 689 |
+
- [06. Open Questions](./06-open-questions.md) - Unresolved decisions
|
docs/od-architecture/04-taxonomy-organization.md
ADDED
|
@@ -0,0 +1,619 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 04. Taxonomy & Organization
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This document proposes taxonomies for organizing capabilities and ODs so that researchers can easily browse, filter, and discover what they need.
|
| 6 |
+
|
| 7 |
+
## Taxonomy Dimensions
|
| 8 |
+
|
| 9 |
+
### 1. Domain-Based Organization
|
| 10 |
+
|
| 11 |
+
Organize by **business domain** or functional area.
|
| 12 |
+
|
| 13 |
+
#### Proposed Domains
|
| 14 |
+
|
| 15 |
+
```
|
| 16 |
+
Supply Chain Management
|
| 17 |
+
βββ Procurement
|
| 18 |
+
β βββ Supplier Management
|
| 19 |
+
β βββ Purchase Order Creation
|
| 20 |
+
β βββ RFQ Processing
|
| 21 |
+
β βββ Vendor Evaluation
|
| 22 |
+
β
|
| 23 |
+
βββ Inventory Management
|
| 24 |
+
β βββ Stock Control
|
| 25 |
+
β βββ Cycle Counting
|
| 26 |
+
β βββ Replenishment
|
| 27 |
+
β βββ Allocation
|
| 28 |
+
β
|
| 29 |
+
βββ Fulfillment
|
| 30 |
+
β βββ Order Processing
|
| 31 |
+
β βββ Picking & Packing
|
| 32 |
+
β βββ Wave Management
|
| 33 |
+
β βββ Returns Processing
|
| 34 |
+
β
|
| 35 |
+
βββ Warehousing
|
| 36 |
+
β βββ Inbound Receiving
|
| 37 |
+
β βββ Putaway
|
| 38 |
+
β βββ Transfers
|
| 39 |
+
β βββ Labor Management
|
| 40 |
+
β
|
| 41 |
+
βββ Transportation
|
| 42 |
+
β βββ Shipment Planning
|
| 43 |
+
β βββ Carrier Management
|
| 44 |
+
β βββ Route Optimization
|
| 45 |
+
β βββ Delivery Tracking
|
| 46 |
+
β
|
| 47 |
+
βββ Data Exchange
|
| 48 |
+
β βββ EDI Document Processing
|
| 49 |
+
β βββ API Integration
|
| 50 |
+
β βββ File Import/Export
|
| 51 |
+
β βββ Format Transformation
|
| 52 |
+
β
|
| 53 |
+
βββ Analytics & Reporting
|
| 54 |
+
βββ KPI Dashboards
|
| 55 |
+
βββ Exception Monitoring
|
| 56 |
+
βββ Audit Trails
|
| 57 |
+
βββ Performance Analysis
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
**Pros**:
|
| 61 |
+
- Aligned with business language
|
| 62 |
+
- Easy for domain experts to navigate
|
| 63 |
+
- Clear ownership
|
| 64 |
+
|
| 65 |
+
**Cons**:
|
| 66 |
+
- Cross-domain capabilities hard to categorize
|
| 67 |
+
- May not match researcher mental models
|
| 68 |
+
- Requires domain knowledge
|
| 69 |
+
|
| 70 |
+
#### Example Mapping
|
| 71 |
+
```
|
| 72 |
+
Domain: Fulfillment
|
| 73 |
+
Capabilities:
|
| 74 |
+
- Order Fulfillment
|
| 75 |
+
- Express Order Fulfillment
|
| 76 |
+
- Drop Ship Fulfillment
|
| 77 |
+
- Pick & Pack
|
| 78 |
+
- Order Cancellation
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### 2. Persona-Based Organization
|
| 82 |
+
|
| 83 |
+
Organize by **who** performs the capability.
|
| 84 |
+
|
| 85 |
+
#### Proposed Personas
|
| 86 |
+
|
| 87 |
+
```
|
| 88 |
+
Management Roles
|
| 89 |
+
βββ Store Manager
|
| 90 |
+
β βββ Capabilities: Order oversight, inventory review, staff coordination
|
| 91 |
+
βββ Warehouse Manager
|
| 92 |
+
β βββ Capabilities: Resource planning, performance monitoring
|
| 93 |
+
βββ Logistics Manager
|
| 94 |
+
β βββ Capabilities: Route planning, carrier negotiation
|
| 95 |
+
βββ Operations Director
|
| 96 |
+
βββ Capabilities: Multi-site coordination, strategic planning
|
| 97 |
+
|
| 98 |
+
Operational Roles
|
| 99 |
+
βββ Warehouse Worker
|
| 100 |
+
β βββ Capabilities: Receiving, picking, packing, putaway
|
| 101 |
+
βββ Inventory Specialist
|
| 102 |
+
β βββ Capabilities: Cycle counting, adjustments, audits
|
| 103 |
+
βββ Shipping Clerk
|
| 104 |
+
β βββ Capabilities: Label generation, manifest creation
|
| 105 |
+
βββ Receiving Clerk
|
| 106 |
+
βββ Capabilities: Appointment scheduling, unloading, inspection
|
| 107 |
+
|
| 108 |
+
Analytical Roles
|
| 109 |
+
βββ Demand Planner
|
| 110 |
+
β βββ Capabilities: Forecast analysis, replenishment planning
|
| 111 |
+
βββ Business Analyst
|
| 112 |
+
β βββ Capabilities: Report generation, exception analysis
|
| 113 |
+
βββ Data Engineer
|
| 114 |
+
βββ Capabilities: Data integration, pipeline management
|
| 115 |
+
|
| 116 |
+
System Roles
|
| 117 |
+
βββ EDI Operator
|
| 118 |
+
β βββ Capabilities: EDI mapping, document transmission
|
| 119 |
+
βββ Integration Specialist
|
| 120 |
+
β βββ Capabilities: API configuration, webhook setup
|
| 121 |
+
βββ Automation Bot
|
| 122 |
+
βββ Capabilities: Scheduled workflows, event-driven processes
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
**Pros**:
|
| 126 |
+
- Intuitive for role-based access
|
| 127 |
+
- Clear permission model
|
| 128 |
+
- Enables persona-specific worlds
|
| 129 |
+
|
| 130 |
+
**Cons**:
|
| 131 |
+
- Capabilities may span multiple personas
|
| 132 |
+
- Persona definitions may vary by organization
|
| 133 |
+
- Maintenance overhead
|
| 134 |
+
|
| 135 |
+
#### Example Mapping
|
| 136 |
+
```
|
| 137 |
+
Persona: Store Manager
|
| 138 |
+
Capabilities:
|
| 139 |
+
- Order Fulfillment
|
| 140 |
+
- Inventory Management
|
| 141 |
+
- Staff Scheduling
|
| 142 |
+
- Exception Handling
|
| 143 |
+
|
| 144 |
+
Cannot Access:
|
| 145 |
+
- Warehouse Physical Operations (worker-level tasks)
|
| 146 |
+
- System Configuration (admin tasks)
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
### 3. Complexity-Based Organization
|
| 150 |
+
|
| 151 |
+
Organize by **complexity** level.
|
| 152 |
+
|
| 153 |
+
#### Complexity Metrics
|
| 154 |
+
|
| 155 |
+
**Quantitative Factors**:
|
| 156 |
+
- Number of steps (1-3: simple, 4-7: medium, 8+: complex)
|
| 157 |
+
- Number of services involved (1: simple, 2-3: medium, 4+: complex)
|
| 158 |
+
- Number of decision points (conditionals, branches)
|
| 159 |
+
- Average execution time
|
| 160 |
+
- Error rate / retry frequency
|
| 161 |
+
|
| 162 |
+
**Qualitative Factors**:
|
| 163 |
+
- Requires domain expertise?
|
| 164 |
+
- Has edge cases?
|
| 165 |
+
- Needs manual intervention?
|
| 166 |
+
- High business impact?
|
| 167 |
+
|
| 168 |
+
#### Complexity Tiers
|
| 169 |
+
|
| 170 |
+
```
|
| 171 |
+
SIMPLE (Tier 1)
|
| 172 |
+
βββ Definition: 1-3 steps, single service, no branching
|
| 173 |
+
βββ Examples:
|
| 174 |
+
β βββ Check Inventory Level
|
| 175 |
+
β βββ Create Purchase Order
|
| 176 |
+
β βββ Update Product Price
|
| 177 |
+
β βββ Generate Report
|
| 178 |
+
βββ Use Case: Learning, testing, debugging
|
| 179 |
+
|
| 180 |
+
MEDIUM (Tier 2)
|
| 181 |
+
βββ Definition: 4-7 steps, 2-3 services, some branching
|
| 182 |
+
βββ Examples:
|
| 183 |
+
β βββ Process Customer Order
|
| 184 |
+
β βββ Receive Shipment
|
| 185 |
+
β βββ Allocate Inventory
|
| 186 |
+
β βββ Generate EDI 850
|
| 187 |
+
βββ Use Case: Standard operations, automation
|
| 188 |
+
|
| 189 |
+
COMPLEX (Tier 3)
|
| 190 |
+
βββ Definition: 8+ steps, multi-service, extensive branching
|
| 191 |
+
βββ Examples:
|
| 192 |
+
β βββ End-to-End Order Fulfillment
|
| 193 |
+
β βββ Cross-Dock Transfer
|
| 194 |
+
β βββ Returns Processing with Restocking
|
| 195 |
+
β βββ Multi-Leg Shipment Orchestration
|
| 196 |
+
βββ Use Case: Advanced scenarios, research experiments
|
| 197 |
+
```
|
| 198 |
+
|
| 199 |
+
**Pros**:
|
| 200 |
+
- Easy to assess difficulty
|
| 201 |
+
- Good for progressive learning
|
| 202 |
+
- Helps with sampling strategies
|
| 203 |
+
|
| 204 |
+
**Cons**:
|
| 205 |
+
- Subjective boundaries
|
| 206 |
+
- May not reflect actual difficulty
|
| 207 |
+
- Changes as system evolves
|
| 208 |
+
|
| 209 |
+
#### Example Mapping
|
| 210 |
+
```
|
| 211 |
+
Capability: Order Fulfillment
|
| 212 |
+
|
| 213 |
+
Simple Variant:
|
| 214 |
+
- Steps: 3 (Create order, allocate inventory, create shipment)
|
| 215 |
+
- Services: 2 (ERP, WMS)
|
| 216 |
+
- Estimated Duration: 2 seconds
|
| 217 |
+
|
| 218 |
+
Medium Variant:
|
| 219 |
+
- Steps: 7 (Add validation, picking, packing, carrier assignment)
|
| 220 |
+
- Services: 3 (ERP, WMS, TMS)
|
| 221 |
+
- Estimated Duration: 5 seconds
|
| 222 |
+
|
| 223 |
+
Complex Variant:
|
| 224 |
+
- Steps: 12 (Add fraud check, inventory reservation, multi-location, split shipments)
|
| 225 |
+
- Services: 4 (ERP, WMS, TMS, External Payment Gateway)
|
| 226 |
+
- Estimated Duration: 10 seconds
|
| 227 |
+
```
|
| 228 |
+
|
| 229 |
+
### 4. Service-Based Organization (Current)
|
| 230 |
+
|
| 231 |
+
Organize by **which service(s)** are involved.
|
| 232 |
+
|
| 233 |
+
```
|
| 234 |
+
Single Service
|
| 235 |
+
βββ ERP-Only
|
| 236 |
+
β βββ Customer Management
|
| 237 |
+
β βββ Product Catalog
|
| 238 |
+
β βββ Order Entry
|
| 239 |
+
βββ WMS-Only
|
| 240 |
+
β βββ Cycle Counting
|
| 241 |
+
β βββ Putaway
|
| 242 |
+
β βββ Inventory Adjustment
|
| 243 |
+
βββ TMS-Only
|
| 244 |
+
βββ Carrier Rate Lookup
|
| 245 |
+
βββ Shipment Tracking
|
| 246 |
+
βββ Route Planning
|
| 247 |
+
|
| 248 |
+
Multi-Service
|
| 249 |
+
βββ ERP + WMS
|
| 250 |
+
β βββ Order Fulfillment (partial)
|
| 251 |
+
β βββ Inventory Synchronization
|
| 252 |
+
βββ WMS + TMS
|
| 253 |
+
β βββ Outbound Shipping
|
| 254 |
+
β βββ Inbound Receiving
|
| 255 |
+
βββ ERP + EDI
|
| 256 |
+
β βββ EDI 850 Processing
|
| 257 |
+
β βββ Invoice Generation
|
| 258 |
+
βββ ERP + WMS + TMS
|
| 259 |
+
βββ End-to-End Order Fulfillment
|
| 260 |
+
βββ Drop Ship Workflow
|
| 261 |
+
```
|
| 262 |
+
|
| 263 |
+
**Pros**:
|
| 264 |
+
- Matches current architecture
|
| 265 |
+
- Clear technical dependencies
|
| 266 |
+
- Easy to implement
|
| 267 |
+
|
| 268 |
+
**Cons**:
|
| 269 |
+
- Not user-friendly
|
| 270 |
+
- Technical rather than semantic
|
| 271 |
+
- Doesn't help discovery
|
| 272 |
+
|
| 273 |
+
### 5. Workflow Pattern Organization
|
| 274 |
+
|
| 275 |
+
Organize by **common workflow patterns**.
|
| 276 |
+
|
| 277 |
+
```
|
| 278 |
+
Sequential Workflows
|
| 279 |
+
βββ Linear Pipeline (A β B β C)
|
| 280 |
+
βββ Example: Inbound Receiving (Appointment β Unload β Inspect β Putaway)
|
| 281 |
+
|
| 282 |
+
Parallel Workflows
|
| 283 |
+
βββ Fork-Join (A β [B, C, D] β E)
|
| 284 |
+
βββ Example: Multi-Location Picking (Split order β Pick at each DC β Consolidate)
|
| 285 |
+
|
| 286 |
+
Conditional Workflows
|
| 287 |
+
βββ If-Then-Else (A β Decision β B or C)
|
| 288 |
+
βββ Example: Order Routing (Check inventory β Ship from DC or Store)
|
| 289 |
+
|
| 290 |
+
Event-Driven Workflows
|
| 291 |
+
βββ Trigger-Action (Event β OD)
|
| 292 |
+
βββ Example: Low Stock Alert β Auto-Replenishment
|
| 293 |
+
|
| 294 |
+
Iterative Workflows
|
| 295 |
+
βββ Loop Until Condition (Repeat A until B)
|
| 296 |
+
βββ Example: Cycle Count (Check location β Adjust β Next location)
|
| 297 |
+
|
| 298 |
+
Compensating Workflows
|
| 299 |
+
βββ Try-Catch-Rollback (A β B fails β Undo A)
|
| 300 |
+
βββ Example: Order Cancellation (Release inventory, refund payment, notify customer)
|
| 301 |
+
```
|
| 302 |
+
|
| 303 |
+
**Pros**:
|
| 304 |
+
- Educational for learning workflow patterns
|
| 305 |
+
- Useful for OD design
|
| 306 |
+
- Technical but accessible
|
| 307 |
+
|
| 308 |
+
**Cons**:
|
| 309 |
+
- Multiple patterns may apply
|
| 310 |
+
- Orthogonal to business meaning
|
| 311 |
+
- Complex to categorize
|
| 312 |
+
|
| 313 |
+
## Multi-Dimensional Tagging
|
| 314 |
+
|
| 315 |
+
Rather than forcing a single taxonomy, use **tags** to support multiple views.
|
| 316 |
+
|
| 317 |
+
### Tag Schema
|
| 318 |
+
|
| 319 |
+
```typescript
|
| 320 |
+
{
|
| 321 |
+
// Core Tags
|
| 322 |
+
domain: string[], // ["fulfillment", "inventory"]
|
| 323 |
+
persona: string[], // ["store-manager", "warehouse-worker"]
|
| 324 |
+
complexity: "simple" | "medium" | "complex",
|
| 325 |
+
|
| 326 |
+
// Service Tags
|
| 327 |
+
services: string[], // ["erp", "wms", "tms"]
|
| 328 |
+
serviceCount: number, // 3
|
| 329 |
+
|
| 330 |
+
// Pattern Tags
|
| 331 |
+
pattern: string[], // ["sequential", "conditional"]
|
| 332 |
+
|
| 333 |
+
// Functional Tags
|
| 334 |
+
category: string[], // ["order-processing", "shipping"]
|
| 335 |
+
|
| 336 |
+
// Technical Tags
|
| 337 |
+
stepCount: number, // 7
|
| 338 |
+
estimatedDuration: number, // 5000 (ms)
|
| 339 |
+
hasExternalDeps: boolean, // false
|
| 340 |
+
|
| 341 |
+
// Business Tags
|
| 342 |
+
businessImpact: "low" | "medium" | "high",
|
| 343 |
+
frequency: "rare" | "occasional" | "frequent",
|
| 344 |
+
|
| 345 |
+
// Meta Tags
|
| 346 |
+
version: string, // "1.0.0"
|
| 347 |
+
author: string, // "system" | researcher name
|
| 348 |
+
status: "draft" | "stable" | "deprecated"
|
| 349 |
+
}
|
| 350 |
+
```
|
| 351 |
+
|
| 352 |
+
### Tag-Based Filtering
|
| 353 |
+
|
| 354 |
+
Researchers can filter by any combination:
|
| 355 |
+
|
| 356 |
+
**Example Queries**:
|
| 357 |
+
```
|
| 358 |
+
# Simple warehouse operations
|
| 359 |
+
domain: "warehousing"
|
| 360 |
+
complexity: "simple"
|
| 361 |
+
services: ["wms"]
|
| 362 |
+
|
| 363 |
+
# Store manager capabilities (medium complexity)
|
| 364 |
+
persona: "store-manager"
|
| 365 |
+
complexity: ["medium", "complex"]
|
| 366 |
+
|
| 367 |
+
# High-frequency fulfillment workflows
|
| 368 |
+
domain: "fulfillment"
|
| 369 |
+
frequency: "frequent"
|
| 370 |
+
businessImpact: ["medium", "high"]
|
| 371 |
+
|
| 372 |
+
# Cross-service workflows
|
| 373 |
+
serviceCount: >= 2
|
| 374 |
+
pattern: "sequential"
|
| 375 |
+
```
|
| 376 |
+
|
| 377 |
+
## Browsing & Discovery UI Concepts
|
| 378 |
+
|
| 379 |
+
### Concept 1: Hierarchical Tree View
|
| 380 |
+
|
| 381 |
+
```
|
| 382 |
+
π Supply Chain Management
|
| 383 |
+
π Fulfillment
|
| 384 |
+
π Order Fulfillment (medium, store-manager)
|
| 385 |
+
π Express Fulfillment (simple, store-manager)
|
| 386 |
+
π Drop Ship (complex, logistics-manager)
|
| 387 |
+
π Inventory Management
|
| 388 |
+
π Cycle Count (simple, inventory-specialist)
|
| 389 |
+
π Replenishment (medium, warehouse-manager)
|
| 390 |
+
```
|
| 391 |
+
|
| 392 |
+
### Concept 2: Persona-Centric View
|
| 393 |
+
|
| 394 |
+
```
|
| 395 |
+
π€ Store Manager
|
| 396 |
+
π My Capabilities (12)
|
| 397 |
+
β Order Fulfillment
|
| 398 |
+
β Inventory Management
|
| 399 |
+
β Exception Handling
|
| 400 |
+
π By Complexity
|
| 401 |
+
Simple: 4 capabilities
|
| 402 |
+
Medium: 6 capabilities
|
| 403 |
+
Complex: 2 capabilities
|
| 404 |
+
```
|
| 405 |
+
|
| 406 |
+
### Concept 3: Tag Cloud / Faceted Search
|
| 407 |
+
|
| 408 |
+
```
|
| 409 |
+
π·οΈ Tags:
|
| 410 |
+
Domain: [Fulfillment (8)] [Inventory (12)] [Transportation (6)]
|
| 411 |
+
Complexity: [Simple (15)] [Medium (20)] [Complex (8)]
|
| 412 |
+
Persona: [Store Manager (10)] [Warehouse Worker (18)]
|
| 413 |
+
|
| 414 |
+
π Search: "order"
|
| 415 |
+
Results (3):
|
| 416 |
+
- Order Fulfillment (fulfillment, medium, store-manager)
|
| 417 |
+
- Order Cancellation (fulfillment, simple, store-manager)
|
| 418 |
+
- Purchase Order Creation (procurement, simple, purchasing-agent)
|
| 419 |
+
```
|
| 420 |
+
|
| 421 |
+
### Concept 4: Capability Matrix
|
| 422 |
+
|
| 423 |
+
```
|
| 424 |
+
β Simple β Medium β Complex β
|
| 425 |
+
ββββββββββββββββΌβββββββββΌβββββββββΌββββββββββ€
|
| 426 |
+
Fulfillment β 4 β 8 β 3 β
|
| 427 |
+
Inventory β 6 β 5 β 1 β
|
| 428 |
+
Transportation β 3 β 4 β 2 β
|
| 429 |
+
Warehousing β 5 β 6 β 4 β
|
| 430 |
+
```
|
| 431 |
+
|
| 432 |
+
## Practical Examples
|
| 433 |
+
|
| 434 |
+
### Example 1: Order Fulfillment Taxonomy
|
| 435 |
+
|
| 436 |
+
```yaml
|
| 437 |
+
capability:
|
| 438 |
+
id: order-fulfillment
|
| 439 |
+
name: Order Fulfillment
|
| 440 |
+
|
| 441 |
+
tags:
|
| 442 |
+
domain: [fulfillment, order-processing]
|
| 443 |
+
persona: [store-manager, fulfillment-specialist]
|
| 444 |
+
complexity: medium
|
| 445 |
+
services: [erp, wms, tms]
|
| 446 |
+
serviceCount: 3
|
| 447 |
+
pattern: [sequential, conditional]
|
| 448 |
+
category: [order-processing, shipping]
|
| 449 |
+
businessImpact: high
|
| 450 |
+
frequency: frequent
|
| 451 |
+
|
| 452 |
+
variants:
|
| 453 |
+
- id: order-fulfillment-standard
|
| 454 |
+
complexity: medium
|
| 455 |
+
stepCount: 7
|
| 456 |
+
estimatedDuration: 5000
|
| 457 |
+
|
| 458 |
+
- id: order-fulfillment-express
|
| 459 |
+
complexity: simple
|
| 460 |
+
stepCount: 4
|
| 461 |
+
estimatedDuration: 3000
|
| 462 |
+
tags: [expedited]
|
| 463 |
+
|
| 464 |
+
- id: order-fulfillment-international
|
| 465 |
+
complexity: complex
|
| 466 |
+
stepCount: 12
|
| 467 |
+
estimatedDuration: 10000
|
| 468 |
+
tags: [customs, international]
|
| 469 |
+
```
|
| 470 |
+
|
| 471 |
+
### Example 2: Warehouse Operations Taxonomy
|
| 472 |
+
|
| 473 |
+
```yaml
|
| 474 |
+
domain:
|
| 475 |
+
id: warehousing
|
| 476 |
+
name: Warehouse Operations
|
| 477 |
+
|
| 478 |
+
capabilities:
|
| 479 |
+
- name: Inbound Receiving
|
| 480 |
+
complexity: medium
|
| 481 |
+
personas: [receiving-clerk, warehouse-worker]
|
| 482 |
+
|
| 483 |
+
- name: Putaway
|
| 484 |
+
complexity: simple
|
| 485 |
+
personas: [warehouse-worker]
|
| 486 |
+
|
| 487 |
+
- name: Cycle Counting
|
| 488 |
+
complexity: simple
|
| 489 |
+
personas: [inventory-specialist]
|
| 490 |
+
|
| 491 |
+
- name: Wave Picking
|
| 492 |
+
complexity: medium
|
| 493 |
+
personas: [warehouse-worker, picking-specialist]
|
| 494 |
+
|
| 495 |
+
- name: Cross-Dock Transfer
|
| 496 |
+
complexity: complex
|
| 497 |
+
personas: [warehouse-manager]
|
| 498 |
+
```
|
| 499 |
+
|
| 500 |
+
## Recommended Approach
|
| 501 |
+
|
| 502 |
+
### Phase 1: Multi-Dimensional Tagging (Immediate)
|
| 503 |
+
|
| 504 |
+
Implement comprehensive tagging on all capabilities and ODs:
|
| 505 |
+
- Domain, persona, complexity (required)
|
| 506 |
+
- Service, pattern, category (optional)
|
| 507 |
+
- Business metadata (impact, frequency)
|
| 508 |
+
|
| 509 |
+
**Benefits**:
|
| 510 |
+
- Maximum flexibility
|
| 511 |
+
- Supports all browsing patterns
|
| 512 |
+
- Easy to extend
|
| 513 |
+
|
| 514 |
+
### Phase 2: Default Views (Short-term)
|
| 515 |
+
|
| 516 |
+
Create 3 primary views:
|
| 517 |
+
1. **Domain View** (default for business users)
|
| 518 |
+
2. **Persona View** (for role-based access)
|
| 519 |
+
3. **Complexity View** (for learning/sampling)
|
| 520 |
+
|
| 521 |
+
**Benefits**:
|
| 522 |
+
- Guided discovery
|
| 523 |
+
- Reduces cognitive load
|
| 524 |
+
- Meets different user needs
|
| 525 |
+
|
| 526 |
+
### Phase 3: Smart Search (Medium-term)
|
| 527 |
+
|
| 528 |
+
Add search with:
|
| 529 |
+
- Full-text search on names/descriptions
|
| 530 |
+
- Tag-based filtering
|
| 531 |
+
- Similarity search ("find capabilities like this one")
|
| 532 |
+
|
| 533 |
+
**Benefits**:
|
| 534 |
+
- Powerful for expert users
|
| 535 |
+
- Handles edge cases
|
| 536 |
+
- Scales to large catalogs
|
| 537 |
+
|
| 538 |
+
### Phase 4: Personalized Recommendations (Long-term)
|
| 539 |
+
|
| 540 |
+
Use knowledge graph + usage data to suggest:
|
| 541 |
+
- "Researchers working on X also used Y"
|
| 542 |
+
- "Based on your world config, you might need Z"
|
| 543 |
+
- "This capability requires these prerequisites"
|
| 544 |
+
|
| 545 |
+
**Benefits**:
|
| 546 |
+
- Contextual
|
| 547 |
+
- Reduces trial-and-error
|
| 548 |
+
- Learns from community
|
| 549 |
+
|
| 550 |
+
## Open Questions
|
| 551 |
+
|
| 552 |
+
### 1. Primary Organization
|
| 553 |
+
|
| 554 |
+
**Question**: What should be the default/primary taxonomy?
|
| 555 |
+
|
| 556 |
+
**Options**:
|
| 557 |
+
- Domain-based (business-oriented)
|
| 558 |
+
- Persona-based (role-oriented)
|
| 559 |
+
- Complexity-based (learning-oriented)
|
| 560 |
+
- Multi-dimensional tags (no primary)
|
| 561 |
+
|
| 562 |
+
**Recommendation Needed**: What's most intuitive for AI researchers?
|
| 563 |
+
|
| 564 |
+
### 2. Tag Vocabulary
|
| 565 |
+
|
| 566 |
+
**Question**: Should tag values be freeform or controlled?
|
| 567 |
+
|
| 568 |
+
**Options**:
|
| 569 |
+
- **Freeform**: Authors can add any tags
|
| 570 |
+
- **Controlled**: Pre-defined tag vocabulary
|
| 571 |
+
- **Hybrid**: Core tags controlled, custom tags allowed
|
| 572 |
+
|
| 573 |
+
**Trade-offs**:
|
| 574 |
+
- Freeform: Flexible but inconsistent
|
| 575 |
+
- Controlled: Consistent but rigid
|
| 576 |
+
|
| 577 |
+
**Recommendation Needed**: How important is consistency?
|
| 578 |
+
|
| 579 |
+
### 3. Maintenance Strategy
|
| 580 |
+
|
| 581 |
+
**Question**: Who maintains the taxonomy?
|
| 582 |
+
|
| 583 |
+
**Options**:
|
| 584 |
+
- **System**: Auto-generated from code
|
| 585 |
+
- **Manual**: Curated by team
|
| 586 |
+
- **Community**: Researchers contribute tags
|
| 587 |
+
- **Hybrid**: System baseline + manual refinement
|
| 588 |
+
|
| 589 |
+
**Recommendation Needed**: What's sustainable long-term?
|
| 590 |
+
|
| 591 |
+
### 4. Granularity
|
| 592 |
+
|
| 593 |
+
**Question**: How detailed should categories be?
|
| 594 |
+
|
| 595 |
+
**Example**:
|
| 596 |
+
- Coarse: "Fulfillment" (20 capabilities)
|
| 597 |
+
- Medium: "Order Processing", "Picking & Packing", "Returns" (5-8 each)
|
| 598 |
+
- Fine: "Standard Picking", "Batch Picking", "Zone Picking" (1-3 each)
|
| 599 |
+
|
| 600 |
+
**Trade-offs**:
|
| 601 |
+
- Coarse: Simple but less precise
|
| 602 |
+
- Fine: Precise but overwhelming
|
| 603 |
+
|
| 604 |
+
**Recommendation Needed**: What level of detail is useful?
|
| 605 |
+
|
| 606 |
+
## Next Steps
|
| 607 |
+
|
| 608 |
+
1. **Choose primary taxonomy** (domain/persona/complexity/tags)
|
| 609 |
+
2. **Define tag schema** and controlled vocabulary
|
| 610 |
+
3. **Tag existing ODs** in codebase
|
| 611 |
+
4. **Build browsing UI** (or API endpoints for CLI)
|
| 612 |
+
5. **Test with users** and iterate
|
| 613 |
+
|
| 614 |
+
## Related Documents
|
| 615 |
+
|
| 616 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - Capability and persona definitions
|
| 617 |
+
- [03. Knowledge Graph](./03-knowledge-graph.md) - Relationship modeling
|
| 618 |
+
- [05. Sampling & World Config](./05-sampling-world-config.md) - Using taxonomy for filtering
|
| 619 |
+
- [06. Open Questions](./06-open-questions.md) - Unresolved decisions
|
docs/od-architecture/05-sampling-world-config.md
ADDED
|
@@ -0,0 +1,754 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 05. Sampling & World Configuration
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
Researchers need the ability to configure "worlds" with specific subsets of capabilities, rather than always having all 100+ capabilities available. This document explores sampling strategies and world configuration patterns.
|
| 6 |
+
|
| 7 |
+
## Problem Statement
|
| 8 |
+
|
| 9 |
+
**Current State**:
|
| 10 |
+
- Every world has all services and tools available
|
| 11 |
+
- All ODs are accessible to all users
|
| 12 |
+
- No way to create focused, specialized environments
|
| 13 |
+
|
| 14 |
+
**User Needs**:
|
| 15 |
+
- "Give me only warehouse operations" (domain filtering)
|
| 16 |
+
- "Sample 10 random capabilities for testing" (random sampling)
|
| 17 |
+
- "Progressive complexity: start simple, add complexity" (staged learning)
|
| 18 |
+
- "Retail-only world for store management research" (persona filtering)
|
| 19 |
+
|
| 20 |
+
## Use Cases
|
| 21 |
+
|
| 22 |
+
### Use Case 1: Domain-Specific Research
|
| 23 |
+
|
| 24 |
+
**Scenario**: Researcher studying warehouse automation
|
| 25 |
+
|
| 26 |
+
**Need**: World with only warehouse-related capabilities
|
| 27 |
+
|
| 28 |
+
**Configuration**:
|
| 29 |
+
```yaml
|
| 30 |
+
world:
|
| 31 |
+
name: "Warehouse Automation Study"
|
| 32 |
+
filter:
|
| 33 |
+
domains: [warehousing, inventory]
|
| 34 |
+
services: [wms]
|
| 35 |
+
|
| 36 |
+
result:
|
| 37 |
+
capabilities: 25 (out of 100)
|
| 38 |
+
- Inbound Receiving
|
| 39 |
+
- Putaway
|
| 40 |
+
- Cycle Counting
|
| 41 |
+
- Picking & Packing
|
| 42 |
+
- Replenishment
|
| 43 |
+
- Warehouse Transfers
|
| 44 |
+
- Labor Management
|
| 45 |
+
...
|
| 46 |
+
|
| 47 |
+
excluded:
|
| 48 |
+
- Order Fulfillment (requires ERP)
|
| 49 |
+
- Shipment Tracking (requires TMS)
|
| 50 |
+
- EDI Processing (requires EDI)
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
### Use Case 2: Persona-Based World
|
| 54 |
+
|
| 55 |
+
**Scenario**: Training AI agent as "Store Manager"
|
| 56 |
+
|
| 57 |
+
**Need**: World with only store manager capabilities
|
| 58 |
+
|
| 59 |
+
**Configuration**:
|
| 60 |
+
```yaml
|
| 61 |
+
world:
|
| 62 |
+
name: "Store Manager Training"
|
| 63 |
+
filter:
|
| 64 |
+
personas: [store-manager]
|
| 65 |
+
|
| 66 |
+
result:
|
| 67 |
+
capabilities: 15
|
| 68 |
+
- Order Fulfillment
|
| 69 |
+
- Inventory Management
|
| 70 |
+
- Exception Handling
|
| 71 |
+
- Staff Coordination
|
| 72 |
+
- Customer Service Escalation
|
| 73 |
+
...
|
| 74 |
+
|
| 75 |
+
excluded:
|
| 76 |
+
- Warehouse Physical Tasks (worker-level)
|
| 77 |
+
- System Administration (admin-level)
|
| 78 |
+
- Data Engineering (technical roles)
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### Use Case 3: Progressive Complexity
|
| 82 |
+
|
| 83 |
+
**Scenario**: Learning path from simple to complex
|
| 84 |
+
|
| 85 |
+
**Need**: Start with simple capabilities, gradually add complexity
|
| 86 |
+
|
| 87 |
+
**Configuration**:
|
| 88 |
+
```yaml
|
| 89 |
+
world:
|
| 90 |
+
name: "Progressive Learning Path"
|
| 91 |
+
stages:
|
| 92 |
+
- stage: 1
|
| 93 |
+
complexity: [simple]
|
| 94 |
+
count: 10
|
| 95 |
+
|
| 96 |
+
- stage: 2
|
| 97 |
+
complexity: [simple, medium]
|
| 98 |
+
count: 20
|
| 99 |
+
|
| 100 |
+
- stage: 3
|
| 101 |
+
complexity: [simple, medium, complex]
|
| 102 |
+
count: all
|
| 103 |
+
|
| 104 |
+
result:
|
| 105 |
+
stage1: 10 simple capabilities
|
| 106 |
+
stage2: + 10 medium capabilities
|
| 107 |
+
stage3: + all remaining capabilities
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
### Use Case 4: Random Sampling for Generalization
|
| 111 |
+
|
| 112 |
+
**Scenario**: Testing AI agent on diverse, random tasks
|
| 113 |
+
|
| 114 |
+
**Need**: Randomly sample N capabilities
|
| 115 |
+
|
| 116 |
+
**Configuration**:
|
| 117 |
+
```yaml
|
| 118 |
+
world:
|
| 119 |
+
name: "Random Capability Test"
|
| 120 |
+
sampling:
|
| 121 |
+
strategy: random
|
| 122 |
+
count: 20
|
| 123 |
+
seed: "reproducible-123"
|
| 124 |
+
|
| 125 |
+
result:
|
| 126 |
+
capabilities: 20 randomly selected
|
| 127 |
+
- Mix of domains, complexities, services
|
| 128 |
+
- Reproducible with same seed
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
### Use Case 5: Weighted Sampling by Frequency
|
| 132 |
+
|
| 133 |
+
**Scenario**: Realistic distribution of common vs rare operations
|
| 134 |
+
|
| 135 |
+
**Need**: Sample based on real-world frequency
|
| 136 |
+
|
| 137 |
+
**Configuration**:
|
| 138 |
+
```yaml
|
| 139 |
+
world:
|
| 140 |
+
name: "Realistic Operations Mix"
|
| 141 |
+
sampling:
|
| 142 |
+
strategy: weighted
|
| 143 |
+
weights:
|
| 144 |
+
frequency: 0.7 # 70% weight on frequency
|
| 145 |
+
complexity: 0.2 # 20% weight on complexity
|
| 146 |
+
businessImpact: 0.1 # 10% weight on impact
|
| 147 |
+
count: 30
|
| 148 |
+
|
| 149 |
+
result:
|
| 150 |
+
capabilities: 30 selected
|
| 151 |
+
- 60% frequent operations (order processing, inventory checks)
|
| 152 |
+
- 30% occasional operations (cycle counts, transfers)
|
| 153 |
+
- 10% rare operations (exceptions, reversals)
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
### Use Case 6: Capability Prerequisites
|
| 157 |
+
|
| 158 |
+
**Scenario**: Ensure dependent capabilities are included
|
| 159 |
+
|
| 160 |
+
**Need**: Auto-include prerequisites when selecting capabilities
|
| 161 |
+
|
| 162 |
+
**Configuration**:
|
| 163 |
+
```yaml
|
| 164 |
+
world:
|
| 165 |
+
name: "Fulfillment with Dependencies"
|
| 166 |
+
capabilities:
|
| 167 |
+
- order-fulfillment # explicitly selected
|
| 168 |
+
|
| 169 |
+
autoIncludeDependencies: true
|
| 170 |
+
|
| 171 |
+
result:
|
| 172 |
+
included:
|
| 173 |
+
- order-fulfillment (explicit)
|
| 174 |
+
- inventory-check (prerequisite)
|
| 175 |
+
- create-shipment (prerequisite)
|
| 176 |
+
- carrier-assignment (prerequisite)
|
| 177 |
+
```
|
| 178 |
+
|
| 179 |
+
## Sampling Strategies
|
| 180 |
+
|
| 181 |
+
### 1. Filter-Based Selection
|
| 182 |
+
|
| 183 |
+
**Method**: Boolean filtering on tags
|
| 184 |
+
|
| 185 |
+
**Criteria**:
|
| 186 |
+
- Domain(s)
|
| 187 |
+
- Persona(s)
|
| 188 |
+
- Complexity level(s)
|
| 189 |
+
- Service(s)
|
| 190 |
+
- Pattern(s)
|
| 191 |
+
- Business impact
|
| 192 |
+
- Frequency
|
| 193 |
+
|
| 194 |
+
**Algorithm**:
|
| 195 |
+
```typescript
|
| 196 |
+
function filterCapabilities(
|
| 197 |
+
allCapabilities: Capability[],
|
| 198 |
+
filters: Filters
|
| 199 |
+
): Capability[] {
|
| 200 |
+
return allCapabilities.filter(cap => {
|
| 201 |
+
if (filters.domains && !filters.domains.includes(cap.domain)) return false;
|
| 202 |
+
if (filters.personas && !cap.personas.some(p => filters.personas.includes(p))) return false;
|
| 203 |
+
if (filters.complexity && cap.complexity !== filters.complexity) return false;
|
| 204 |
+
if (filters.services && !cap.services.every(s => filters.services.includes(s))) return false;
|
| 205 |
+
// ... more filters
|
| 206 |
+
return true;
|
| 207 |
+
});
|
| 208 |
+
}
|
| 209 |
+
```
|
| 210 |
+
|
| 211 |
+
**Pros**:
|
| 212 |
+
- Deterministic
|
| 213 |
+
- Intuitive
|
| 214 |
+
- Easy to explain
|
| 215 |
+
|
| 216 |
+
**Cons**:
|
| 217 |
+
- May return too many or too few results
|
| 218 |
+
- No control over count
|
| 219 |
+
|
| 220 |
+
### 2. Random Sampling
|
| 221 |
+
|
| 222 |
+
**Method**: Randomly select N capabilities
|
| 223 |
+
|
| 224 |
+
**Variants**:
|
| 225 |
+
- **Uniform Random**: All capabilities equally likely
|
| 226 |
+
- **Stratified Random**: Sample from each category proportionally
|
| 227 |
+
|
| 228 |
+
**Algorithm**:
|
| 229 |
+
```typescript
|
| 230 |
+
function randomSample(
|
| 231 |
+
capabilities: Capability[],
|
| 232 |
+
count: number,
|
| 233 |
+
seed?: string
|
| 234 |
+
): Capability[] {
|
| 235 |
+
const rng = seed ? seededRandom(seed) : Math.random;
|
| 236 |
+
const shuffled = shuffle(capabilities, rng);
|
| 237 |
+
return shuffled.slice(0, count);
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
function stratifiedSample(
|
| 241 |
+
capabilities: Capability[],
|
| 242 |
+
count: number,
|
| 243 |
+
stratifyBy: 'domain' | 'complexity' | 'persona'
|
| 244 |
+
): Capability[] {
|
| 245 |
+
const groups = groupBy(capabilities, stratifyBy);
|
| 246 |
+
const perGroup = Math.ceil(count / groups.length);
|
| 247 |
+
return groups.flatMap(group => randomSample(group, perGroup)).slice(0, count);
|
| 248 |
+
}
|
| 249 |
+
```
|
| 250 |
+
|
| 251 |
+
**Pros**:
|
| 252 |
+
- Good for generalization testing
|
| 253 |
+
- Reproducible with seed
|
| 254 |
+
- Unbiased
|
| 255 |
+
|
| 256 |
+
**Cons**:
|
| 257 |
+
- May not match researcher intent
|
| 258 |
+
- May include unrelated capabilities
|
| 259 |
+
- No semantic coherence
|
| 260 |
+
|
| 261 |
+
### 3. Weighted Sampling
|
| 262 |
+
|
| 263 |
+
**Method**: Sample based on attribute weights
|
| 264 |
+
|
| 265 |
+
**Weights**:
|
| 266 |
+
- **Frequency**: How often used in real world
|
| 267 |
+
- **Business Impact**: High-impact operations more likely
|
| 268 |
+
- **Complexity**: Prefer simpler or more complex
|
| 269 |
+
- **Recency**: Recently added capabilities
|
| 270 |
+
- **Popularity**: Most-used by other researchers
|
| 271 |
+
|
| 272 |
+
**Algorithm**:
|
| 273 |
+
```typescript
|
| 274 |
+
function weightedSample(
|
| 275 |
+
capabilities: Capability[],
|
| 276 |
+
count: number,
|
| 277 |
+
weights: WeightConfig
|
| 278 |
+
): Capability[] {
|
| 279 |
+
// Calculate composite score for each capability
|
| 280 |
+
const scored = capabilities.map(cap => ({
|
| 281 |
+
capability: cap,
|
| 282 |
+
score:
|
| 283 |
+
cap.frequency * weights.frequency +
|
| 284 |
+
cap.businessImpact * weights.businessImpact +
|
| 285 |
+
(1 / cap.complexity) * weights.simplicity
|
| 286 |
+
}));
|
| 287 |
+
|
| 288 |
+
// Sort by score and take top N
|
| 289 |
+
return scored
|
| 290 |
+
.sort((a, b) => b.score - a.score)
|
| 291 |
+
.slice(0, count)
|
| 292 |
+
.map(s => s.capability);
|
| 293 |
+
}
|
| 294 |
+
```
|
| 295 |
+
|
| 296 |
+
**Pros**:
|
| 297 |
+
- Realistic distributions
|
| 298 |
+
- Tunable via weights
|
| 299 |
+
- Can match real-world scenarios
|
| 300 |
+
|
| 301 |
+
**Cons**:
|
| 302 |
+
- Requires metadata (frequency, impact)
|
| 303 |
+
- More complex to configure
|
| 304 |
+
- Less predictable
|
| 305 |
+
|
| 306 |
+
### 4. Hierarchical Sampling
|
| 307 |
+
|
| 308 |
+
**Method**: Sample from capability hierarchy
|
| 309 |
+
|
| 310 |
+
**Approach**:
|
| 311 |
+
- Start with high-level domains
|
| 312 |
+
- Drill down to sub-capabilities
|
| 313 |
+
- Ensure coverage across hierarchy
|
| 314 |
+
|
| 315 |
+
**Algorithm**:
|
| 316 |
+
```typescript
|
| 317 |
+
function hierarchicalSample(
|
| 318 |
+
capabilityTree: CapabilityTree,
|
| 319 |
+
countPerLevel: number[]
|
| 320 |
+
): Capability[] {
|
| 321 |
+
const selected: Capability[] = [];
|
| 322 |
+
|
| 323 |
+
// Level 0: Domains
|
| 324 |
+
const domains = randomSample(capabilityTree.domains, countPerLevel[0]);
|
| 325 |
+
|
| 326 |
+
domains.forEach(domain => {
|
| 327 |
+
// Level 1: Categories within domain
|
| 328 |
+
const categories = randomSample(domain.categories, countPerLevel[1]);
|
| 329 |
+
|
| 330 |
+
categories.forEach(category => {
|
| 331 |
+
// Level 2: Capabilities within category
|
| 332 |
+
selected.push(...randomSample(category.capabilities, countPerLevel[2]));
|
| 333 |
+
});
|
| 334 |
+
});
|
| 335 |
+
|
| 336 |
+
return selected;
|
| 337 |
+
}
|
| 338 |
+
```
|
| 339 |
+
|
| 340 |
+
**Pros**:
|
| 341 |
+
- Ensures diversity
|
| 342 |
+
- Covers different areas
|
| 343 |
+
- Good for broad testing
|
| 344 |
+
|
| 345 |
+
**Cons**:
|
| 346 |
+
- Requires hierarchical structure
|
| 347 |
+
- May not match real workflows
|
| 348 |
+
- Complex configuration
|
| 349 |
+
|
| 350 |
+
### 5. Graph-Based Sampling
|
| 351 |
+
|
| 352 |
+
**Method**: Use knowledge graph to ensure coherence
|
| 353 |
+
|
| 354 |
+
**Approach**:
|
| 355 |
+
- Select seed capability
|
| 356 |
+
- Include connected capabilities (prerequisites, dependents)
|
| 357 |
+
- Expand by graph distance
|
| 358 |
+
|
| 359 |
+
**Algorithm**:
|
| 360 |
+
```typescript
|
| 361 |
+
function graphSample(
|
| 362 |
+
graph: KnowledgeGraph,
|
| 363 |
+
seedCapability: string,
|
| 364 |
+
maxDistance: number,
|
| 365 |
+
maxCount: number
|
| 366 |
+
): Capability[] {
|
| 367 |
+
const visited = new Set<string>();
|
| 368 |
+
const queue: [string, number][] = [[seedCapability, 0]];
|
| 369 |
+
const selected: Capability[] = [];
|
| 370 |
+
|
| 371 |
+
while (queue.length > 0 && selected.length < maxCount) {
|
| 372 |
+
const [capId, distance] = queue.shift()!;
|
| 373 |
+
|
| 374 |
+
if (visited.has(capId) || distance > maxDistance) continue;
|
| 375 |
+
visited.add(capId);
|
| 376 |
+
|
| 377 |
+
const capability = graph.getNode(capId);
|
| 378 |
+
selected.push(capability);
|
| 379 |
+
|
| 380 |
+
// Add neighbors
|
| 381 |
+
const neighbors = graph.getNeighbors(capId, ['prerequisite', 'related_to']);
|
| 382 |
+
neighbors.forEach(neighbor => {
|
| 383 |
+
queue.push([neighbor, distance + 1]);
|
| 384 |
+
});
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
return selected;
|
| 388 |
+
}
|
| 389 |
+
```
|
| 390 |
+
|
| 391 |
+
**Pros**:
|
| 392 |
+
- Semantically coherent
|
| 393 |
+
- Includes dependencies
|
| 394 |
+
- Useful for focused research
|
| 395 |
+
|
| 396 |
+
**Cons**:
|
| 397 |
+
- Requires knowledge graph
|
| 398 |
+
- May create echo chambers
|
| 399 |
+
- Complex to reason about
|
| 400 |
+
|
| 401 |
+
## World Configuration Schema
|
| 402 |
+
|
| 403 |
+
### Proposed Configuration Format
|
| 404 |
+
|
| 405 |
+
```yaml
|
| 406 |
+
world:
|
| 407 |
+
# Metadata
|
| 408 |
+
id: string
|
| 409 |
+
name: string
|
| 410 |
+
description: string
|
| 411 |
+
author: string
|
| 412 |
+
tags: string[]
|
| 413 |
+
|
| 414 |
+
# Capability Selection
|
| 415 |
+
capabilities:
|
| 416 |
+
# Option 1: Explicit list
|
| 417 |
+
explicit:
|
| 418 |
+
- order-fulfillment
|
| 419 |
+
- inventory-management
|
| 420 |
+
- cycle-counting
|
| 421 |
+
|
| 422 |
+
# Option 2: Filter-based
|
| 423 |
+
filters:
|
| 424 |
+
domains: [fulfillment, warehousing]
|
| 425 |
+
personas: [store-manager]
|
| 426 |
+
complexity: [simple, medium]
|
| 427 |
+
services: [erp, wms]
|
| 428 |
+
|
| 429 |
+
# Option 3: Sampling
|
| 430 |
+
sampling:
|
| 431 |
+
strategy: random | weighted | stratified | hierarchical | graph
|
| 432 |
+
count: 20
|
| 433 |
+
seed: "reproducible-123"
|
| 434 |
+
weights:
|
| 435 |
+
frequency: 0.5
|
| 436 |
+
complexity: 0.3
|
| 437 |
+
businessImpact: 0.2
|
| 438 |
+
|
| 439 |
+
# Dependency handling
|
| 440 |
+
autoIncludeDependencies: true
|
| 441 |
+
autoExcludeBlocked: true
|
| 442 |
+
|
| 443 |
+
# Chaos Configuration (per-world)
|
| 444 |
+
chaos:
|
| 445 |
+
enabled: true
|
| 446 |
+
globalProbability: 0.1
|
| 447 |
+
presets: [light-chaos]
|
| 448 |
+
overrides:
|
| 449 |
+
# Per-capability overrides
|
| 450 |
+
order-fulfillment:
|
| 451 |
+
probability: 0.3
|
| 452 |
+
|
| 453 |
+
# Resource Limits
|
| 454 |
+
limits:
|
| 455 |
+
maxConcurrentODs: 10
|
| 456 |
+
maxStepsPerOD: 50
|
| 457 |
+
timeoutMs: 30000
|
| 458 |
+
|
| 459 |
+
# Data Seeding
|
| 460 |
+
seed:
|
| 461 |
+
companies: 10
|
| 462 |
+
products: 100
|
| 463 |
+
initialOrders: 50
|
| 464 |
+
customSeed: "data-seed-123"
|
| 465 |
+
```
|
| 466 |
+
|
| 467 |
+
### Example Configurations
|
| 468 |
+
|
| 469 |
+
#### Example 1: Warehouse-Only World
|
| 470 |
+
```yaml
|
| 471 |
+
world:
|
| 472 |
+
name: "Warehouse Automation Research"
|
| 473 |
+
capabilities:
|
| 474 |
+
filters:
|
| 475 |
+
domains: [warehousing, inventory]
|
| 476 |
+
services: [wms]
|
| 477 |
+
autoIncludeDependencies: false
|
| 478 |
+
|
| 479 |
+
chaos:
|
| 480 |
+
enabled: true
|
| 481 |
+
globalProbability: 0.2
|
| 482 |
+
|
| 483 |
+
seed:
|
| 484 |
+
companies: 5
|
| 485 |
+
products: 50
|
| 486 |
+
```
|
| 487 |
+
|
| 488 |
+
#### Example 2: Progressive Learning World
|
| 489 |
+
```yaml
|
| 490 |
+
world:
|
| 491 |
+
name: "AI Agent Training - Progressive"
|
| 492 |
+
capabilities:
|
| 493 |
+
filters:
|
| 494 |
+
complexity: [simple] # Start with simple only
|
| 495 |
+
personas: [warehouse-worker]
|
| 496 |
+
# Later stages can be added dynamically
|
| 497 |
+
|
| 498 |
+
chaos:
|
| 499 |
+
enabled: false # No chaos during learning
|
| 500 |
+
|
| 501 |
+
seed:
|
| 502 |
+
companies: 3
|
| 503 |
+
products: 20
|
| 504 |
+
```
|
| 505 |
+
|
| 506 |
+
#### Example 3: Realistic Mix World
|
| 507 |
+
```yaml
|
| 508 |
+
world:
|
| 509 |
+
name: "Realistic Operations Simulation"
|
| 510 |
+
capabilities:
|
| 511 |
+
sampling:
|
| 512 |
+
strategy: weighted
|
| 513 |
+
count: 30
|
| 514 |
+
weights:
|
| 515 |
+
frequency: 0.7
|
| 516 |
+
businessImpact: 0.2
|
| 517 |
+
complexity: 0.1
|
| 518 |
+
|
| 519 |
+
chaos:
|
| 520 |
+
enabled: true
|
| 521 |
+
globalProbability: 0.05 # Light chaos
|
| 522 |
+
presets: [realistic-failures]
|
| 523 |
+
|
| 524 |
+
seed:
|
| 525 |
+
companies: 20
|
| 526 |
+
products: 200
|
| 527 |
+
initialOrders: 100
|
| 528 |
+
```
|
| 529 |
+
|
| 530 |
+
#### Example 4: Domain Exploration World
|
| 531 |
+
```yaml
|
| 532 |
+
world:
|
| 533 |
+
name: "Cross-Domain Integration Test"
|
| 534 |
+
capabilities:
|
| 535 |
+
sampling:
|
| 536 |
+
strategy: stratified
|
| 537 |
+
count: 25
|
| 538 |
+
stratifyBy: domain # Equal representation from each domain
|
| 539 |
+
|
| 540 |
+
chaos:
|
| 541 |
+
enabled: true
|
| 542 |
+
globalProbability: 0.15
|
| 543 |
+
|
| 544 |
+
seed:
|
| 545 |
+
companies: 10
|
| 546 |
+
products: 100
|
| 547 |
+
```
|
| 548 |
+
|
| 549 |
+
## Implementation Considerations
|
| 550 |
+
|
| 551 |
+
### 1. Capability Registry
|
| 552 |
+
|
| 553 |
+
Need a central registry that supports:
|
| 554 |
+
- Querying by tags/filters
|
| 555 |
+
- Counting capabilities matching criteria
|
| 556 |
+
- Sampling with various strategies
|
| 557 |
+
- Dependency resolution
|
| 558 |
+
|
| 559 |
+
**API Example**:
|
| 560 |
+
```typescript
|
| 561 |
+
interface CapabilityRegistry {
|
| 562 |
+
// Query
|
| 563 |
+
find(filters: Filters): Capability[];
|
| 564 |
+
count(filters: Filters): number;
|
| 565 |
+
|
| 566 |
+
// Sampling
|
| 567 |
+
sample(strategy: SamplingStrategy, config: SamplingConfig): Capability[];
|
| 568 |
+
|
| 569 |
+
// Dependencies
|
| 570 |
+
resolveDependencies(capabilities: Capability[]): Capability[];
|
| 571 |
+
validateDependencies(capabilities: Capability[]): ValidationResult;
|
| 572 |
+
}
|
| 573 |
+
```
|
| 574 |
+
|
| 575 |
+
### 2. World Lifecycle
|
| 576 |
+
|
| 577 |
+
**Creation**:
|
| 578 |
+
```
|
| 579 |
+
1. Parse world configuration
|
| 580 |
+
2. Resolve capability selection (filters/sampling)
|
| 581 |
+
3. Resolve dependencies
|
| 582 |
+
4. Validate configuration
|
| 583 |
+
5. Create world in database
|
| 584 |
+
6. Seed initial data
|
| 585 |
+
7. Return world ID
|
| 586 |
+
```
|
| 587 |
+
|
| 588 |
+
**Updates**:
|
| 589 |
+
```
|
| 590 |
+
1. Add/remove capabilities dynamically
|
| 591 |
+
2. Update chaos configuration
|
| 592 |
+
3. Adjust limits
|
| 593 |
+
4. Cannot change after ODs have executed (immutability)
|
| 594 |
+
```
|
| 595 |
+
|
| 596 |
+
**Deletion**:
|
| 597 |
+
```
|
| 598 |
+
1. Archive logs and results
|
| 599 |
+
2. Delete world data
|
| 600 |
+
3. Update registry
|
| 601 |
+
```
|
| 602 |
+
|
| 603 |
+
### 3. Configuration Validation
|
| 604 |
+
|
| 605 |
+
**Checks**:
|
| 606 |
+
- At least 1 capability selected
|
| 607 |
+
- All referenced capabilities exist
|
| 608 |
+
- Dependencies are satisfiable
|
| 609 |
+
- No circular dependencies
|
| 610 |
+
- Services required by capabilities are available
|
| 611 |
+
- Sampling count β€ total available capabilities
|
| 612 |
+
|
| 613 |
+
**Validation API**:
|
| 614 |
+
```typescript
|
| 615 |
+
interface ValidationResult {
|
| 616 |
+
valid: boolean;
|
| 617 |
+
errors: string[];
|
| 618 |
+
warnings: string[];
|
| 619 |
+
resolvedCapabilities: Capability[];
|
| 620 |
+
dependencyGraph: DependencyGraph;
|
| 621 |
+
}
|
| 622 |
+
```
|
| 623 |
+
|
| 624 |
+
### 4. Presets & Templates
|
| 625 |
+
|
| 626 |
+
Provide pre-configured world templates:
|
| 627 |
+
|
| 628 |
+
```yaml
|
| 629 |
+
presets:
|
| 630 |
+
- id: warehouse-basic
|
| 631 |
+
name: "Basic Warehouse Operations"
|
| 632 |
+
capabilities:
|
| 633 |
+
filters:
|
| 634 |
+
domains: [warehousing]
|
| 635 |
+
complexity: [simple]
|
| 636 |
+
|
| 637 |
+
- id: full-supply-chain
|
| 638 |
+
name: "End-to-End Supply Chain"
|
| 639 |
+
capabilities:
|
| 640 |
+
filters:
|
| 641 |
+
domains: [procurement, inventory, fulfillment, transportation]
|
| 642 |
+
|
| 643 |
+
- id: ai-training-starter
|
| 644 |
+
name: "AI Agent Training Starter Pack"
|
| 645 |
+
capabilities:
|
| 646 |
+
explicit:
|
| 647 |
+
- order-fulfillment-simple
|
| 648 |
+
- inventory-check
|
| 649 |
+
- shipment-tracking
|
| 650 |
+
```
|
| 651 |
+
|
| 652 |
+
## API Endpoints
|
| 653 |
+
|
| 654 |
+
### World Configuration API
|
| 655 |
+
|
| 656 |
+
```
|
| 657 |
+
POST /api/worlds # Create world with config
|
| 658 |
+
GET /api/worlds/:worldId # Get world details
|
| 659 |
+
PUT /api/worlds/:worldId # Update world config
|
| 660 |
+
DELETE /api/worlds/:worldId # Delete world
|
| 661 |
+
|
| 662 |
+
GET /api/worlds/:worldId/capabilities # List capabilities in this world
|
| 663 |
+
POST /api/worlds/:worldId/capabilities # Add capability to world
|
| 664 |
+
DELETE /api/worlds/:worldId/capabilities/:capId # Remove capability
|
| 665 |
+
|
| 666 |
+
POST /api/worlds/:worldId/sample # Resample capabilities
|
| 667 |
+
POST /api/worlds/:worldId/validate # Validate configuration
|
| 668 |
+
```
|
| 669 |
+
|
| 670 |
+
### Sampling API
|
| 671 |
+
|
| 672 |
+
```
|
| 673 |
+
POST /api/capabilities/sample # Sample capabilities (without creating world)
|
| 674 |
+
POST /api/capabilities/filter # Filter capabilities
|
| 675 |
+
GET /api/capabilities/count # Count capabilities matching criteria
|
| 676 |
+
```
|
| 677 |
+
|
| 678 |
+
### Preset API
|
| 679 |
+
|
| 680 |
+
```
|
| 681 |
+
GET /api/world-presets # List presets
|
| 682 |
+
GET /api/world-presets/:presetId # Get preset config
|
| 683 |
+
POST /api/world-presets/:presetId/instantiate # Create world from preset
|
| 684 |
+
```
|
| 685 |
+
|
| 686 |
+
## Open Questions
|
| 687 |
+
|
| 688 |
+
### 1. Static vs Dynamic Configuration
|
| 689 |
+
|
| 690 |
+
**Question**: Can world capabilities change after creation?
|
| 691 |
+
|
| 692 |
+
**Options**:
|
| 693 |
+
- **Static**: Configuration locked at creation (immutable)
|
| 694 |
+
- **Dynamic**: Capabilities can be added/removed during experiments
|
| 695 |
+
- **Staged**: Pre-defined stages that unlock over time
|
| 696 |
+
|
| 697 |
+
**Trade-offs**:
|
| 698 |
+
- Static: Reproducible, simple, but inflexible
|
| 699 |
+
- Dynamic: Flexible, but hard to reproduce
|
| 700 |
+
- Staged: Good for learning paths, but complex
|
| 701 |
+
|
| 702 |
+
**Recommendation Needed**: What's the priorityβreproducibility or flexibility?
|
| 703 |
+
|
| 704 |
+
### 2. Default Behavior
|
| 705 |
+
|
| 706 |
+
**Question**: If no capabilities specified, what happens?
|
| 707 |
+
|
| 708 |
+
**Options**:
|
| 709 |
+
- **All**: Include all capabilities (current behavior)
|
| 710 |
+
- **Error**: Require explicit configuration
|
| 711 |
+
- **Smart Default**: Sample 20 common capabilities
|
| 712 |
+
|
| 713 |
+
**Recommendation Needed**: What's the safest default?
|
| 714 |
+
|
| 715 |
+
### 3. Dependency Auto-Resolution
|
| 716 |
+
|
| 717 |
+
**Question**: Should dependencies be automatically included?
|
| 718 |
+
|
| 719 |
+
**Scenario**: Researcher selects "Order Fulfillment" but not "Inventory Check" (prerequisite)
|
| 720 |
+
|
| 721 |
+
**Options**:
|
| 722 |
+
- **Auto-Include**: Silently add dependencies (convenient but surprising)
|
| 723 |
+
- **Warn**: Show warning but allow (flexible but risky)
|
| 724 |
+
- **Error**: Reject invalid configuration (strict but safe)
|
| 725 |
+
|
| 726 |
+
**Recommendation Needed**: What behavior is least surprising?
|
| 727 |
+
|
| 728 |
+
### 4. Sampling Determinism
|
| 729 |
+
|
| 730 |
+
**Question**: Should sampling be deterministic?
|
| 731 |
+
|
| 732 |
+
**Options**:
|
| 733 |
+
- **Always Seeded**: Require seed for reproducibility
|
| 734 |
+
- **Optional Seed**: Allow non-deterministic sampling
|
| 735 |
+
- **Hybrid**: Default seed + override option
|
| 736 |
+
|
| 737 |
+
**Recommendation Needed**: How important is experiment reproducibility?
|
| 738 |
+
|
| 739 |
+
## Next Steps
|
| 740 |
+
|
| 741 |
+
1. **Choose default sampling strategy** for most common use cases
|
| 742 |
+
2. **Define world configuration schema** formally (JSON Schema/Zod)
|
| 743 |
+
3. **Build capability registry** with filtering and sampling
|
| 744 |
+
4. **Implement dependency resolution** using knowledge graph
|
| 745 |
+
5. **Create 5-10 world presets** for common scenarios
|
| 746 |
+
6. **Build world configuration API** endpoints
|
| 747 |
+
7. **Test with realistic scenarios** and iterate
|
| 748 |
+
|
| 749 |
+
## Related Documents
|
| 750 |
+
|
| 751 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - Capability definitions
|
| 752 |
+
- [03. Knowledge Graph](./03-knowledge-graph.md) - Dependency modeling
|
| 753 |
+
- [04. Taxonomy & Organization](./04-taxonomy-organization.md) - Filtering strategies
|
| 754 |
+
- [06. Open Questions](./06-open-questions.md) - Unresolved decisions
|
docs/od-architecture/06-open-questions.md
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 06. Open Questions & Decisions
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This document consolidates all design questions from the OD architecture discussion, tracking both decisions made and questions still pending.
|
| 6 |
+
|
| 7 |
+
**Last Updated**: 2025-11-14
|
| 8 |
+
|
| 9 |
+
## Decision Summary
|
| 10 |
+
|
| 11 |
+
| ID | Question | Status | Decision |
|
| 12 |
+
|----|----------|--------|----------|
|
| 13 |
+
| **Priority 1: Critical** |
|
| 14 |
+
| Q1.1 | Capability Definition | β
**DECIDED** | Semantic Grouping / Domain Process (~50 capabilities) |
|
| 15 |
+
| Q1.2 | Capability β OD Relationship | β
**DECIDED** | 1:N Variants |
|
| 16 |
+
| Q1.3 | Knowledge Graph Approach | β
**DECIDED** | Hybrid (Manual β Static β Runtime, phased) |
|
| 17 |
+
| Q1.4 | Primary Taxonomy | β
**DECIDED** | Multi-dimensional tags, domain-based default |
|
| 18 |
+
| **Priority 2: Important** |
|
| 19 |
+
| Q2.1 | Persona Granularity | β
**DECIDED** | Detailed (20-50 personas) |
|
| 20 |
+
| Q2.2 | Persona-Capability Config | β
**DECIDED** | Hybrid (defaults + world overrides) |
|
| 21 |
+
| Q2.3 | Hierarchy vs Flat | β
**DECIDED** | Flat with tags (add hierarchy later if needed) |
|
| 22 |
+
| Q2.4 | Data Flow Inference | β
**DECIDED** | Manual annotations + runtime validation |
|
| 23 |
+
| Q2.5 | Graph Technology | β
**DECIDED** | In-memory (graphlib) + MongoDB persistence |
|
| 24 |
+
| **Priority 3: Nice-to-Have** |
|
| 25 |
+
| Q3.1 | Tag Vocabulary | π‘ RECOMMENDED | Hybrid (core controlled + custom allowed) |
|
| 26 |
+
| Q3.2 | Taxonomy Maintenance | π‘ RECOMMENDED | Hybrid (system baseline + manual curation) |
|
| 27 |
+
| Q3.3 | Graph Update Frequency | π‘ RECOMMENDED | Startup + manual refresh |
|
| 28 |
+
| Q3.4 | World Mutability | π‘ RECOMMENDED | Static (locked at creation for reproducibility) |
|
| 29 |
+
| Q3.5 | Default World Behavior | π‘ RECOMMENDED | Error (require explicit configuration) |
|
| 30 |
+
| Q3.6 | Dependency Auto-Resolution | π‘ RECOMMENDED | Warn (show warning but allow) |
|
| 31 |
+
| Q3.7 | Sampling Determinism | π‘ RECOMMENDED | Hybrid (default seed + override) |
|
| 32 |
+
|
| 33 |
+
## Priority 1: Critical Decisions (Block Implementation)
|
| 34 |
+
|
| 35 |
+
These questions must be answered first, as they fundamentally shape the architecture.
|
| 36 |
+
|
| 37 |
+
### Q1.1: Capability Definition
|
| 38 |
+
|
| 39 |
+
> **β
DECISION** (2025-11-14)
|
| 40 |
+
> **Chosen**: **Option D + C**: Semantic Grouping with Domain Process characteristics (~50 capabilities)
|
| 41 |
+
> **Rationale**: Capabilities should be actionable business processes that AI agents can perform end-to-end. Not too broad ("Order Management" contains too many distinct workflows), not too granular ("Click button to create order" is too atomic). Examples: "Fulfill Customer Order", "Receive Inbound Shipment", "Cycle Count Inventory".
|
| 42 |
+
> **Implementation**: Start with ~30-40 capabilities, grow to 50-60 as needed. Each capability maps to 1-N OD variants.
|
| 43 |
+
|
| 44 |
+
**Question**: What exactly is a capability?
|
| 45 |
+
|
| 46 |
+
**Context**: Need clear definition to design the entire system.
|
| 47 |
+
|
| 48 |
+
**Options**:
|
| 49 |
+
- **A. Business Function**: High-level processes ("Order Management", "Inventory Control")
|
| 50 |
+
- **B. User Story**: Goal-oriented tasks ("As a store manager, I want to fulfill an order")
|
| 51 |
+
- **C. Domain Process**: Technical workflows ("Inbound Receiving Flow", "Pick-Pack-Ship Process")
|
| 52 |
+
- **D. Semantic Grouping**: Logical grouping of related ODs
|
| 53 |
+
|
| 54 |
+
**Trade-offs**:
|
| 55 |
+
| Option | Granularity | User-Friendly | Technical Clarity | Count |
|
| 56 |
+
|--------|-------------|---------------|-------------------|-------|
|
| 57 |
+
| A | Coarse | High | Low | ~20 |
|
| 58 |
+
| B | Fine | Very High | Medium | ~100+ |
|
| 59 |
+
| C | Medium | Medium | High | ~50 |
|
| 60 |
+
| D | Variable | Medium | Medium | ~30-60 |
|
| 61 |
+
|
| 62 |
+
**Impact**: Affects taxonomy, knowledge graph, UI design, and tagging strategy.
|
| 63 |
+
|
| 64 |
+
**Recommendation Needed**: Which best serves AI researchers?
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
### Q1.2: Capability β OD Relationship
|
| 69 |
+
|
| 70 |
+
> **β
DECISION** (2025-11-14)
|
| 71 |
+
> **Chosen**: **Option B**: 1:N Mapping (Variants)
|
| 72 |
+
> **Rationale**: One capability can have multiple OD implementations (variants) for different scenarios. Examples: "Order Fulfillment - Standard", "Order Fulfillment - Express", "Order Fulfillment - International". This provides flexibility for researchers to choose complexity level and optimization targets (speed vs accuracy). Also enables low-chaos vs high-chaos variants of the same capability. Can add N:M composition in future if needed.
|
| 73 |
+
> **Implementation**: Capability β OD[] mapping in registry. Variant selection via tags (complexity, speed, chaos-level).
|
| 74 |
+
|
| 75 |
+
**Question**: Can one capability have multiple OD implementations?
|
| 76 |
+
|
| 77 |
+
**Context**: Determines flexibility vs simplicity trade-off.
|
| 78 |
+
|
| 79 |
+
**Options**:
|
| 80 |
+
- **A. 1:1 Mapping**: One capability = exactly one OD
|
| 81 |
+
- **B. 1:N Mapping (Variants)**: One capability = multiple OD variants (standard, express, complex)
|
| 82 |
+
- **C. N:M Mapping (Composition)**: Capabilities can share ODs, ODs can compose
|
| 83 |
+
|
| 84 |
+
**Examples**:
|
| 85 |
+
```
|
| 86 |
+
Option A (1:1):
|
| 87 |
+
Capability "Order Fulfillment" β OD "order-fulfillment-v1"
|
| 88 |
+
|
| 89 |
+
Option B (1:N):
|
| 90 |
+
Capability "Order Fulfillment" β [
|
| 91 |
+
OD "order-fulfillment-standard",
|
| 92 |
+
OD "order-fulfillment-express",
|
| 93 |
+
OD "order-fulfillment-international"
|
| 94 |
+
]
|
| 95 |
+
|
| 96 |
+
Option C (N:M):
|
| 97 |
+
Capability "Order Fulfillment" β OD "order-fulfillment"
|
| 98 |
+
Capability "Inventory Check" β OD "inventory-check"
|
| 99 |
+
OD "order-fulfillment" uses OD "inventory-check" (sub-workflow)
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
**Trade-offs**:
|
| 103 |
+
- A: Simplest, but inflexible
|
| 104 |
+
- B: Good balance, clear variants
|
| 105 |
+
- C: Most flexible, but most complex
|
| 106 |
+
|
| 107 |
+
**Impact**: Registry design, variant selection logic, OD composition patterns.
|
| 108 |
+
|
| 109 |
+
**Recommendation Needed**: What level of flexibility is required?
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
### Q1.3: Knowledge Graph Implementation Approach
|
| 114 |
+
|
| 115 |
+
> **β
DECISION** (2025-11-14)
|
| 116 |
+
> **Chosen**: **Hybrid - Phased Approach**: Start with Option D (Manual), evolve to Option C (Hybrid)
|
| 117 |
+
> **Rationale**:
|
| 118 |
+
> - **Phase 1 (MVP)**: Manual annotations in tool definitions (`@produces Order`, `@requires Customer, Product`) - Fast to implement, high quality
|
| 119 |
+
> - **Phase 2**: Static analysis to extract and validate annotations using TypeScript compiler API
|
| 120 |
+
> - **Phase 3**: Runtime learning to refine edge weights and discover implicit patterns
|
| 121 |
+
> **Implementation**: Build graph structure now, populate incrementally. Start with manual annotations for critical tools, expand coverage over time.
|
| 122 |
+
|
| 123 |
+
**Question**: How should the knowledge graph be built?
|
| 124 |
+
|
| 125 |
+
**Context**: Affects development timeline and capabilities.
|
| 126 |
+
|
| 127 |
+
**Options**:
|
| 128 |
+
- **A. Static Analysis** (Build time): Parse code, generate graph from types/schemas
|
| 129 |
+
- **B. Dynamic Learning** (Runtime): Learn from OD executions, infer relationships
|
| 130 |
+
- **C. Hybrid**: Static baseline + runtime refinement
|
| 131 |
+
- **D. Manual Annotation**: Developers explicitly specify relationships
|
| 132 |
+
|
| 133 |
+
**Trade-offs**:
|
| 134 |
+
| Option | Effort | Accuracy | Maintenance | Bootstrap Time |
|
| 135 |
+
|--------|--------|----------|-------------|----------------|
|
| 136 |
+
| A | Medium | Medium | Low | Fast |
|
| 137 |
+
| B | High | High | Low | Slow |
|
| 138 |
+
| C | High | Very High | Medium | Medium |
|
| 139 |
+
| D | Low | High | High | Fast |
|
| 140 |
+
|
| 141 |
+
**Impact**: Development time, graph quality, maintenance burden.
|
| 142 |
+
|
| 143 |
+
**Recommendation Needed**: What's feasible for initial version?
|
| 144 |
+
|
| 145 |
+
---
|
| 146 |
+
|
| 147 |
+
### Q1.4: Primary Taxonomy
|
| 148 |
+
|
| 149 |
+
> **β
DECISION** (2025-11-14)
|
| 150 |
+
> **Chosen**: **Option D**: Multi-Dimensional Tags with **Domain-Based Default View**
|
| 151 |
+
> **Rationale**: Different researchers have different mental models. Tags support all browsing patterns without forcing a single hierarchy. Default to domain-based view (Fulfillment, Inventory, Transportation) as it matches business language, but also offer persona view and complexity view.
|
| 152 |
+
> **Implementation**: Every capability gets comprehensive tags: `{domain: [], persona: [], complexity: "", services: [], pattern: []}`. API supports filtering by any tag combination. UI offers 3 primary views: Domain (default), Persona, Complexity.
|
| 153 |
+
> **Example**: `/api/capabilities?domain=fulfillment`, `/api/capabilities?persona=store-manager`, `/api/capabilities?complexity=simple`
|
| 154 |
+
|
| 155 |
+
**Question**: What should be the default organization scheme?
|
| 156 |
+
|
| 157 |
+
**Context**: Determines how researchers browse and discover capabilities.
|
| 158 |
+
|
| 159 |
+
**Options**:
|
| 160 |
+
- **A. Domain-Based**: Organize by business domain (Fulfillment, Inventory, Transportation)
|
| 161 |
+
- **B. Persona-Based**: Organize by role (Store Manager, Warehouse Worker)
|
| 162 |
+
- **C. Complexity-Based**: Organize by difficulty (Simple, Medium, Complex)
|
| 163 |
+
- **D. Multi-Dimensional Tags**: No primary taxonomy, support all views
|
| 164 |
+
|
| 165 |
+
**Trade-offs**:
|
| 166 |
+
| Option | Intuitive | Flexible | Maintenance | Use Case |
|
| 167 |
+
|--------|-----------|----------|-------------|----------|
|
| 168 |
+
| A | High | Low | Low | Business-oriented research |
|
| 169 |
+
| B | Medium | Medium | Medium | Role-based training |
|
| 170 |
+
| C | Medium | Low | Low | Progressive learning |
|
| 171 |
+
| D | Low | Very High | High | Expert users |
|
| 172 |
+
|
| 173 |
+
**Impact**: UI design, browsing patterns, filtering logic.
|
| 174 |
+
|
| 175 |
+
**Recommendation Needed**: What's most intuitive for AI researchers?
|
| 176 |
+
|
| 177 |
+
---
|
| 178 |
+
|
| 179 |
+
## Priority 2: Important Design Choices
|
| 180 |
+
|
| 181 |
+
These affect implementation details but can be iterated on.
|
| 182 |
+
|
| 183 |
+
### Q2.1: Persona Granularity
|
| 184 |
+
|
| 185 |
+
> **β
DECISION** (2025-11-14)
|
| 186 |
+
> **Chosen**: **Option B**: Detailed (20-50 personas)
|
| 187 |
+
> **Rationale**: Broad personas (5-10) are too coarse - "Manager" doesn't convey specific responsibilities. Functional personas (50+) are overkill and hard to maintain. Sweet spot: Role-specific but not task-specific. Examples: Store Manager, Warehouse Manager, DC Manager (different management roles); Receiving Clerk, Shipping Clerk, Inventory Specialist (different operational functions).
|
| 188 |
+
> **Implementation**: Start with 15-20 core personas, expand to 30-40 as use cases emerge. Not: "Morning Shift Receiving Clerk" (too granular).
|
| 189 |
+
|
| 190 |
+
**Question**: How detailed should personas be?
|
| 191 |
+
|
| 192 |
+
**Options**:
|
| 193 |
+
- **A. Broad** (5-10 personas): Manager, Worker, Coordinator, Analyst, Bot
|
| 194 |
+
- **B. Detailed** (20-50 personas): Store Manager, DC Manager, Warehouse Manager, Receiving Clerk, etc.
|
| 195 |
+
- **C. Functional** (50+ personas): Very specific roles for each function
|
| 196 |
+
|
| 197 |
+
**Trade-offs**:
|
| 198 |
+
- A: Simple to manage, coarse permissions
|
| 199 |
+
- B: Balance of specificity and manageability
|
| 200 |
+
- C: Highly realistic, complex to maintain
|
| 201 |
+
|
| 202 |
+
**Impact**: Permission model, world configuration complexity.
|
| 203 |
+
|
| 204 |
+
**Recommendation Needed**: What level matches research needs?
|
| 205 |
+
|
| 206 |
+
---
|
| 207 |
+
|
| 208 |
+
### Q2.2: Persona β Capability Configuration
|
| 209 |
+
|
| 210 |
+
> **β
DECISION** (2025-11-14)
|
| 211 |
+
> **Chosen**: **Option C**: Hybrid (Defaults in config, overridable per world)
|
| 212 |
+
> **Rationale**: Standard persona-capability mappings should be in version-controlled config (stable, predictable). But researchers need ability to create custom personas or restrict capabilities for experiments. Solution: Default mappings work out-of-box, but worlds can override with custom personas.
|
| 213 |
+
> **Implementation**: Default mappings in `config/personas.json`. World config can add `personaOverrides: { "custom-agent": { capabilities: [...] } }`.
|
| 214 |
+
|
| 215 |
+
**Question**: Should persona-capability mappings be configurable?
|
| 216 |
+
|
| 217 |
+
**Options**:
|
| 218 |
+
- **A. Static**: Hardcoded in config files, version controlled
|
| 219 |
+
- **B. Dynamic**: Stored in database, editable via API
|
| 220 |
+
- **C. Hybrid**: Defaults in config, overridable per world
|
| 221 |
+
|
| 222 |
+
**Use Cases**:
|
| 223 |
+
- Custom personas for specific experiments
|
| 224 |
+
- Restrict capabilities for testing
|
| 225 |
+
- Evolve personas without code changes
|
| 226 |
+
|
| 227 |
+
**Impact**: Flexibility, complexity, reproducibility.
|
| 228 |
+
|
| 229 |
+
**Recommendation Needed**: How important is runtime configurability?
|
| 230 |
+
|
| 231 |
+
---
|
| 232 |
+
|
| 233 |
+
### Q2.3: Hierarchy vs Flat Capabilities
|
| 234 |
+
|
| 235 |
+
> **β
DECISION** (2025-11-14)
|
| 236 |
+
> **Chosen**: **Flat with tags** (add hierarchy later if needed)
|
| 237 |
+
> **Rationale**: With ~50 capabilities, flat structure is manageable. Tags provide "virtual hierarchy": filtering by `domain:fulfillment` shows all fulfillment capabilities. Simpler to implement and reason about. Can add optional parent/child relationships later if catalog grows to 100+ capabilities.
|
| 238 |
+
> **Implementation**: No parent/child fields. Use tags for grouping: `tags: { domain: ["fulfillment"], category: ["order-processing"] }`.
|
| 239 |
+
|
| 240 |
+
**Question**: Should capabilities have hierarchical structure?
|
| 241 |
+
|
| 242 |
+
**Examples**:
|
| 243 |
+
```
|
| 244 |
+
Hierarchical:
|
| 245 |
+
Order Management (parent)
|
| 246 |
+
βββ Create Order
|
| 247 |
+
βββ Fulfill Order
|
| 248 |
+
βββ Cancel Order
|
| 249 |
+
βββ Track Order
|
| 250 |
+
|
| 251 |
+
Flat:
|
| 252 |
+
- Create Order
|
| 253 |
+
- Fulfill Order
|
| 254 |
+
- Cancel Order
|
| 255 |
+
- Track Order
|
| 256 |
+
```
|
| 257 |
+
|
| 258 |
+
**Trade-offs**:
|
| 259 |
+
- Hierarchical: Better organization, more complex
|
| 260 |
+
- Flat: Simpler, but harder to navigate large catalogs
|
| 261 |
+
|
| 262 |
+
**Impact**: UI complexity, filtering logic, tagging strategy.
|
| 263 |
+
|
| 264 |
+
**Recommendation Needed**: Is flat sufficient or do we need hierarchy?
|
| 265 |
+
|
| 266 |
+
---
|
| 267 |
+
|
| 268 |
+
### Q2.4: Data Flow Inference Method
|
| 269 |
+
|
| 270 |
+
> **β
DECISION** (2025-11-14)
|
| 271 |
+
> **Chosen**: **Option D**: Hybrid (Manual annotations + runtime validation)
|
| 272 |
+
> **Rationale**: Phase 1: Add manual annotations to tool definitions (`produces: ["Order"], requires: ["Customer", "Product"]`). Fast to implement, high quality. Phase 2: Runtime tracking validates annotations and discovers edge cases. Best of both worlds.
|
| 273 |
+
> **Implementation**: Add metadata fields to service tool definitions. Start with critical tools, expand coverage incrementally. Runtime logs can validate/suggest annotations.
|
| 274 |
+
|
| 275 |
+
**Question**: How do we determine which entities a tool produces/requires?
|
| 276 |
+
|
| 277 |
+
**Context**: Needed for knowledge graph and OD validation.
|
| 278 |
+
|
| 279 |
+
**Options**:
|
| 280 |
+
- **A. Manual Annotation**: Developers add metadata (e.g., `@produces Order`)
|
| 281 |
+
- **B. Schema Analysis**: Infer from TypeScript types and input/output schemas
|
| 282 |
+
- **C. Runtime Learning**: Monitor executions, track data flow
|
| 283 |
+
- **D. Hybrid**: Start with annotations, refine with runtime data
|
| 284 |
+
|
| 285 |
+
**Feasibility**:
|
| 286 |
+
- A: Immediate, but manual effort
|
| 287 |
+
- B: Possible with TypeScript compiler API, may be incomplete
|
| 288 |
+
- C: Accurate but slow to bootstrap
|
| 289 |
+
- D: Best of both worlds, more complex
|
| 290 |
+
|
| 291 |
+
**Impact**: Graph quality, validation accuracy, developer burden.
|
| 292 |
+
|
| 293 |
+
**Recommendation Needed**: What's most practical?
|
| 294 |
+
|
| 295 |
+
---
|
| 296 |
+
|
| 297 |
+
### Q2.5: Graph Technology Choice
|
| 298 |
+
|
| 299 |
+
> **β
DECISION** (2025-11-14)
|
| 300 |
+
> **Chosen**: **Option D**: In-memory (graphlib) + MongoDB persistence
|
| 301 |
+
> **Rationale**: Use in-memory graph library (graphlib) for fast queries. Persist graph structure to MongoDB (already in stack). Load graph on startup. No new infrastructure (Neo4j). Can migrate to dedicated graph DB later if query complexity demands it.
|
| 302 |
+
> **Implementation**: `Graph` class using graphlib. Store nodes/edges in MongoDB collections. Load on service startup: `graph.loadFromMongoDB()`. Update and persist as needed.
|
| 303 |
+
|
| 304 |
+
**Question**: What technology should power the knowledge graph?
|
| 305 |
+
|
| 306 |
+
**Options**:
|
| 307 |
+
- **A. In-Memory (graphlib, cytoscape.js)**: Simple, fast, not persistent
|
| 308 |
+
- **B. Graph Database (Neo4j, ArangoDB)**: Purpose-built, powerful queries, infrastructure
|
| 309 |
+
- **C. MongoDB**: Already using it, not optimized for graphs
|
| 310 |
+
- **D. Hybrid**: In-memory + MongoDB persistence
|
| 311 |
+
|
| 312 |
+
**Trade-offs**:
|
| 313 |
+
| Option | Setup | Performance | Persistence | Query Power |
|
| 314 |
+
|--------|-------|-------------|-------------|-------------|
|
| 315 |
+
| A | Easy | Fast | No | Basic |
|
| 316 |
+
| B | Hard | Fast | Yes | Excellent |
|
| 317 |
+
| C | Easy | Slow | Yes | Limited |
|
| 318 |
+
| D | Medium | Fast | Yes | Medium |
|
| 319 |
+
|
| 320 |
+
**Impact**: Infrastructure complexity, query capabilities, scalability.
|
| 321 |
+
|
| 322 |
+
**Recommendation Needed**: What fits the architecture best?
|
| 323 |
+
|
| 324 |
+
---
|
| 325 |
+
|
| 326 |
+
## Priority 3: Nice-to-Have Features
|
| 327 |
+
|
| 328 |
+
These can be deferred to later phases. **RECOMMENDED** options provided below can be finalized during implementation.
|
| 329 |
+
|
| 330 |
+
### Q3.1: Tag Vocabulary Control
|
| 331 |
+
|
| 332 |
+
> **π‘ RECOMMENDED**: **Option C**: Hybrid (Core tags controlled, custom tags allowed)
|
| 333 |
+
> Core tags (domain, persona, complexity, services) use controlled vocabulary. Custom tags allowed for experimental/research-specific categorization.
|
| 334 |
+
|
| 335 |
+
**Question**: Should tag values be freeform or controlled?
|
| 336 |
+
|
| 337 |
+
**Options**:
|
| 338 |
+
- **A. Freeform**: Authors can add any tags (flexible, inconsistent)
|
| 339 |
+
- **B. Controlled**: Pre-defined tag vocabulary (consistent, rigid)
|
| 340 |
+
- **C. Hybrid**: Core tags controlled, custom tags allowed
|
| 341 |
+
|
| 342 |
+
**Impact**: Tag consistency, search quality, maintenance.
|
| 343 |
+
|
| 344 |
+
---
|
| 345 |
+
|
| 346 |
+
### Q3.2: Taxonomy Maintenance
|
| 347 |
+
|
| 348 |
+
> **π‘ RECOMMENDED**: **Option D**: Hybrid (System baseline + manual curation)
|
| 349 |
+
> System generates initial tags from code structure. Team manually curates and refines. Sustainable long-term.
|
| 350 |
+
|
| 351 |
+
**Question**: Who maintains the taxonomy and tags?
|
| 352 |
+
|
| 353 |
+
**Options**:
|
| 354 |
+
- **A. System**: Auto-generated from code
|
| 355 |
+
- **B. Manual**: Curated by team
|
| 356 |
+
- **C. Community**: Researchers contribute
|
| 357 |
+
- **D. Hybrid**: System baseline + manual curation
|
| 358 |
+
|
| 359 |
+
**Impact**: Accuracy, freshness, maintenance burden.
|
| 360 |
+
|
| 361 |
+
---
|
| 362 |
+
|
| 363 |
+
### Q3.3: Graph Update Frequency
|
| 364 |
+
|
| 365 |
+
> **π‘ RECOMMENDED**: **Option B**: Startup (+ manual refresh capability)
|
| 366 |
+
> Load graph on service startup. Provide manual refresh endpoint for updates without restart.
|
| 367 |
+
|
| 368 |
+
**Question**: When does the knowledge graph get updated?
|
| 369 |
+
|
| 370 |
+
**Options**:
|
| 371 |
+
- **A. Build Time**: Regenerated on deployment
|
| 372 |
+
- **B. Startup**: Built when service starts
|
| 373 |
+
- **C. Runtime**: Updated as ODs execute
|
| 374 |
+
- **D. Manual**: Explicit refresh command
|
| 375 |
+
|
| 376 |
+
**Impact**: Graph freshness, performance, complexity.
|
| 377 |
+
|
| 378 |
+
---
|
| 379 |
+
|
| 380 |
+
### Q3.4: World Configuration Mutability
|
| 381 |
+
|
| 382 |
+
> **π‘ RECOMMENDED**: **Option A**: Static (locked at creation)
|
| 383 |
+
> World configuration locked at creation for reproducibility. Create new world for different configuration.
|
| 384 |
+
|
| 385 |
+
**Question**: Can world capabilities change after creation?
|
| 386 |
+
|
| 387 |
+
**Options**:
|
| 388 |
+
- **A. Static**: Configuration locked at creation (reproducible, inflexible)
|
| 389 |
+
- **B. Dynamic**: Capabilities can be added/removed (flexible, hard to reproduce)
|
| 390 |
+
- **C. Staged**: Pre-defined stages that unlock over time (good for learning, complex)
|
| 391 |
+
|
| 392 |
+
**Impact**: Reproducibility, flexibility, complexity.
|
| 393 |
+
|
| 394 |
+
---
|
| 395 |
+
|
| 396 |
+
### Q3.5: Default World Behavior
|
| 397 |
+
|
| 398 |
+
> **π‘ RECOMMENDED**: **Option B**: Error (require explicit configuration)
|
| 399 |
+
> Fail fast if no capabilities specified. Forces researchers to think about world configuration.
|
| 400 |
+
|
| 401 |
+
**Question**: If no capabilities specified, what happens?
|
| 402 |
+
|
| 403 |
+
**Options**:
|
| 404 |
+
- **A. All**: Include all capabilities (current behavior)
|
| 405 |
+
- **B. Error**: Require explicit configuration (safe, strict)
|
| 406 |
+
- **C. Smart Default**: Sample 20 common capabilities (convenient, opinionated)
|
| 407 |
+
|
| 408 |
+
**Impact**: User experience, safety, defaults.
|
| 409 |
+
|
| 410 |
+
---
|
| 411 |
+
|
| 412 |
+
### Q3.6: Dependency Auto-Resolution
|
| 413 |
+
|
| 414 |
+
> **π‘ RECOMMENDED**: **Option B**: Warn (show warning but allow)
|
| 415 |
+
> Show clear warning message listing missing dependencies, but allow configuration. Researcher makes informed choice.
|
| 416 |
+
|
| 417 |
+
**Question**: Should dependencies be automatically included?
|
| 418 |
+
|
| 419 |
+
**Scenario**: Researcher selects "Order Fulfillment" but not "Inventory Check" (prerequisite)
|
| 420 |
+
|
| 421 |
+
**Options**:
|
| 422 |
+
- **A. Auto-Include**: Silently add dependencies (convenient, surprising)
|
| 423 |
+
- **B. Warn**: Show warning but allow (flexible, risky)
|
| 424 |
+
- **C. Error**: Reject invalid configuration (strict, safe)
|
| 425 |
+
|
| 426 |
+
**Impact**: User experience, safety, complexity.
|
| 427 |
+
|
| 428 |
+
---
|
| 429 |
+
|
| 430 |
+
### Q3.7: Sampling Determinism
|
| 431 |
+
|
| 432 |
+
> **π‘ RECOMMENDED**: **Option C**: Hybrid (default seed + override)
|
| 433 |
+
> Auto-generate seed (timestamp-based) for reproducibility. Allow explicit seed override for exact replication.
|
| 434 |
+
|
| 435 |
+
**Question**: Should sampling always be deterministic?
|
| 436 |
+
|
| 437 |
+
**Options**:
|
| 438 |
+
- **A. Always Seeded**: Require seed for reproducibility (reproducible, less convenient)
|
| 439 |
+
- **B. Optional Seed**: Allow non-deterministic sampling (flexible, hard to reproduce)
|
| 440 |
+
- **C. Hybrid**: Default seed + override option (balanced)
|
| 441 |
+
|
| 442 |
+
**Impact**: Experiment reproducibility, user experience.
|
| 443 |
+
|
| 444 |
+
---
|
| 445 |
+
|
| 446 |
+
## Decision-Making Framework
|
| 447 |
+
|
| 448 |
+
### How to Prioritize
|
| 449 |
+
|
| 450 |
+
**Criteria**:
|
| 451 |
+
1. **Blocking**: Does this block other work?
|
| 452 |
+
2. **Impact**: How many components are affected?
|
| 453 |
+
3. **Reversibility**: Can we change this decision later?
|
| 454 |
+
4. **Effort**: How much work to implement each option?
|
| 455 |
+
|
| 456 |
+
**Suggested Process**:
|
| 457 |
+
1. Answer all Priority 1 questions first
|
| 458 |
+
2. Build proof-of-concept based on Priority 1 answers
|
| 459 |
+
3. Test POC with realistic scenarios
|
| 460 |
+
4. Answer Priority 2 questions based on learnings
|
| 461 |
+
5. Defer Priority 3 questions to later phases
|
| 462 |
+
|
| 463 |
+
### Decision Log Template
|
| 464 |
+
|
| 465 |
+
For each question, document:
|
| 466 |
+
```markdown
|
| 467 |
+
## Decision: [Question Number]
|
| 468 |
+
|
| 469 |
+
**Date**: YYYY-MM-DD
|
| 470 |
+
**Decided By**: [Name/Team]
|
| 471 |
+
**Chosen Option**: [A/B/C/D]
|
| 472 |
+
|
| 473 |
+
**Rationale**:
|
| 474 |
+
- Why this option was chosen
|
| 475 |
+
- Key trade-offs considered
|
| 476 |
+
- Alternative options rejected and why
|
| 477 |
+
|
| 478 |
+
**Impact**:
|
| 479 |
+
- What changes in implementation
|
| 480 |
+
- Dependencies on other decisions
|
| 481 |
+
- Timeline impact
|
| 482 |
+
|
| 483 |
+
**Revisit Date**: YYYY-MM-DD (if needed)
|
| 484 |
+
```
|
| 485 |
+
|
| 486 |
+
## Next Steps
|
| 487 |
+
|
| 488 |
+
β
**Completed**:
|
| 489 |
+
1. All Priority 1 (critical) questions decided
|
| 490 |
+
2. All Priority 2 (important) questions decided
|
| 491 |
+
3. Priority 3 (nice-to-have) recommendations provided
|
| 492 |
+
|
| 493 |
+
**Now Ready For**:
|
| 494 |
+
1. **Create implementation roadmap** based on decisions
|
| 495 |
+
2. **Build proof-of-concept** for:
|
| 496 |
+
- Capability registry with multi-dimensional tags
|
| 497 |
+
- Knowledge graph (in-memory + MongoDB)
|
| 498 |
+
- OD variant system (1:N mapping)
|
| 499 |
+
- Manual tool annotations (produces/requires)
|
| 500 |
+
3. **Define initial capability catalog** (~30-40 capabilities)
|
| 501 |
+
4. **Define persona catalog** (~15-20 personas)
|
| 502 |
+
5. **Start Phase 1 implementation** (see implementation plan TBD)
|
| 503 |
+
|
| 504 |
+
## Related Documents
|
| 505 |
+
|
| 506 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - Questions about capability/persona/OD definitions
|
| 507 |
+
- [03. Knowledge Graph](./03-knowledge-graph.md) - Questions about graph implementation
|
| 508 |
+
- [04. Taxonomy & Organization](./04-taxonomy-organization.md) - Questions about categorization
|
| 509 |
+
- [05. Sampling & World Config](./05-sampling-world-config.md) - Questions about world configuration
|
| 510 |
+
|
| 511 |
+
---
|
| 512 |
+
|
| 513 |
+
## Summary
|
| 514 |
+
|
| 515 |
+
**Status**: β
All critical and important questions decided (2025-11-14)
|
| 516 |
+
|
| 517 |
+
**Priority 1 (Critical)**: 4/4 **DECIDED** β
|
| 518 |
+
- Capability definition β Semantic Grouping / Domain Process (~50 capabilities)
|
| 519 |
+
- Capability β OD relationship β 1:N Variants
|
| 520 |
+
- Knowledge graph approach β Hybrid (Manual β Static β Runtime phased)
|
| 521 |
+
- Primary taxonomy β Multi-dimensional tags, domain-based default
|
| 522 |
+
|
| 523 |
+
**Priority 2 (Important)**: 5/5 **DECIDED** β
|
| 524 |
+
- Persona granularity β Detailed (20-50 personas)
|
| 525 |
+
- Persona-capability configuration β Hybrid (defaults + world overrides)
|
| 526 |
+
- Hierarchy vs flat β Flat with tags
|
| 527 |
+
- Data flow inference β Manual annotations + runtime validation
|
| 528 |
+
- Graph technology β In-memory (graphlib) + MongoDB
|
| 529 |
+
|
| 530 |
+
**Priority 3 (Nice-to-Have)**: 7/7 **RECOMMENDED** π‘
|
| 531 |
+
- Tag vocabulary β Hybrid (core controlled + custom allowed)
|
| 532 |
+
- Taxonomy maintenance β Hybrid (system baseline + manual curation)
|
| 533 |
+
- Graph update frequency β Startup + manual refresh
|
| 534 |
+
- World configuration mutability β Static (locked at creation)
|
| 535 |
+
- Default world behavior β Error (require explicit config)
|
| 536 |
+
- Dependency auto-resolution β Warn (show warning but allow)
|
| 537 |
+
- Sampling determinism β Hybrid (default seed + override)
|
| 538 |
+
|
| 539 |
+
**Next Step**: Create implementation roadmap and build proof-of-concept.
|
docs/od-architecture/07-chaos-integration.md
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 07. Chaos Integration
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This document explains how the chaos management system integrates with the OD architecture. Chaos is a **cross-cutting concern** that affects capability execution at multiple levels.
|
| 6 |
+
|
| 7 |
+
For complete chaos management details, see [Chaos Management Documentation](../chaos/).
|
| 8 |
+
|
| 9 |
+
**Last Updated**: 2025-11-14
|
| 10 |
+
|
| 11 |
+
## Chaos in the Architecture
|
| 12 |
+
|
| 13 |
+
### Architectural Position
|
| 14 |
+
|
| 15 |
+
```
|
| 16 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 17 |
+
β PERSONA β
|
| 18 |
+
β (Store Manager) β
|
| 19 |
+
ββββββββββββββββ¬βββββββββββββββββββββββ
|
| 20 |
+
β
|
| 21 |
+
β
|
| 22 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 23 |
+
β CAPABILITY β β Chaos override possible
|
| 24 |
+
β (Order Fulfillment) β
|
| 25 |
+
ββββββββββββββββ¬βββββββββββββββββββββββ
|
| 26 |
+
β
|
| 27 |
+
β
|
| 28 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 29 |
+
β OPERATIONAL DESCRIPTOR (OD) β β Chaos policy defined
|
| 30 |
+
β (Workflow with chaos config) β
|
| 31 |
+
ββββββββββββββββ¬βββββββββββββββββββββββ
|
| 32 |
+
β
|
| 33 |
+
β
|
| 34 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 35 |
+
β STEP β β Chaos injected here
|
| 36 |
+
β (Tool execution + chaos) β
|
| 37 |
+
ββββββββββββββββ¬βββββββββββββββββββββββ
|
| 38 |
+
β
|
| 39 |
+
β
|
| 40 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 41 |
+
β TOOL β
|
| 42 |
+
β (Actual service call) β
|
| 43 |
+
βββββββββββββββββββββββββββββββββββββββ
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
**Chaos is injected**: After tool execution, before storing output (in the Step layer)
|
| 47 |
+
|
| 48 |
+
**Chaos is configured**: At World, Capability, OD, and Step levels
|
| 49 |
+
|
| 50 |
+
## Configuration Cascade
|
| 51 |
+
|
| 52 |
+
Chaos configuration follows a **priority cascade** (highest to lowest):
|
| 53 |
+
|
| 54 |
+
```
|
| 55 |
+
1. MASTER KILL-SWITCH (environment variable)
|
| 56 |
+
β if enabled
|
| 57 |
+
2. Step-level chaos override (in OD definition)
|
| 58 |
+
β if not specified
|
| 59 |
+
3. OD-level chaos policy (global OD chaos)
|
| 60 |
+
β if not specified
|
| 61 |
+
4. Capability-level override (per-capability config)
|
| 62 |
+
β if not specified
|
| 63 |
+
5. World-level chaos policy (world config)
|
| 64 |
+
β if not specified
|
| 65 |
+
6. System default chaos preset
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
### Example Cascade
|
| 69 |
+
|
| 70 |
+
**Environment**: `CHAOS_ENABLED=true`
|
| 71 |
+
|
| 72 |
+
**World Config**:
|
| 73 |
+
```yaml
|
| 74 |
+
world:
|
| 75 |
+
id: "research-001"
|
| 76 |
+
chaos:
|
| 77 |
+
preset: "moderate" # Global: 0.15 probability
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
**Capability Override**:
|
| 81 |
+
```yaml
|
| 82 |
+
capability:
|
| 83 |
+
id: "order-fulfillment"
|
| 84 |
+
chaosOverride:
|
| 85 |
+
probability: 0.3 # Higher for this capability
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
**OD Definition**:
|
| 89 |
+
```yaml
|
| 90 |
+
od:
|
| 91 |
+
id: "order-fulfillment-standard"
|
| 92 |
+
chaos:
|
| 93 |
+
probability: 0.25 # OD-level setting
|
| 94 |
+
steps:
|
| 95 |
+
- id: "check-inventory"
|
| 96 |
+
chaos:
|
| 97 |
+
probability: 0.0 # This step: no chaos!
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
**Result**:
|
| 101 |
+
- `check-inventory` step: **0.0** (step override)
|
| 102 |
+
- Other steps in OD: **0.25** (OD-level)
|
| 103 |
+
- Other capabilities in world: **0.15** (world preset)
|
| 104 |
+
|
| 105 |
+
## Integration Points
|
| 106 |
+
|
| 107 |
+
### 1. World Configuration
|
| 108 |
+
|
| 109 |
+
Chaos is configured when creating a world:
|
| 110 |
+
|
| 111 |
+
```yaml
|
| 112 |
+
POST /api/worlds
|
| 113 |
+
{
|
| 114 |
+
"name": "Chaos Research World",
|
| 115 |
+
"capabilities": {
|
| 116 |
+
"filters": { "domain": ["fulfillment"] }
|
| 117 |
+
},
|
| 118 |
+
"chaos": {
|
| 119 |
+
"preset": "aggressive",
|
| 120 |
+
"seed": "repro-123"
|
| 121 |
+
}
|
| 122 |
+
}
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
**What Happens**:
|
| 126 |
+
- World uses "aggressive" preset (0.3 probability)
|
| 127 |
+
- All capabilities in this world inherit this chaos
|
| 128 |
+
- Seed ensures reproducibility
|
| 129 |
+
|
| 130 |
+
### 2. Capability-Level Overrides
|
| 131 |
+
|
| 132 |
+
Fine-grained control per capability:
|
| 133 |
+
|
| 134 |
+
```yaml
|
| 135 |
+
world:
|
| 136 |
+
chaos:
|
| 137 |
+
preset: "moderate"
|
| 138 |
+
capabilityOverrides:
|
| 139 |
+
order-fulfillment:
|
| 140 |
+
probability: 0.5 # Critical capability: more chaos
|
| 141 |
+
inventory-check:
|
| 142 |
+
probability: 0.0 # Critical path: no chaos
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
**Use Case**: Test resilience of critical capabilities with higher chaos.
|
| 146 |
+
|
| 147 |
+
### 3. OD Execution
|
| 148 |
+
|
| 149 |
+
Chaos is injected during OD execution:
|
| 150 |
+
|
| 151 |
+
```
|
| 152 |
+
1. Researcher executes capability
|
| 153 |
+
2. Capability maps to OD
|
| 154 |
+
3. OD executor runs steps
|
| 155 |
+
4. For each step:
|
| 156 |
+
a. Execute tool (service call)
|
| 157 |
+
b. Resolve chaos policy (use cascade)
|
| 158 |
+
c. Maybe inject chaos (based on probability)
|
| 159 |
+
d. Store result (potentially modified by chaos)
|
| 160 |
+
5. Return execution result
|
| 161 |
+
```
|
| 162 |
+
|
| 163 |
+
**Chaos Transparency**:
|
| 164 |
+
- Chaos injections are logged
|
| 165 |
+
- Chaos modifications tracked in telemetry
|
| 166 |
+
- Researchers can see what chaos was applied
|
| 167 |
+
|
| 168 |
+
### 4. OD Variants with Chaos
|
| 169 |
+
|
| 170 |
+
Capabilities can have chaos-specific variants:
|
| 171 |
+
|
| 172 |
+
```yaml
|
| 173 |
+
capability:
|
| 174 |
+
id: "order-fulfillment"
|
| 175 |
+
variants:
|
| 176 |
+
- id: "order-fulfillment-no-chaos"
|
| 177 |
+
chaos: { enabled: false }
|
| 178 |
+
odId: "order-fulfillment-v1"
|
| 179 |
+
|
| 180 |
+
- id: "order-fulfillment-light-chaos"
|
| 181 |
+
chaos: { preset: "light" }
|
| 182 |
+
odId: "order-fulfillment-v1"
|
| 183 |
+
|
| 184 |
+
- id: "order-fulfillment-aggressive-chaos"
|
| 185 |
+
chaos: { preset: "aggressive" }
|
| 186 |
+
odId: "order-fulfillment-v1"
|
| 187 |
+
```
|
| 188 |
+
|
| 189 |
+
**Benefit**: Same workflow, different chaos levels for A/B testing.
|
| 190 |
+
|
| 191 |
+
## Chaos Presets
|
| 192 |
+
|
| 193 |
+
### Standard Presets
|
| 194 |
+
|
| 195 |
+
Defined in `config/chaos-presets/`:
|
| 196 |
+
|
| 197 |
+
**light.json** (0.05 probability):
|
| 198 |
+
- Stale data (eventual consistency)
|
| 199 |
+
- Rate limits (throttling)
|
| 200 |
+
- Missing data (occasional)
|
| 201 |
+
|
| 202 |
+
**moderate.json** (0.15 probability):
|
| 203 |
+
- All light scenarios
|
| 204 |
+
- Data corruption
|
| 205 |
+
- Partial data
|
| 206 |
+
- Permission denied
|
| 207 |
+
|
| 208 |
+
**aggressive.json** (0.3 probability):
|
| 209 |
+
- All scenarios
|
| 210 |
+
- Higher weights
|
| 211 |
+
- More severe configurations
|
| 212 |
+
|
| 213 |
+
**realistic.json** (0.08 probability):
|
| 214 |
+
- Real-world failure distribution
|
| 215 |
+
- Stale data: 40% weight
|
| 216 |
+
- Rate limits: 20% weight
|
| 217 |
+
- Rare failures: < 5% weight
|
| 218 |
+
|
| 219 |
+
### Custom Presets
|
| 220 |
+
|
| 221 |
+
Researchers can create custom presets:
|
| 222 |
+
|
| 223 |
+
```json
|
| 224 |
+
// config/chaos-presets/custom-fulfillment.json
|
| 225 |
+
{
|
| 226 |
+
"id": "custom-fulfillment",
|
| 227 |
+
"name": "Order Fulfillment Focused Chaos",
|
| 228 |
+
"globalProbability": 0.2,
|
| 229 |
+
"scenarios": [
|
| 230 |
+
{
|
| 231 |
+
"type": "missing_data",
|
| 232 |
+
"weight": 10,
|
| 233 |
+
"description": "Missing inventory records",
|
| 234 |
+
"config": { "missingRecords": true }
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"type": "stale_data",
|
| 238 |
+
"weight": 8,
|
| 239 |
+
"description": "Stale order status",
|
| 240 |
+
"config": { "staleDataAge": 120 }
|
| 241 |
+
}
|
| 242 |
+
]
|
| 243 |
+
}
|
| 244 |
+
```
|
| 245 |
+
|
| 246 |
+
## Master Kill-Switch
|
| 247 |
+
|
| 248 |
+
### Environment Variables
|
| 249 |
+
|
| 250 |
+
```bash
|
| 251 |
+
# Disable all chaos globally
|
| 252 |
+
CHAOS_ENABLED=false
|
| 253 |
+
|
| 254 |
+
# Use specific preset
|
| 255 |
+
CHAOS_PRESET=moderate
|
| 256 |
+
|
| 257 |
+
# Override global probability
|
| 258 |
+
CHAOS_GLOBAL_PROBABILITY=0.2
|
| 259 |
+
|
| 260 |
+
# Set global seed
|
| 261 |
+
CHAOS_GLOBAL_SEED=experiment-001
|
| 262 |
+
```
|
| 263 |
+
|
| 264 |
+
**Priority**: Environment variables override ALL file-based configuration.
|
| 265 |
+
|
| 266 |
+
### Runtime Control
|
| 267 |
+
|
| 268 |
+
```bash
|
| 269 |
+
# Via API (if implemented)
|
| 270 |
+
PUT /api/chaos/status
|
| 271 |
+
{
|
| 272 |
+
"enabled": false
|
| 273 |
+
}
|
| 274 |
+
```
|
| 275 |
+
|
| 276 |
+
**Use Case**: Emergency disable without restarting service.
|
| 277 |
+
|
| 278 |
+
## Chaos Telemetry
|
| 279 |
+
|
| 280 |
+
### What's Logged
|
| 281 |
+
|
| 282 |
+
Every chaos injection logs:
|
| 283 |
+
|
| 284 |
+
```json
|
| 285 |
+
{
|
| 286 |
+
"timestamp": "2025-11-14T10:30:45Z",
|
| 287 |
+
"level": "info",
|
| 288 |
+
"msg": "Chaos injected",
|
| 289 |
+
"chaos": {
|
| 290 |
+
"worldId": "research-001",
|
| 291 |
+
"capabilityId": "order-fulfillment",
|
| 292 |
+
"odId": "order-fulfillment-standard-v1",
|
| 293 |
+
"stepId": "check-inventory",
|
| 294 |
+
"scenarioType": "stale_data",
|
| 295 |
+
"configSource": "world-preset",
|
| 296 |
+
"probability": 0.15,
|
| 297 |
+
"seed": "repro-123",
|
| 298 |
+
"modifications": {
|
| 299 |
+
"staleDataAge": 60,
|
| 300 |
+
"fieldsAffected": ["timestamp", "lastUpdated"]
|
| 301 |
+
}
|
| 302 |
+
}
|
| 303 |
+
}
|
| 304 |
+
```
|
| 305 |
+
|
| 306 |
+
### Chaos Metrics
|
| 307 |
+
|
| 308 |
+
Track chaos impact:
|
| 309 |
+
|
| 310 |
+
```
|
| 311 |
+
GET /api/chaos/metrics?worldId=research-001
|
| 312 |
+
{
|
| 313 |
+
"totalInjections": 150,
|
| 314 |
+
"injectionRate": 0.14,
|
| 315 |
+
"scenarioDistribution": {
|
| 316 |
+
"stale_data": 60,
|
| 317 |
+
"missing_data": 45,
|
| 318 |
+
"rate_limit": 30
|
| 319 |
+
},
|
| 320 |
+
"impactAnalysis": {
|
| 321 |
+
"odSuccessRate": 0.75,
|
| 322 |
+
"odSuccessRateWithoutChaos": 0.95,
|
| 323 |
+
"chaosImpact": -20%
|
| 324 |
+
}
|
| 325 |
+
}
|
| 326 |
+
```
|
| 327 |
+
|
| 328 |
+
## Integration with Knowledge Graph
|
| 329 |
+
|
| 330 |
+
### Chaos-Aware Validation
|
| 331 |
+
|
| 332 |
+
Knowledge graph can validate chaos feasibility:
|
| 333 |
+
|
| 334 |
+
```typescript
|
| 335 |
+
// Can this OD handle this chaos scenario?
|
| 336 |
+
graph.validateChaos(odId, chaosScenario);
|
| 337 |
+
|
| 338 |
+
// Which scenarios are safe for this capability?
|
| 339 |
+
graph.suggestSafeChaos(capabilityId);
|
| 340 |
+
```
|
| 341 |
+
|
| 342 |
+
### Chaos Dependencies
|
| 343 |
+
|
| 344 |
+
Some chaos scenarios require specific data:
|
| 345 |
+
|
| 346 |
+
```
|
| 347 |
+
Scenario: "data_corruption"
|
| 348 |
+
Requires: Fields to corrupt
|
| 349 |
+
Validates: OD produces structured data (not just primitives)
|
| 350 |
+
|
| 351 |
+
Scenario: "missing_data"
|
| 352 |
+
Requires: Optional fields in schema
|
| 353 |
+
Validates: OD can handle missing data gracefully
|
| 354 |
+
```
|
| 355 |
+
|
| 356 |
+
**Future**: Graph validates chaos applicability before injection.
|
| 357 |
+
|
| 358 |
+
## Researcher Workflows
|
| 359 |
+
|
| 360 |
+
### Workflow 1: Standard Chaos Testing
|
| 361 |
+
|
| 362 |
+
```yaml
|
| 363 |
+
# Create world with moderate chaos
|
| 364 |
+
world:
|
| 365 |
+
name: "Resilience Test"
|
| 366 |
+
chaos:
|
| 367 |
+
preset: "moderate"
|
| 368 |
+
seed: "test-001"
|
| 369 |
+
|
| 370 |
+
# Execute capabilities
|
| 371 |
+
# Observe failures
|
| 372 |
+
# Analyze chaos impact
|
| 373 |
+
```
|
| 374 |
+
|
| 375 |
+
### Workflow 2: Progressive Chaos
|
| 376 |
+
|
| 377 |
+
```yaml
|
| 378 |
+
# Phase 1: No chaos
|
| 379 |
+
world1:
|
| 380 |
+
chaos: { enabled: false }
|
| 381 |
+
|
| 382 |
+
# Phase 2: Light chaos
|
| 383 |
+
world2:
|
| 384 |
+
chaos: { preset: "light" }
|
| 385 |
+
|
| 386 |
+
# Phase 3: Aggressive chaos
|
| 387 |
+
world3:
|
| 388 |
+
chaos: { preset: "aggressive" }
|
| 389 |
+
|
| 390 |
+
# Compare results across phases
|
| 391 |
+
```
|
| 392 |
+
|
| 393 |
+
### Workflow 3: Targeted Chaos
|
| 394 |
+
|
| 395 |
+
```yaml
|
| 396 |
+
# Most capabilities: no chaos
|
| 397 |
+
world:
|
| 398 |
+
chaos: { enabled: false }
|
| 399 |
+
|
| 400 |
+
# Except one critical capability
|
| 401 |
+
capabilityOverrides:
|
| 402 |
+
order-fulfillment:
|
| 403 |
+
chaos:
|
| 404 |
+
preset: "aggressive"
|
| 405 |
+
scenarios: [
|
| 406 |
+
{ type: "missing_data", weight: 10 }
|
| 407 |
+
]
|
| 408 |
+
```
|
| 409 |
+
|
| 410 |
+
### Workflow 4: A/B Testing
|
| 411 |
+
|
| 412 |
+
```yaml
|
| 413 |
+
# Control group: no chaos variant
|
| 414 |
+
capability: "order-fulfillment-no-chaos"
|
| 415 |
+
|
| 416 |
+
# Treatment group: chaos variant
|
| 417 |
+
capability: "order-fulfillment-light-chaos"
|
| 418 |
+
|
| 419 |
+
# Compare AI agent performance
|
| 420 |
+
```
|
| 421 |
+
|
| 422 |
+
## Best Practices
|
| 423 |
+
|
| 424 |
+
### 1. Start with Presets
|
| 425 |
+
|
| 426 |
+
Don't configure chaos manually from scratch:
|
| 427 |
+
|
| 428 |
+
```yaml
|
| 429 |
+
# β
Good: Use preset
|
| 430 |
+
chaos:
|
| 431 |
+
preset: "moderate"
|
| 432 |
+
|
| 433 |
+
# β Avoid: Manual config (error-prone)
|
| 434 |
+
chaos:
|
| 435 |
+
probability: 0.15
|
| 436 |
+
scenarios: [ ... 20 lines of config ... ]
|
| 437 |
+
```
|
| 438 |
+
|
| 439 |
+
### 2. Always Use Seeds for Reproducibility
|
| 440 |
+
|
| 441 |
+
```yaml
|
| 442 |
+
# β
Good: Reproducible
|
| 443 |
+
chaos:
|
| 444 |
+
preset: "moderate"
|
| 445 |
+
seed: "experiment-20251114-001"
|
| 446 |
+
|
| 447 |
+
# β Avoid: Non-deterministic
|
| 448 |
+
chaos:
|
| 449 |
+
preset: "moderate"
|
| 450 |
+
# no seed = different chaos each run
|
| 451 |
+
```
|
| 452 |
+
|
| 453 |
+
### 3. Override Selectively
|
| 454 |
+
|
| 455 |
+
```yaml
|
| 456 |
+
# β
Good: Preset + targeted override
|
| 457 |
+
chaos:
|
| 458 |
+
preset: "moderate"
|
| 459 |
+
capabilityOverrides:
|
| 460 |
+
critical-capability:
|
| 461 |
+
probability: 0.0 # No chaos for critical path
|
| 462 |
+
|
| 463 |
+
# β Avoid: Everything manual
|
| 464 |
+
capabilityOverrides:
|
| 465 |
+
cap1: { ... }
|
| 466 |
+
cap2: { ... }
|
| 467 |
+
cap3: { ... }
|
| 468 |
+
# Too much manual config
|
| 469 |
+
```
|
| 470 |
+
|
| 471 |
+
### 4. Document Chaos Rationale
|
| 472 |
+
|
| 473 |
+
```yaml
|
| 474 |
+
world:
|
| 475 |
+
name: "Agent Resilience Test"
|
| 476 |
+
description: "Testing AI agent with realistic failure rates"
|
| 477 |
+
chaos:
|
| 478 |
+
preset: "realistic"
|
| 479 |
+
seed: "resilience-001"
|
| 480 |
+
chaosRationale: "Using realistic preset to match production failure distribution"
|
| 481 |
+
```
|
| 482 |
+
|
| 483 |
+
## Implementation Phases
|
| 484 |
+
|
| 485 |
+
Chaos management is built incrementally alongside OD architecture:
|
| 486 |
+
|
| 487 |
+
### Phase 1 (Core Capability System)
|
| 488 |
+
- **Deliverable**: Chaos preset files
|
| 489 |
+
- **Deliverable**: Environment variable support (CHAOS_ENABLED)
|
| 490 |
+
- **Deliverable**: ChaosConfigRegistry service
|
| 491 |
+
- Researchers can use presets
|
| 492 |
+
|
| 493 |
+
### Phase 2 (World Configuration)
|
| 494 |
+
- **Deliverable**: World-level chaos config
|
| 495 |
+
- **Deliverable**: Apply presets to worlds
|
| 496 |
+
- **Deliverable**: Seed support for reproducibility
|
| 497 |
+
- Researchers configure chaos per world
|
| 498 |
+
|
| 499 |
+
### Phase 4 (Advanced Features)
|
| 500 |
+
- **Deliverable**: Capability-level overrides
|
| 501 |
+
- **Deliverable**: OD-level runtime config
|
| 502 |
+
- **Deliverable**: Chaos telemetry and metrics
|
| 503 |
+
- Researchers have fine-grained control
|
| 504 |
+
|
| 505 |
+
### Phase 5 (Polish & Scale)
|
| 506 |
+
- **Deliverable**: Chaos configuration API
|
| 507 |
+
- **Deliverable**: Impact analysis tools
|
| 508 |
+
- **Deliverable**: Migration from scattered configs
|
| 509 |
+
- Production-ready chaos management
|
| 510 |
+
|
| 511 |
+
## Related Documents
|
| 512 |
+
|
| 513 |
+
- **[Chaos Management](../chaos/chaos-management.md)** - Complete chaos system design
|
| 514 |
+
- **[Chaos Presets](../chaos/)** - Preset library and details
|
| 515 |
+
- **[02. Conceptual Model](./02-conceptual-model.md)** - Where chaos fits in architecture
|
| 516 |
+
- **[08. Implementation Roadmap](./08-implementation-roadmap.md)** - Chaos implementation timeline
|
| 517 |
+
- **[05. World Configuration](./05-sampling-world-config.md)** - World-level chaos config
|
| 518 |
+
|
| 519 |
+
## Summary
|
| 520 |
+
|
| 521 |
+
**Key Points**:
|
| 522 |
+
1. Chaos is a **cross-cutting concern** affecting OD execution
|
| 523 |
+
2. Configuration **cascades** from World β Capability β OD β Step
|
| 524 |
+
3. **Master kill-switch** via environment variables
|
| 525 |
+
4. **Presets** provide standardized chaos configurations
|
| 526 |
+
5. **Telemetry** tracks all chaos injections
|
| 527 |
+
6. **Reproducible** via seeded randomness
|
| 528 |
+
7. Integrated with **OD architecture** from Phase 1
|
| 529 |
+
|
| 530 |
+
**For Researchers**:
|
| 531 |
+
- Start with presets (light, moderate, aggressive, realistic)
|
| 532 |
+
- Configure at world level
|
| 533 |
+
- Override for specific capabilities as needed
|
| 534 |
+
- Always use seeds for reproducibility
|
| 535 |
+
- Monitor chaos impact via telemetry
|
docs/od-architecture/08-implementation-roadmap.md
ADDED
|
@@ -0,0 +1,819 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 08. Implementation Roadmap
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This roadmap outlines a **value-driven, incremental approach** to implementing the OD management system. Each phase delivers usable features to researchers, not just infrastructure.
|
| 6 |
+
|
| 7 |
+
**Last Updated**: 2025-11-14
|
| 8 |
+
|
| 9 |
+
## Why NOT Bottom-Up?
|
| 10 |
+
|
| 11 |
+
**Bottom-up approach (β Don't do this)**:
|
| 12 |
+
```
|
| 13 |
+
Phase 1: Build complete database schema
|
| 14 |
+
Phase 2: Build knowledge graph infrastructure
|
| 15 |
+
Phase 3: Build capability registry
|
| 16 |
+
Phase 4: Build persona system
|
| 17 |
+
Phase 5: Finally, let researchers use it
|
| 18 |
+
```
|
| 19 |
+
|
| 20 |
+
**Problems**:
|
| 21 |
+
- No researcher value until Phase 5
|
| 22 |
+
- High risk if requirements change
|
| 23 |
+
- Over-engineering for features we might not need
|
| 24 |
+
- Long feedback loop - don't learn if design works until the end
|
| 25 |
+
|
| 26 |
+
## Our Approach: Value-Driven Vertical Slices
|
| 27 |
+
|
| 28 |
+
**Incremental approach (β
We do this)**:
|
| 29 |
+
```
|
| 30 |
+
Phase 0: Walking skeleton - 5 hardcoded capabilities researchers can execute
|
| 31 |
+
Phase 1: Browse and filter ~30 capabilities
|
| 32 |
+
Phase 2: Create custom worlds with capability sampling
|
| 33 |
+
Phase 3: Validate dependencies (basic knowledge graph)
|
| 34 |
+
Phase 4: Add personas and chaos integration
|
| 35 |
+
Phase 5: Polish and scale
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
**Benefits**:
|
| 39 |
+
- Researcher value from Phase 0
|
| 40 |
+
- Fast feedback - learn if approach works early
|
| 41 |
+
- Can pivot based on learnings
|
| 42 |
+
- Lower risk - small increments
|
| 43 |
+
- Infrastructure built when needed, not speculatively
|
| 44 |
+
|
| 45 |
+
## Guiding Principles
|
| 46 |
+
|
| 47 |
+
1. **Deliver Value Every Phase**: Each phase = something researchers can use
|
| 48 |
+
2. **Walking Skeleton First**: Get minimal end-to-end working, then expand
|
| 49 |
+
3. **Defer Decisions**: Don't implement everything designed; implement what's needed
|
| 50 |
+
4. **Evolutionary Architecture**: Allow for changes based on learnings
|
| 51 |
+
5. **Vertical Slices**: Build features end-to-end, not layers horizontally
|
| 52 |
+
|
| 53 |
+
---
|
| 54 |
+
|
| 55 |
+
## Phase 0: Walking Skeleton (2-3 weeks)
|
| 56 |
+
|
| 57 |
+
### Goal
|
| 58 |
+
Prove the concept works end-to-end with minimal implementation.
|
| 59 |
+
|
| 60 |
+
### What Researchers Can Do
|
| 61 |
+
- List available capabilities (5 hardcoded examples)
|
| 62 |
+
- View capability details (name, description, tags)
|
| 63 |
+
- Execute a capability (maps to existing OD)
|
| 64 |
+
|
| 65 |
+
### Deliverables
|
| 66 |
+
|
| 67 |
+
**1. Hardcoded Capability Catalog** (~5 capabilities)
|
| 68 |
+
```typescript
|
| 69 |
+
// src/capabilities/catalog.ts
|
| 70 |
+
export const CAPABILITIES = [
|
| 71 |
+
{
|
| 72 |
+
id: "order-fulfillment-simple",
|
| 73 |
+
name: "Order Fulfillment (Simple)",
|
| 74 |
+
description: "Process customer order with basic workflow",
|
| 75 |
+
tags: {
|
| 76 |
+
domain: ["fulfillment"],
|
| 77 |
+
complexity: "simple",
|
| 78 |
+
services: ["erp", "wms"]
|
| 79 |
+
},
|
| 80 |
+
odId: "order-fulfillment-standard-v1" // Links to existing OD
|
| 81 |
+
},
|
| 82 |
+
// ... 4 more
|
| 83 |
+
];
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
**2. Simple REST API**
|
| 87 |
+
```
|
| 88 |
+
GET /api/capabilities # List all capabilities
|
| 89 |
+
GET /api/capabilities/:id # Get capability details
|
| 90 |
+
POST /api/capabilities/:id/execute # Execute (runs linked OD)
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
**3. Execution Logic**
|
| 94 |
+
- Map capability ID β existing OD
|
| 95 |
+
- Execute OD using current executor
|
| 96 |
+
- Return results
|
| 97 |
+
|
| 98 |
+
### What We're NOT Building Yet
|
| 99 |
+
- β Database persistence
|
| 100 |
+
- β Knowledge graph
|
| 101 |
+
- β Complex filtering
|
| 102 |
+
- β World configuration
|
| 103 |
+
- β Persona system
|
| 104 |
+
- β Dynamic capability creation
|
| 105 |
+
|
| 106 |
+
### Success Criteria
|
| 107 |
+
- β
Researcher can GET /api/capabilities and see 5 options
|
| 108 |
+
- β
Researcher can execute a capability and get results
|
| 109 |
+
- β
End-to-end flow works without errors
|
| 110 |
+
- β
Team agrees this approach is promising
|
| 111 |
+
|
| 112 |
+
### Decision Point
|
| 113 |
+
**After Phase 0**: Does this approach provide value? Should we continue?
|
| 114 |
+
|
| 115 |
+
**Effort**: 2-3 weeks (1 developer)
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
## Phase 1: Core Capability System (3-4 weeks)
|
| 120 |
+
|
| 121 |
+
### Goal
|
| 122 |
+
Expand to ~30 capabilities with browsing, filtering, and tagging.
|
| 123 |
+
|
| 124 |
+
### What Researchers Can Do
|
| 125 |
+
- Browse ~30 capabilities across domains
|
| 126 |
+
- Filter by domain, complexity, services
|
| 127 |
+
- Search by name/description
|
| 128 |
+
- Execute any capability
|
| 129 |
+
- **Use chaos presets** (light, moderate, aggressive)
|
| 130 |
+
|
| 131 |
+
### Deliverables
|
| 132 |
+
|
| 133 |
+
**1. Capability Registry Service**
|
| 134 |
+
```typescript
|
| 135 |
+
// src/services/capability-registry.service.ts
|
| 136 |
+
class CapabilityRegistry {
|
| 137 |
+
private capabilities: Map<string, Capability>;
|
| 138 |
+
|
| 139 |
+
find(filters: CapabilityFilters): Capability[];
|
| 140 |
+
get(capabilityId: string): Capability | null;
|
| 141 |
+
search(query: string): Capability[];
|
| 142 |
+
}
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
**2. Capability Definitions** (~30 capabilities)
|
| 146 |
+
- File-based storage: `config/capabilities/`
|
| 147 |
+
- YAML or JSON format
|
| 148 |
+
- Comprehensive tags for each
|
| 149 |
+
|
| 150 |
+
**3. Enhanced API**
|
| 151 |
+
```
|
| 152 |
+
GET /api/capabilities?domain=fulfillment
|
| 153 |
+
GET /api/capabilities?complexity=simple
|
| 154 |
+
GET /api/capabilities?services=wms,erp
|
| 155 |
+
GET /api/capabilities/search?q=order
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
**4. Map Capabilities to Existing ODs**
|
| 159 |
+
- Use current OD builders
|
| 160 |
+
- No need to refactor existing ODs yet
|
| 161 |
+
|
| 162 |
+
**5. Chaos Management Foundation**
|
| 163 |
+
```typescript
|
| 164 |
+
// src/config/chaos-config.registry.ts
|
| 165 |
+
class ChaosConfigRegistry {
|
| 166 |
+
loadPreset(presetId: string): ChaosPolicy;
|
| 167 |
+
listPresets(): PresetMetadata[];
|
| 168 |
+
isChaosEnabled(): boolean; // Check CHAOS_ENABLED env var
|
| 169 |
+
}
|
| 170 |
+
```
|
| 171 |
+
|
| 172 |
+
**6. Chaos Preset Files**
|
| 173 |
+
```
|
| 174 |
+
config/chaos-presets/
|
| 175 |
+
βββ light.json # 0.05 probability
|
| 176 |
+
βββ moderate.json # 0.15 probability
|
| 177 |
+
βββ aggressive.json # 0.3 probability
|
| 178 |
+
βββ realistic.json # 0.08 probability (real-world distribution)
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
**7. Environment Variable Support**
|
| 182 |
+
```bash
|
| 183 |
+
CHAOS_ENABLED=true|false # Master kill-switch
|
| 184 |
+
CHAOS_PRESET=moderate # Default preset
|
| 185 |
+
CHAOS_GLOBAL_PROBABILITY=0.1 # Override probability
|
| 186 |
+
```
|
| 187 |
+
|
| 188 |
+
### What We're NOT Building Yet
|
| 189 |
+
- β MongoDB persistence (file-based is fine)
|
| 190 |
+
- β Knowledge graph
|
| 191 |
+
- β World configuration
|
| 192 |
+
- β Persona mapping
|
| 193 |
+
- β OD variants (just 1:1 mapping for now)
|
| 194 |
+
|
| 195 |
+
### Success Criteria
|
| 196 |
+
- β
30 capabilities defined and discoverable
|
| 197 |
+
- β
Filtering works correctly
|
| 198 |
+
- β
All capabilities executable
|
| 199 |
+
- β
Researchers can find what they need
|
| 200 |
+
- β
**Chaos presets work with env var control**
|
| 201 |
+
- β
**CHAOS_ENABLED=false disables all chaos**
|
| 202 |
+
|
| 203 |
+
### Decision Point
|
| 204 |
+
**After Phase 1**: Are 30 capabilities enough? Is tagging working? Do we need hierarchy? **Are chaos presets sufficient?**
|
| 205 |
+
|
| 206 |
+
**Effort**: 3-4 weeks (1-2 developers)
|
| 207 |
+
- Define 30 capabilities: 1 week
|
| 208 |
+
- Build registry service: 1 week
|
| 209 |
+
- API endpoints: 1 week
|
| 210 |
+
- **Chaos presets & registry: 3 days**
|
| 211 |
+
- Testing & docs: 1 week
|
| 212 |
+
|
| 213 |
+
---
|
| 214 |
+
|
| 215 |
+
## Phase 2: World Configuration (2-3 weeks)
|
| 216 |
+
|
| 217 |
+
### Goal
|
| 218 |
+
Enable researchers to create custom worlds with capability sampling.
|
| 219 |
+
|
| 220 |
+
### What Researchers Can Do
|
| 221 |
+
- Create world with specific capabilities (filter-based selection)
|
| 222 |
+
- Sample capabilities randomly or by criteria
|
| 223 |
+
- Execute capabilities within configured world
|
| 224 |
+
- World configuration is immutable after creation
|
| 225 |
+
- **Configure chaos at world level** (preset-based)
|
| 226 |
+
- **Reproducible chaos** with seeds
|
| 227 |
+
|
| 228 |
+
### Deliverables
|
| 229 |
+
|
| 230 |
+
**1. World Configuration Schema**
|
| 231 |
+
```yaml
|
| 232 |
+
world:
|
| 233 |
+
id: "research-001"
|
| 234 |
+
name: "Warehouse Operations Study"
|
| 235 |
+
capabilities:
|
| 236 |
+
filters:
|
| 237 |
+
domains: [warehousing, inventory]
|
| 238 |
+
complexity: [simple, medium]
|
| 239 |
+
chaos:
|
| 240 |
+
preset: "moderate" # Use preset
|
| 241 |
+
seed: "repro-123" # Reproducible chaos
|
| 242 |
+
```
|
| 243 |
+
|
| 244 |
+
**2. World Configuration API**
|
| 245 |
+
```
|
| 246 |
+
POST /api/worlds # Create world with config
|
| 247 |
+
GET /api/worlds/:worldId # Get world details
|
| 248 |
+
GET /api/worlds/:worldId/capabilities # List capabilities in world
|
| 249 |
+
POST /api/worlds/:worldId/capabilities/:capId/execute # Execute in world context
|
| 250 |
+
```
|
| 251 |
+
|
| 252 |
+
**3. Sampling Strategies** (start simple)
|
| 253 |
+
- Filter-based selection (domain, complexity, etc.)
|
| 254 |
+
- Random sampling with count
|
| 255 |
+
- Seed support for reproducibility
|
| 256 |
+
|
| 257 |
+
**4. World-Scoped Execution**
|
| 258 |
+
- Execute ODs in world context
|
| 259 |
+
- Isolated data per world (already supported)
|
| 260 |
+
|
| 261 |
+
**5. World-Level Chaos Configuration**
|
| 262 |
+
```typescript
|
| 263 |
+
// Update ChaosConfigRegistry
|
| 264 |
+
class ChaosConfigRegistry {
|
| 265 |
+
// Add world-level chaos resolution
|
| 266 |
+
getWorldChaosPolicy(worldId: string): ChaosPolicy;
|
| 267 |
+
setWorldChaosPolicy(worldId: string, policy: ChaosPolicy): void;
|
| 268 |
+
|
| 269 |
+
// Resolve chaos with world context
|
| 270 |
+
resolveChaosPolicy(context: ChaosContext): ChaosPolicy;
|
| 271 |
+
}
|
| 272 |
+
```
|
| 273 |
+
- Apply preset to world
|
| 274 |
+
- Support chaos seed for reproducibility
|
| 275 |
+
- Chaos inherits to all capabilities in world
|
| 276 |
+
|
| 277 |
+
### What We're NOT Building Yet
|
| 278 |
+
- β MongoDB persistence (in-memory registry is fine)
|
| 279 |
+
- β Dependency validation
|
| 280 |
+
- β Persona-based filtering
|
| 281 |
+
- β Complex sampling (weighted, hierarchical, graph-based)
|
| 282 |
+
- β World mutation after creation
|
| 283 |
+
- β **Capability-level chaos overrides** (comes in Phase 4)
|
| 284 |
+
|
| 285 |
+
### Success Criteria
|
| 286 |
+
- β
Researcher can create world with filtered capabilities
|
| 287 |
+
- β
World shows only selected capabilities
|
| 288 |
+
- β
Capabilities execute correctly in world context
|
| 289 |
+
- β
Sampling is reproducible with seed
|
| 290 |
+
- β
**Chaos configured at world level**
|
| 291 |
+
- β
**Same seed produces identical chaos across runs**
|
| 292 |
+
|
| 293 |
+
### Decision Point
|
| 294 |
+
**After Phase 2**: Are filter-based and random sampling sufficient? Do we need weighted/hierarchical? **Is world-level chaos enough or need capability-level?**
|
| 295 |
+
|
| 296 |
+
**Effort**: 2-3 weeks (1 developer)
|
| 297 |
+
- World config schema: 3 days
|
| 298 |
+
- Sampling logic: 1 week
|
| 299 |
+
- API endpoints: 3 days
|
| 300 |
+
- **World chaos integration: 2 days**
|
| 301 |
+
- Testing: 3 days
|
| 302 |
+
|
| 303 |
+
---
|
| 304 |
+
|
| 305 |
+
## Phase 3: Knowledge Graph Basics (3-4 weeks)
|
| 306 |
+
|
| 307 |
+
### Goal
|
| 308 |
+
Add dependency validation and basic capability suggestions using a simple knowledge graph.
|
| 309 |
+
|
| 310 |
+
### What Researchers Can Do
|
| 311 |
+
- Validate that a capability is executable (has all dependencies)
|
| 312 |
+
- Get warned about missing prerequisites
|
| 313 |
+
- See "related capabilities" suggestions
|
| 314 |
+
- Validate OD feasibility before execution
|
| 315 |
+
|
| 316 |
+
### Deliverables
|
| 317 |
+
|
| 318 |
+
**1. Manual Tool Annotations**
|
| 319 |
+
```typescript
|
| 320 |
+
// Add to existing service tool definitions
|
| 321 |
+
{
|
| 322 |
+
tool: "createOrder",
|
| 323 |
+
produces: ["Order"],
|
| 324 |
+
requires: ["Customer", "Product"],
|
| 325 |
+
service: "erp"
|
| 326 |
+
}
|
| 327 |
+
```
|
| 328 |
+
|
| 329 |
+
**2. In-Memory Knowledge Graph**
|
| 330 |
+
```typescript
|
| 331 |
+
// src/services/knowledge-graph.service.ts
|
| 332 |
+
class KnowledgeGraph {
|
| 333 |
+
// Nodes: Services, Tools, Entities, Capabilities
|
| 334 |
+
// Edges: uses, produces, requires, exposed_by
|
| 335 |
+
|
| 336 |
+
validateOD(odId: string): ValidationResult;
|
| 337 |
+
findCapabilities(filters: any): Capability[];
|
| 338 |
+
suggestRelated(capabilityId: string): Capability[];
|
| 339 |
+
}
|
| 340 |
+
```
|
| 341 |
+
|
| 342 |
+
**3. Dependency Validation**
|
| 343 |
+
- Check if OD has all required tools
|
| 344 |
+
- Check if tools have required data
|
| 345 |
+
- Warn if dependencies missing
|
| 346 |
+
|
| 347 |
+
**4. Enhanced API**
|
| 348 |
+
```
|
| 349 |
+
GET /api/capabilities/:id/validate # Validate capability is executable
|
| 350 |
+
GET /api/capabilities/:id/dependencies # List dependencies
|
| 351 |
+
GET /api/capabilities/:id/related # Suggest related capabilities
|
| 352 |
+
```
|
| 353 |
+
|
| 354 |
+
### What We're NOT Building Yet
|
| 355 |
+
- β MongoDB persistence for graph (rebuild on startup is fine)
|
| 356 |
+
- β Runtime learning
|
| 357 |
+
- β Static analysis of code
|
| 358 |
+
- β Complex graph queries
|
| 359 |
+
- β OD discovery/suggestion (just validation)
|
| 360 |
+
|
| 361 |
+
### Success Criteria
|
| 362 |
+
- β
Can validate if capability is executable
|
| 363 |
+
- β
Warnings shown for missing dependencies
|
| 364 |
+
- β
Related capabilities suggested accurately
|
| 365 |
+
- β
Graph loads quickly on startup
|
| 366 |
+
|
| 367 |
+
### Decision Point
|
| 368 |
+
**After Phase 3**: Is manual annotation sustainable? Do we need static analysis? Is validation useful?
|
| 369 |
+
|
| 370 |
+
**Effort**: 3-4 weeks (1-2 developers)
|
| 371 |
+
- Annotate tools: 1 week (15-20 critical tools)
|
| 372 |
+
- Build graph structure: 1 week
|
| 373 |
+
- Validation logic: 1 week
|
| 374 |
+
- API & testing: 1 week
|
| 375 |
+
|
| 376 |
+
---
|
| 377 |
+
|
| 378 |
+
## Phase 4: Advanced Features (3-4 weeks)
|
| 379 |
+
|
| 380 |
+
### Goal
|
| 381 |
+
Add persona system and advanced chaos integration.
|
| 382 |
+
|
| 383 |
+
### What Researchers Can Do
|
| 384 |
+
- Filter capabilities by persona
|
| 385 |
+
- Create worlds with persona-based access
|
| 386 |
+
- Configure chaos at world/capability level with full priority cascade
|
| 387 |
+
- Analyze chaos impact through detailed telemetry
|
| 388 |
+
|
| 389 |
+
### Deliverables
|
| 390 |
+
|
| 391 |
+
**1. Persona System** (~15-20 personas)
|
| 392 |
+
```yaml
|
| 393 |
+
# config/personas.yaml
|
| 394 |
+
personas:
|
| 395 |
+
- id: store-manager
|
| 396 |
+
name: Store Manager
|
| 397 |
+
description: Manages store operations
|
| 398 |
+
capabilities:
|
| 399 |
+
- order-fulfillment
|
| 400 |
+
- inventory-management
|
| 401 |
+
- exception-handling
|
| 402 |
+
```
|
| 403 |
+
|
| 404 |
+
**2. Persona-Based Filtering**
|
| 405 |
+
```
|
| 406 |
+
GET /api/capabilities?persona=store-manager
|
| 407 |
+
GET /api/personas # List all personas
|
| 408 |
+
GET /api/personas/:id/capabilities # Capabilities for persona
|
| 409 |
+
```
|
| 410 |
+
|
| 411 |
+
**3. Advanced Chaos Features**
|
| 412 |
+
```yaml
|
| 413 |
+
world:
|
| 414 |
+
chaos:
|
| 415 |
+
preset: "moderate"
|
| 416 |
+
# Capability-level overrides
|
| 417 |
+
capabilityOverrides:
|
| 418 |
+
order-fulfillment:
|
| 419 |
+
probability: 0.3
|
| 420 |
+
scenarios:
|
| 421 |
+
- type: missing_data
|
| 422 |
+
weight: 10
|
| 423 |
+
inventory-check:
|
| 424 |
+
probability: 0.0 # No chaos for critical path
|
| 425 |
+
```
|
| 426 |
+
|
| 427 |
+
**Chaos Configuration Priority Cascade**:
|
| 428 |
+
```typescript
|
| 429 |
+
// Implement full priority cascade
|
| 430 |
+
class ChaosConfigRegistry {
|
| 431 |
+
resolveChaosPolicy(context: ChaosContext): ChaosPolicy {
|
| 432 |
+
// 1. Check master kill-switch (CHAOS_ENABLED)
|
| 433 |
+
// 2. Step-level override (from OD)
|
| 434 |
+
// 3. OD-level policy
|
| 435 |
+
// 4. Capability-level override
|
| 436 |
+
// 5. World-level policy
|
| 437 |
+
// 6. System default
|
| 438 |
+
}
|
| 439 |
+
}
|
| 440 |
+
```
|
| 441 |
+
|
| 442 |
+
**Chaos Telemetry**:
|
| 443 |
+
```typescript
|
| 444 |
+
// Enhanced logging for chaos injections
|
| 445 |
+
{
|
| 446 |
+
chaosInjected: true,
|
| 447 |
+
scenarioType: "stale_data",
|
| 448 |
+
configSource: "capability-override",
|
| 449 |
+
probability: 0.3,
|
| 450 |
+
seed: "repro-123"
|
| 451 |
+
}
|
| 452 |
+
```
|
| 453 |
+
|
| 454 |
+
**4. World Persona Overrides**
|
| 455 |
+
```yaml
|
| 456 |
+
world:
|
| 457 |
+
personaOverrides:
|
| 458 |
+
custom-agent:
|
| 459 |
+
capabilities: [order-fulfillment, inventory-check]
|
| 460 |
+
```
|
| 461 |
+
|
| 462 |
+
### What We're NOT Building Yet
|
| 463 |
+
- β MongoDB persistence (still file-based)
|
| 464 |
+
- β Complex persona hierarchies
|
| 465 |
+
- β Dynamic persona creation UI
|
| 466 |
+
- β OD Variants (deferred to Phase 6)
|
| 467 |
+
|
| 468 |
+
### Success Criteria
|
| 469 |
+
- β
Personas defined and queryable
|
| 470 |
+
- β
Can filter capabilities by persona
|
| 471 |
+
- β
**Capability-level chaos overrides functional**
|
| 472 |
+
- β
**Chaos priority cascade implemented correctly**
|
| 473 |
+
- β
**Chaos telemetry logs all injections**
|
| 474 |
+
- β
Custom personas can be created per world
|
| 475 |
+
|
| 476 |
+
### Decision Point
|
| 477 |
+
**After Phase 4**: Are personas granular enough? **Is chaos telemetry providing useful insights?**
|
| 478 |
+
|
| 479 |
+
**Effort**: 3-4 weeks (2 developers)
|
| 480 |
+
- Define personas: 1 week
|
| 481 |
+
- Persona filtering: 1 week
|
| 482 |
+
- **Advanced chaos features**: 1 week
|
| 483 |
+
- Capability-level overrides
|
| 484 |
+
- Priority cascade implementation
|
| 485 |
+
- Enhanced telemetry
|
| 486 |
+
- Testing & docs: 1 week
|
| 487 |
+
|
| 488 |
+
---
|
| 489 |
+
|
| 490 |
+
## Phase 5: Polish & Scale (Ongoing)
|
| 491 |
+
|
| 492 |
+
### Goal
|
| 493 |
+
Production-ready system with performance, persistence, and documentation.
|
| 494 |
+
|
| 495 |
+
### What Researchers Can Do
|
| 496 |
+
- Use system at scale (100+ capabilities, 50+ personas)
|
| 497 |
+
- Advanced sampling strategies
|
| 498 |
+
- Comprehensive documentation
|
| 499 |
+
- Performance monitoring
|
| 500 |
+
|
| 501 |
+
### Deliverables
|
| 502 |
+
|
| 503 |
+
**1. MongoDB Persistence**
|
| 504 |
+
- Capabilities collection
|
| 505 |
+
- Personas collection
|
| 506 |
+
- Worlds collection
|
| 507 |
+
- Knowledge graph nodes/edges
|
| 508 |
+
|
| 509 |
+
**2. Performance Optimization**
|
| 510 |
+
- Caching for capability queries
|
| 511 |
+
- Efficient graph queries
|
| 512 |
+
- Pagination for large result sets
|
| 513 |
+
|
| 514 |
+
**3. Advanced Sampling**
|
| 515 |
+
- Weighted sampling
|
| 516 |
+
- Hierarchical sampling
|
| 517 |
+
- Graph-based sampling
|
| 518 |
+
|
| 519 |
+
**4. Comprehensive Documentation**
|
| 520 |
+
- API reference
|
| 521 |
+
- Researcher guide
|
| 522 |
+
- Capability cookbook
|
| 523 |
+
- Migration guide from old system
|
| 524 |
+
|
| 525 |
+
**5. Monitoring & Telemetry**
|
| 526 |
+
- Usage metrics
|
| 527 |
+
- Performance metrics
|
| 528 |
+
- Error tracking
|
| 529 |
+
|
| 530 |
+
**6. Chaos Management API & Tools**
|
| 531 |
+
```
|
| 532 |
+
# Chaos configuration endpoints
|
| 533 |
+
GET /api/chaos/presets # List presets
|
| 534 |
+
GET /api/chaos/presets/:id # Get preset
|
| 535 |
+
POST /api/chaos/presets # Create custom preset
|
| 536 |
+
PUT /api/worlds/:worldId/chaos # Update world chaos
|
| 537 |
+
GET /api/chaos/metrics?worldId=... # Chaos impact metrics
|
| 538 |
+
POST /api/chaos/test # Test chaos (dry run)
|
| 539 |
+
```
|
| 540 |
+
|
| 541 |
+
**7. Chaos Impact Analysis**
|
| 542 |
+
- Chaos metrics aggregation (injection counts, scenario distribution)
|
| 543 |
+
- Success rate correlation (with vs without chaos)
|
| 544 |
+
- Chaos impact reports
|
| 545 |
+
- A/B testing tools (compare chaos variants)
|
| 546 |
+
|
| 547 |
+
**8. Migration from Scattered Chaos Configs**
|
| 548 |
+
- Extract chaos from 14+ existing files
|
| 549 |
+
- Convert to centralized presets
|
| 550 |
+
- Update builders to use ChaosConfigRegistry
|
| 551 |
+
- Deprecation warnings for inline chaos
|
| 552 |
+
|
| 553 |
+
### Success Criteria
|
| 554 |
+
- β
System handles 100+ capabilities
|
| 555 |
+
- β
Query performance < 100ms
|
| 556 |
+
- β
Complete documentation
|
| 557 |
+
- β
Migration plan for existing ODs
|
| 558 |
+
- β
**Chaos configuration API fully functional**
|
| 559 |
+
- β
**All scattered chaos configs migrated to presets**
|
| 560 |
+
- β
**Chaos impact analysis provides actionable insights**
|
| 561 |
+
|
| 562 |
+
**Effort**: Ongoing (2+ developers)
|
| 563 |
+
|
| 564 |
+
---
|
| 565 |
+
|
| 566 |
+
## Migration Strategy
|
| 567 |
+
|
| 568 |
+
### Backward Compatibility
|
| 569 |
+
|
| 570 |
+
**Phase 0-2**: New system runs alongside old
|
| 571 |
+
- Existing OD builders continue working
|
| 572 |
+
- New capability API available but optional
|
| 573 |
+
- No breaking changes
|
| 574 |
+
|
| 575 |
+
**Phase 3-4**: Encourage migration
|
| 576 |
+
- Document migration path
|
| 577 |
+
- Create capabilities for common ODs
|
| 578 |
+
- Deprecation warnings for old patterns
|
| 579 |
+
|
| 580 |
+
**Phase 5**: Complete migration
|
| 581 |
+
- All ODs accessible via capabilities
|
| 582 |
+
- Old builders deprecated but still functional
|
| 583 |
+
- Migration tooling to convert old β new
|
| 584 |
+
|
| 585 |
+
### Coexistence Pattern
|
| 586 |
+
|
| 587 |
+
```typescript
|
| 588 |
+
// Old way (still works)
|
| 589 |
+
const od = new GenericODBuilder()
|
| 590 |
+
.addStep(...)
|
| 591 |
+
.build();
|
| 592 |
+
|
| 593 |
+
// New way (recommended)
|
| 594 |
+
const capability = await capabilityRegistry.get("order-fulfillment");
|
| 595 |
+
await capability.execute(worldId, inputs);
|
| 596 |
+
```
|
| 597 |
+
|
| 598 |
+
---
|
| 599 |
+
|
| 600 |
+
## Phase 6: OD Variants (Future)
|
| 601 |
+
|
| 602 |
+
### Goal
|
| 603 |
+
Support multiple implementation approaches for the same capability through OD variants.
|
| 604 |
+
|
| 605 |
+
### What Researchers Can Do
|
| 606 |
+
- Choose OD variants (simple vs complex implementations)
|
| 607 |
+
- Select complexity-based variants for capabilities
|
| 608 |
+
- Use chaos-focused variants with different chaos presets
|
| 609 |
+
- Execute capabilities with variant-specific configurations
|
| 610 |
+
|
| 611 |
+
### Deliverables
|
| 612 |
+
|
| 613 |
+
**1. OD Variant Type System**
|
| 614 |
+
```typescript
|
| 615 |
+
// Capability can have multiple OD implementation variants
|
| 616 |
+
capability:
|
| 617 |
+
id: order-fulfillment
|
| 618 |
+
variants:
|
| 619 |
+
# Complexity variants
|
| 620 |
+
- id: order-fulfillment-simple
|
| 621 |
+
complexity: simple
|
| 622 |
+
odId: "order-fulfillment-simple-v1"
|
| 623 |
+
- id: order-fulfillment-standard
|
| 624 |
+
complexity: medium
|
| 625 |
+
odId: "order-fulfillment-standard-v1"
|
| 626 |
+
- id: order-fulfillment-complex
|
| 627 |
+
complexity: complex
|
| 628 |
+
odId: "order-fulfillment-complex-v1"
|
| 629 |
+
```
|
| 630 |
+
|
| 631 |
+
**2. Complexity Variants**
|
| 632 |
+
- Convert 3-5 high-value capabilities to variant model
|
| 633 |
+
- Each capability has 2-3 variants (simple/medium/complex)
|
| 634 |
+
- Different OD implementations for different complexity levels
|
| 635 |
+
|
| 636 |
+
**3. Chaos Variants**
|
| 637 |
+
```yaml
|
| 638 |
+
# Same workflow, different chaos configurations
|
| 639 |
+
capability:
|
| 640 |
+
variants:
|
| 641 |
+
- id: inventory-check-no-chaos
|
| 642 |
+
chaos: { enabled: false }
|
| 643 |
+
odId: "inventory-check-standard-v1"
|
| 644 |
+
- id: inventory-check-light
|
| 645 |
+
chaos: { preset: "light" }
|
| 646 |
+
odId: "inventory-check-standard-v1"
|
| 647 |
+
- id: inventory-check-aggressive
|
| 648 |
+
chaos: { preset: "aggressive" }
|
| 649 |
+
odId: "inventory-check-standard-v1"
|
| 650 |
+
```
|
| 651 |
+
|
| 652 |
+
**4. Variant Selection API**
|
| 653 |
+
```
|
| 654 |
+
GET /capabilities/:id/variants # List all variants
|
| 655 |
+
POST /capabilities/:id/execute
|
| 656 |
+
{
|
| 657 |
+
"worldId": "...",
|
| 658 |
+
"inputs": {...},
|
| 659 |
+
"options": {
|
| 660 |
+
"variantId": "order-fulfillment-complex" // or
|
| 661 |
+
"complexity": "medium"
|
| 662 |
+
}
|
| 663 |
+
}
|
| 664 |
+
```
|
| 665 |
+
|
| 666 |
+
### What We're NOT Building Yet
|
| 667 |
+
- β N:M composition (multiple ODs combined)
|
| 668 |
+
- β Dynamic variant generation
|
| 669 |
+
- β Variant recommendations
|
| 670 |
+
|
| 671 |
+
### Success Criteria
|
| 672 |
+
- β
3-5 capabilities with complexity variants
|
| 673 |
+
- β
Variant selection working (by ID and complexity)
|
| 674 |
+
- β
Chaos variants functional
|
| 675 |
+
- β
All variant tests passing
|
| 676 |
+
- β
API documentation complete
|
| 677 |
+
|
| 678 |
+
### Decision Point
|
| 679 |
+
**After Phase 6**: Is 1:N variant mapping sufficient? Do we need N:M composition?
|
| 680 |
+
|
| 681 |
+
**Effort**: 1-2 weeks (1 developer)
|
| 682 |
+
- Variant type system: 1 day
|
| 683 |
+
- Complexity variants (3-5 capabilities): 2-3 days
|
| 684 |
+
- Capability executor updates: 1 day
|
| 685 |
+
- Variant selection API: 1 day
|
| 686 |
+
- Chaos variants: 1 day
|
| 687 |
+
- Testing & docs: 1-2 days
|
| 688 |
+
|
| 689 |
+
**Note**: This phase is deprioritized and will be scheduled based on research needs after Phase 5 is complete.
|
| 690 |
+
|
| 691 |
+
---
|
| 692 |
+
|
| 693 |
+
## Risk Mitigation
|
| 694 |
+
|
| 695 |
+
### Major Risks
|
| 696 |
+
|
| 697 |
+
**1. Scope Creep**
|
| 698 |
+
- **Mitigation**: Each phase has clear "NOT building" list. Defer aggressively.
|
| 699 |
+
|
| 700 |
+
**2. Over-Engineering**
|
| 701 |
+
- **Mitigation**: Start simple, add complexity only when needed.
|
| 702 |
+
|
| 703 |
+
**3. Changing Requirements**
|
| 704 |
+
- **Mitigation**: Decision points after each phase. Can pivot based on learnings.
|
| 705 |
+
|
| 706 |
+
**4. Adoption**
|
| 707 |
+
- **Mitigation**: Backward compatibility. Researchers can adopt incrementally.
|
| 708 |
+
|
| 709 |
+
**5. Performance**
|
| 710 |
+
- **Mitigation**: Deferred to Phase 5. Measure early, optimize when needed.
|
| 711 |
+
|
| 712 |
+
### Flexibility Points
|
| 713 |
+
|
| 714 |
+
**Can Easily Change**:
|
| 715 |
+
- Number of capabilities (30 β 50 β 100)
|
| 716 |
+
- Sampling strategies
|
| 717 |
+
- Tag vocabulary
|
| 718 |
+
- Persona definitions
|
| 719 |
+
|
| 720 |
+
**Hard to Change Later**:
|
| 721 |
+
- Capability β OD relationship (1:1 vs 1:N vs N:M)
|
| 722 |
+
- Knowledge graph structure
|
| 723 |
+
- API design
|
| 724 |
+
|
| 725 |
+
**Strategy**: Lock hard-to-change early, keep easy-to-change flexible.
|
| 726 |
+
|
| 727 |
+
---
|
| 728 |
+
|
| 729 |
+
## Decision Points & Metrics
|
| 730 |
+
|
| 731 |
+
### After Each Phase
|
| 732 |
+
|
| 733 |
+
**Questions to Answer**:
|
| 734 |
+
1. Did we deliver value to researchers?
|
| 735 |
+
2. Were our assumptions correct?
|
| 736 |
+
3. What surprised us?
|
| 737 |
+
4. What should we adjust?
|
| 738 |
+
|
| 739 |
+
**Metrics to Track**:
|
| 740 |
+
- API usage (which endpoints are popular?)
|
| 741 |
+
- Capability execution counts (which are used most?)
|
| 742 |
+
- Error rates (where do things fail?)
|
| 743 |
+
- Researcher feedback (qualitative)
|
| 744 |
+
|
| 745 |
+
### Go/No-Go Criteria
|
| 746 |
+
|
| 747 |
+
**Continue to next phase if**:
|
| 748 |
+
- β
Current phase delivered promised value
|
| 749 |
+
- β
Researchers are using the features
|
| 750 |
+
- β
No major architectural issues discovered
|
| 751 |
+
|
| 752 |
+
**Pivot or adjust if**:
|
| 753 |
+
- β Low adoption
|
| 754 |
+
- β Fundamental design flaw found
|
| 755 |
+
- β Requirements changed significantly
|
| 756 |
+
|
| 757 |
+
---
|
| 758 |
+
|
| 759 |
+
## Effort Summary
|
| 760 |
+
|
| 761 |
+
| Phase | Duration | Team Size | Focus |
|
| 762 |
+
|-------|----------|-----------|-------|
|
| 763 |
+
| Phase 0: Walking Skeleton | 2-3 weeks | 1 dev | Proof of concept |
|
| 764 |
+
| Phase 1: Core System | 3-4 weeks | 1-2 devs | Capability browsing |
|
| 765 |
+
| Phase 2: World Config | 2-3 weeks | 1 dev | Customization |
|
| 766 |
+
| Phase 3: Knowledge Graph | 3-4 weeks | 1-2 devs | Validation |
|
| 767 |
+
| Phase 4: Advanced Features | 3-4 weeks | 2 devs | Personas & chaos |
|
| 768 |
+
| Phase 5: Polish & Scale | Ongoing | 2+ devs | Production-ready |
|
| 769 |
+
| Phase 6: OD Variants | 1-2 weeks | 1 dev | Variant system (Future) |
|
| 770 |
+
|
| 771 |
+
**Total to MVP (Phase 0-2)**: 7-10 weeks
|
| 772 |
+
**Total to Full Feature Set (Phase 0-4)**: 13-17 weeks (~3-4 months)
|
| 773 |
+
**Total with OD Variants (Phase 0-6)**: 14-19 weeks (~3.5-5 months)
|
| 774 |
+
|
| 775 |
+
---
|
| 776 |
+
|
| 777 |
+
## Success Metrics
|
| 778 |
+
|
| 779 |
+
### Phase 0 Success
|
| 780 |
+
- Concept validated
|
| 781 |
+
- Team aligned on approach
|
| 782 |
+
|
| 783 |
+
### Phase 1-2 Success
|
| 784 |
+
- 10+ researchers using capability API
|
| 785 |
+
- 50+ capability executions per week
|
| 786 |
+
|
| 787 |
+
### Phase 3-4 Success
|
| 788 |
+
- Dependency validation prevents 80% of execution errors
|
| 789 |
+
- Personas used in 50% of world configurations
|
| 790 |
+
|
| 791 |
+
### Phase 5 Success
|
| 792 |
+
- 100+ capabilities defined
|
| 793 |
+
- < 100ms query performance
|
| 794 |
+
- Migration complete for 80% of existing ODs
|
| 795 |
+
|
| 796 |
+
---
|
| 797 |
+
|
| 798 |
+
## Related Documents
|
| 799 |
+
|
| 800 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - Architecture we're implementing
|
| 801 |
+
- [06. Open Questions & Decisions](./06-open-questions.md) - Decisions guiding this roadmap
|
| 802 |
+
- [07. Chaos Integration](./07-chaos-integration.md) - How chaos integrates with OD architecture
|
| 803 |
+
- [04. Taxonomy & Organization](./04-taxonomy-organization.md) - How capabilities are organized
|
| 804 |
+
- [05. Sampling & World Config](./05-sampling-world-config.md) - World configuration details
|
| 805 |
+
- [Chaos Management](../chaos/chaos-management.md) - Complete chaos system design
|
| 806 |
+
|
| 807 |
+
---
|
| 808 |
+
|
| 809 |
+
## Next Steps
|
| 810 |
+
|
| 811 |
+
1. **Review roadmap** with team and stakeholders
|
| 812 |
+
2. **Get approval** for Phase 0 start
|
| 813 |
+
3. **Create Phase 0 task breakdown** (detailed stories)
|
| 814 |
+
4. **Assign developer(s)** to Phase 0
|
| 815 |
+
5. **Set up** project tracking (GitHub issues, board, etc.)
|
| 816 |
+
6. **Start Phase 0 implementation**
|
| 817 |
+
7. **Review progress weekly**, adjust as needed
|
| 818 |
+
|
| 819 |
+
**First Milestone**: Complete Phase 0 in 2-3 weeks, validate approach.
|
docs/od-architecture/09-implementation-tasks.md
ADDED
|
@@ -0,0 +1,1548 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 09. Implementation Tasks Tracker
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This document serves as a master index for all implementation tasks across phases. Detailed task specifications are maintained in phase-specific files within the `implementation/` directory.
|
| 6 |
+
|
| 7 |
+
**Last Updated**: 2025-11-21
|
| 8 |
+
|
| 9 |
+
**How to Use**:
|
| 10 |
+
1. Navigate to the appropriate phase folder: `implementation/phaseN/`
|
| 11 |
+
2. Open `tasks.md` for detailed tickets
|
| 12 |
+
3. Pick a ticket with status π TODO
|
| 13 |
+
4. Update status to π§ IN PROGRESS
|
| 14 |
+
5. Complete the work according to acceptance criteria
|
| 15 |
+
6. Update status to β
DONE
|
| 16 |
+
|
| 17 |
+
**Status Key**:
|
| 18 |
+
- π **TODO**: Not started
|
| 19 |
+
- π§ **IN PROGRESS**: Currently being worked on
|
| 20 |
+
- β
**DONE**: Completed and tested
|
| 21 |
+
- β **BLOCKED**: Waiting on dependencies
|
| 22 |
+
- βΈοΈ **ON HOLD**: Paused, will resume later
|
| 23 |
+
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
## Phase Index
|
| 27 |
+
|
| 28 |
+
### Phase 0: Walking Skeleton (2-3 weeks)
|
| 29 |
+
|
| 30 |
+
**Epic**: MORPH-100 - Walking Skeleton
|
| 31 |
+
|
| 32 |
+
**Goal**: Prove the concept works end-to-end with minimal implementation
|
| 33 |
+
|
| 34 |
+
**Status**: β
**COMPLETED**
|
| 35 |
+
|
| 36 |
+
**Documents**:
|
| 37 |
+
- [Tasks](./implementation/phase0/tasks.md) - Detailed 12 tickets
|
| 38 |
+
- [Demo Script](./implementation/phase0/demo.md) - Walkthrough
|
| 39 |
+
- [Test Results](./implementation/phase0/test-results.md) - Test execution results
|
| 40 |
+
|
| 41 |
+
**Summary**:
|
| 42 |
+
- 12 tickets, ~21 story points
|
| 43 |
+
- 5 capabilities implemented
|
| 44 |
+
- API endpoints functional
|
| 45 |
+
- End-to-end flow validated
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
### Phase 1: Core Capability System (3-4 weeks)
|
| 50 |
+
|
| 51 |
+
**Epic**: MORPH-200 - Core Capability System
|
| 52 |
+
|
| 53 |
+
**Goal**: Expand to 4 working capabilities with real OD execution, filtering, and chaos support
|
| 54 |
+
|
| 55 |
+
**Status**: β
**COMPLETED**
|
| 56 |
+
|
| 57 |
+
**Documents**:
|
| 58 |
+
- [Tasks](./implementation/phase1/tasks.md) - Detailed 20 tickets
|
| 59 |
+
- [Demo Script](./implementation/phase1/demo-script.md) - Walkthrough
|
| 60 |
+
- [Test Results](./implementation/phase1/test-results.md) - Test execution results
|
| 61 |
+
- [Retrospective](./implementation/phase1/retrospective.md) - Lessons learned
|
| 62 |
+
|
| 63 |
+
**Summary**:
|
| 64 |
+
- 20 tickets, ~57 story points
|
| 65 |
+
- 4 working capabilities: inventory-check, shipment-tracking, equipment-availability-check, dock-appointment-scheduling
|
| 66 |
+
- Real OD execution with chaos engineering
|
| 67 |
+
- Search/filtering APIs functional
|
| 68 |
+
- Performance baselines established
|
| 69 |
+
- **Decision**: β
Proceed to Phase 2 (World Configuration)
|
| 70 |
+
|
| 71 |
+
---
|
| 72 |
+
|
| 73 |
+
### Phase 2: World Configuration (2.5-3 weeks)
|
| 74 |
+
|
| 75 |
+
**Epic**: MORPH-300 - World Configuration
|
| 76 |
+
|
| 77 |
+
**Goal**: Enable researchers to create custom worlds with capability sampling and chaos configuration
|
| 78 |
+
|
| 79 |
+
**Status**: π **TODO** (Ready to Start)
|
| 80 |
+
|
| 81 |
+
**Documents**:
|
| 82 |
+
- [Tasks](./implementation/phase2/tasks.md) - Detailed 10 tickets (REVISED)
|
| 83 |
+
|
| 84 |
+
**Summary**:
|
| 85 |
+
- 10 tickets, 22 story points (revised from 30 - **27% effort reduction**)
|
| 86 |
+
- Extends existing World model (leverages 40% existing infrastructure)
|
| 87 |
+
- Sampling strategies: filter, random, seeded
|
| 88 |
+
- World-level chaos configuration with API endpoints
|
| 89 |
+
- Capability-level chaos overrides
|
| 90 |
+
- **Critical bug fix**: Capability executor chaos integration
|
| 91 |
+
- Reproducibility via seeds for sampling and chaos
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
### Phase 3-5: Future Phases
|
| 96 |
+
|
| 97 |
+
**Status**: π **LOCKED** (will be created after Phase 2 completion)
|
| 98 |
+
|
| 99 |
+
See [08. Implementation Roadmap](./08-implementation-roadmap.md) for high-level phase definitions.
|
| 100 |
+
|
| 101 |
+
---
|
| 102 |
+
|
| 103 |
+
## Quick Navigation
|
| 104 |
+
|
| 105 |
+
| Phase | Status | Tasks | Demo | Tests | Retro |
|
| 106 |
+
|-------|--------|-------|------|-------|-------|
|
| 107 |
+
| Phase 0 | β
DONE | [tasks](./implementation/phase0/tasks.md) | [demo](./implementation/phase0/demo.md) | [tests](./implementation/phase0/test-results.md) | - |
|
| 108 |
+
| Phase 1 | β
DONE | [tasks](./implementation/phase1/tasks.md) | [demo](./implementation/phase1/demo-script.md) | [tests](./implementation/phase1/test-results.md) | [retro](./implementation/phase1/retrospective.md) |
|
| 109 |
+
| Phase 2 | π TODO | [tasks](./implementation/phase2/tasks.md) | - | - | - |
|
| 110 |
+
| Phase 3+ | π LOCKED | - | - | - | - |
|
| 111 |
+
|
| 112 |
+
---
|
| 113 |
+
|
| 114 |
+
## Historical Detail (Archived)
|
| 115 |
+
|
| 116 |
+
The content below has been moved to phase-specific `tasks.md` files. This section is kept for reference only.
|
| 117 |
+
|
| 118 |
+
<details>
|
| 119 |
+
<summary>Phase 0 Tickets (ARCHIVED - See implementation/phase0/tasks.md)</summary>
|
| 120 |
+
|
| 121 |
+
### MORPH-101: Project Setup & Type Definitions
|
| 122 |
+
|
| 123 |
+
**Type**: Task
|
| 124 |
+
**Priority**: High
|
| 125 |
+
**Estimate**: 2 points (1 day)
|
| 126 |
+
**Status**: β
DONE
|
| 127 |
+
**Completed**: 2025-11-19
|
| 128 |
+
|
| 129 |
+
**Description**:
|
| 130 |
+
Set up project structure and create TypeScript type definitions for capabilities.
|
| 131 |
+
|
| 132 |
+
**Acceptance Criteria**:
|
| 133 |
+
- [ ] Folder structure created: `src/capabilities/`
|
| 134 |
+
- [ ] Type definitions file created: `src/types/capability.type.ts`
|
| 135 |
+
- [ ] Core types defined: `Capability`, `CapabilityMetadata`, `CapabilityTags`
|
| 136 |
+
- [ ] Types compile without errors
|
| 137 |
+
- [ ] Types exported properly
|
| 138 |
+
|
| 139 |
+
**Technical Details**:
|
| 140 |
+
```typescript
|
| 141 |
+
// src/types/capability.type.ts
|
| 142 |
+
export interface Capability {
|
| 143 |
+
id: string;
|
| 144 |
+
name: string;
|
| 145 |
+
description: string;
|
| 146 |
+
tags: CapabilityTags;
|
| 147 |
+
odId: string; // Maps to existing OD
|
| 148 |
+
version: string;
|
| 149 |
+
metadata?: CapabilityMetadata;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
export interface CapabilityTags {
|
| 153 |
+
domain: string[];
|
| 154 |
+
complexity: 'simple' | 'medium' | 'complex';
|
| 155 |
+
services: string[];
|
| 156 |
+
personas?: string[];
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
export interface CapabilityMetadata {
|
| 160 |
+
author?: string;
|
| 161 |
+
createdAt?: Date;
|
| 162 |
+
estimatedDuration?: number;
|
| 163 |
+
}
|
| 164 |
+
```
|
| 165 |
+
|
| 166 |
+
**Dependencies**: None
|
| 167 |
+
|
| 168 |
+
**Testing**:
|
| 169 |
+
- Types compile successfully
|
| 170 |
+
- Can import types in other files
|
| 171 |
+
|
| 172 |
+
---
|
| 173 |
+
|
| 174 |
+
### MORPH-102: Create 5 Hardcoded Capabilities
|
| 175 |
+
|
| 176 |
+
**Type**: Task
|
| 177 |
+
**Priority**: High
|
| 178 |
+
**Estimate**: 3 points (1 day)
|
| 179 |
+
**Status**: β
DONE
|
| 180 |
+
**Completed**: 2025-11-19
|
| 181 |
+
|
| 182 |
+
**Description**:
|
| 183 |
+
Create a hardcoded catalog of 5 example capabilities spanning different domains and complexity levels.
|
| 184 |
+
|
| 185 |
+
**Acceptance Criteria**:
|
| 186 |
+
- [ ] File created: `src/capabilities/catalog.ts`
|
| 187 |
+
- [ ] 5 capabilities defined with complete metadata
|
| 188 |
+
- [ ] Covers at least 3 different domains
|
| 189 |
+
- [ ] Mix of simple, medium, complex
|
| 190 |
+
- [ ] Each capability maps to an existing OD
|
| 191 |
+
- [ ] Data exported as constant array
|
| 192 |
+
|
| 193 |
+
**Technical Details**:
|
| 194 |
+
```typescript
|
| 195 |
+
// src/capabilities/catalog.ts
|
| 196 |
+
import { Capability } from '../types/capability.type';
|
| 197 |
+
|
| 198 |
+
export const INITIAL_CAPABILITIES: Capability[] = [
|
| 199 |
+
{
|
| 200 |
+
id: 'order-fulfillment-simple',
|
| 201 |
+
name: 'Order Fulfillment (Simple)',
|
| 202 |
+
description: 'Process customer order with basic workflow',
|
| 203 |
+
tags: {
|
| 204 |
+
domain: ['fulfillment', 'order-processing'],
|
| 205 |
+
complexity: 'simple',
|
| 206 |
+
services: ['erp', 'wms']
|
| 207 |
+
},
|
| 208 |
+
odId: 'order-fulfillment-standard-v1', // Existing OD
|
| 209 |
+
version: '1.0.0'
|
| 210 |
+
},
|
| 211 |
+
// ... 4 more
|
| 212 |
+
];
|
| 213 |
+
```
|
| 214 |
+
|
| 215 |
+
**Capabilities to Create**:
|
| 216 |
+
1. **order-fulfillment-simple** (Fulfillment, Simple, ERP+WMS)
|
| 217 |
+
2. **inventory-check** (Inventory, Simple, WMS)
|
| 218 |
+
3. **inbound-receiving** (Warehousing, Medium, TMS+WMS)
|
| 219 |
+
4. **edi-850-generation** (EDI, Medium, EDI+ERP)
|
| 220 |
+
5. **shipment-tracking** (Transportation, Simple, TMS)
|
| 221 |
+
|
| 222 |
+
**Dependencies**: MORPH-101
|
| 223 |
+
|
| 224 |
+
**Testing**:
|
| 225 |
+
- Catalog imports successfully
|
| 226 |
+
- All 5 capabilities have required fields
|
| 227 |
+
- OD IDs reference existing ODs
|
| 228 |
+
|
| 229 |
+
---
|
| 230 |
+
|
| 231 |
+
### MORPH-103: Build Capability Catalog Service
|
| 232 |
+
|
| 233 |
+
**Type**: Story
|
| 234 |
+
**Priority**: High
|
| 235 |
+
**Estimate**: 3 points (1.5 days)
|
| 236 |
+
**Status**: β
DONE
|
| 237 |
+
**Completed**: 2025-11-19
|
| 238 |
+
|
| 239 |
+
**Description**:
|
| 240 |
+
Create an in-memory capability catalog service with basic query methods.
|
| 241 |
+
|
| 242 |
+
**Acceptance Criteria**:
|
| 243 |
+
- [ ] File created: `src/services/capability-catalog.service.ts`
|
| 244 |
+
- [ ] `CapabilityCatalog` class implemented
|
| 245 |
+
- [ ] Method: `getAll()` returns all capabilities
|
| 246 |
+
- [ ] Method: `getById(id)` returns single capability or null
|
| 247 |
+
- [ ] Method: `filter(tags)` returns filtered capabilities
|
| 248 |
+
- [ ] Service is a singleton
|
| 249 |
+
- [ ] Loads from hardcoded catalog on initialization
|
| 250 |
+
|
| 251 |
+
**Technical Details**:
|
| 252 |
+
```typescript
|
| 253 |
+
// src/services/capability-catalog.service.ts
|
| 254 |
+
import { Capability, CapabilityTags } from '../types/capability.type';
|
| 255 |
+
import { INITIAL_CAPABILITIES } from '../capabilities/catalog';
|
| 256 |
+
|
| 257 |
+
class CapabilityCatalog {
|
| 258 |
+
private capabilities: Map<string, Capability>;
|
| 259 |
+
|
| 260 |
+
constructor() {
|
| 261 |
+
this.capabilities = new Map();
|
| 262 |
+
this.loadCapabilities();
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
private loadCapabilities(): void {
|
| 266 |
+
INITIAL_CAPABILITIES.forEach(cap => {
|
| 267 |
+
this.capabilities.set(cap.id, cap);
|
| 268 |
+
});
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
getAll(): Capability[] {
|
| 272 |
+
return Array.from(this.capabilities.values());
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
getById(id: string): Capability | null {
|
| 276 |
+
return this.capabilities.get(id) || null;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
filter(filters: Partial<CapabilityTags>): Capability[] {
|
| 280 |
+
return this.getAll().filter(cap => {
|
| 281 |
+
if (filters.domain && !filters.domain.some(d => cap.tags.domain.includes(d))) {
|
| 282 |
+
return false;
|
| 283 |
+
}
|
| 284 |
+
if (filters.complexity && cap.tags.complexity !== filters.complexity) {
|
| 285 |
+
return false;
|
| 286 |
+
}
|
| 287 |
+
if (filters.services && !filters.services.every(s => cap.tags.services.includes(s))) {
|
| 288 |
+
return false;
|
| 289 |
+
}
|
| 290 |
+
return true;
|
| 291 |
+
});
|
| 292 |
+
}
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
// Singleton
|
| 296 |
+
export const capabilityCatalog = new CapabilityCatalog();
|
| 297 |
+
```
|
| 298 |
+
|
| 299 |
+
**Dependencies**: MORPH-101, MORPH-102
|
| 300 |
+
|
| 301 |
+
**Testing**:
|
| 302 |
+
- `getAll()` returns 5 capabilities
|
| 303 |
+
- `getById('order-fulfillment-simple')` returns correct capability
|
| 304 |
+
- `filter({ domain: ['fulfillment'] })` returns matching capabilities
|
| 305 |
+
- `filter({ complexity: 'simple' })` returns 3 simple capabilities
|
| 306 |
+
|
| 307 |
+
---
|
| 308 |
+
|
| 309 |
+
### MORPH-104: Create GET /api/capabilities Endpoint
|
| 310 |
+
|
| 311 |
+
**Type**: Story
|
| 312 |
+
**Priority**: High
|
| 313 |
+
**Estimate**: 2 points (1 day)
|
| 314 |
+
**Status**: β
DONE
|
| 315 |
+
**Completed**: 2025-11-19
|
| 316 |
+
|
| 317 |
+
**Description**:
|
| 318 |
+
Create REST API endpoint to list all capabilities with optional filtering.
|
| 319 |
+
|
| 320 |
+
**Acceptance Criteria**:
|
| 321 |
+
- [ ] Route created: `src/routes/capabilities.route.ts`
|
| 322 |
+
- [ ] `GET /api/capabilities` returns all capabilities
|
| 323 |
+
- [ ] Query params supported: `domain`, `complexity`, `services`
|
| 324 |
+
- [ ] Returns JSON array of capabilities
|
| 325 |
+
- [ ] Proper HTTP status codes (200, 400)
|
| 326 |
+
- [ ] Route registered in main app
|
| 327 |
+
|
| 328 |
+
**Technical Details**:
|
| 329 |
+
```typescript
|
| 330 |
+
// src/routes/capabilities.route.ts
|
| 331 |
+
import { Router } from 'express';
|
| 332 |
+
import { capabilityCatalog } from '../services/capability-catalog.service';
|
| 333 |
+
|
| 334 |
+
const router = Router();
|
| 335 |
+
|
| 336 |
+
router.get('/', (req, res) => {
|
| 337 |
+
try {
|
| 338 |
+
const { domain, complexity, services } = req.query;
|
| 339 |
+
|
| 340 |
+
const filters: any = {};
|
| 341 |
+
if (domain) filters.domain = Array.isArray(domain) ? domain : [domain];
|
| 342 |
+
if (complexity) filters.complexity = complexity;
|
| 343 |
+
if (services) filters.services = Array.isArray(services) ? services : [services];
|
| 344 |
+
|
| 345 |
+
const capabilities = Object.keys(filters).length > 0
|
| 346 |
+
? capabilityCatalog.filter(filters)
|
| 347 |
+
: capabilityCatalog.getAll();
|
| 348 |
+
|
| 349 |
+
res.json(capabilities);
|
| 350 |
+
} catch (error) {
|
| 351 |
+
res.status(400).json({ error: error.message });
|
| 352 |
+
}
|
| 353 |
+
});
|
| 354 |
+
|
| 355 |
+
export default router;
|
| 356 |
+
```
|
| 357 |
+
|
| 358 |
+
**API Examples**:
|
| 359 |
+
```bash
|
| 360 |
+
# Get all capabilities
|
| 361 |
+
GET /api/capabilities
|
| 362 |
+
β Returns: [5 capabilities]
|
| 363 |
+
|
| 364 |
+
# Filter by domain
|
| 365 |
+
GET /api/capabilities?domain=fulfillment
|
| 366 |
+
β Returns: [1-2 capabilities]
|
| 367 |
+
|
| 368 |
+
# Filter by complexity
|
| 369 |
+
GET /api/capabilities?complexity=simple
|
| 370 |
+
β Returns: [3 capabilities]
|
| 371 |
+
|
| 372 |
+
# Multiple filters
|
| 373 |
+
GET /api/capabilities?domain=fulfillment&complexity=simple
|
| 374 |
+
β Returns: [1 capability]
|
| 375 |
+
```
|
| 376 |
+
|
| 377 |
+
**Dependencies**: MORPH-103
|
| 378 |
+
|
| 379 |
+
**Testing**:
|
| 380 |
+
- Manual curl/Postman tests
|
| 381 |
+
- Returns correct number of capabilities
|
| 382 |
+
- Filtering works correctly
|
| 383 |
+
- Invalid filters return 400
|
| 384 |
+
|
| 385 |
+
---
|
| 386 |
+
|
| 387 |
+
### MORPH-105: Create GET /api/capabilities/:id Endpoint
|
| 388 |
+
|
| 389 |
+
**Type**: Task
|
| 390 |
+
**Priority**: High
|
| 391 |
+
**Estimate**: 1 point (0.5 days)
|
| 392 |
+
**Status**: β
DONE
|
| 393 |
+
**Completed**: 2025-11-19
|
| 394 |
+
|
| 395 |
+
**Description**:
|
| 396 |
+
Create REST API endpoint to get details of a single capability.
|
| 397 |
+
|
| 398 |
+
**Acceptance Criteria**:
|
| 399 |
+
- [ ] `GET /api/capabilities/:id` returns capability details
|
| 400 |
+
- [ ] Returns 404 if capability not found
|
| 401 |
+
- [ ] Returns 200 with capability JSON if found
|
| 402 |
+
- [ ] Includes all capability metadata
|
| 403 |
+
|
| 404 |
+
**Technical Details**:
|
| 405 |
+
```typescript
|
| 406 |
+
// Add to src/routes/capabilities.route.ts
|
| 407 |
+
router.get('/:id', (req, res) => {
|
| 408 |
+
const { id } = req.params;
|
| 409 |
+
const capability = capabilityCatalog.getById(id);
|
| 410 |
+
|
| 411 |
+
if (!capability) {
|
| 412 |
+
return res.status(404).json({ error: 'Capability not found' });
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
res.json(capability);
|
| 416 |
+
});
|
| 417 |
+
```
|
| 418 |
+
|
| 419 |
+
**API Examples**:
|
| 420 |
+
```bash
|
| 421 |
+
# Get capability details
|
| 422 |
+
GET /api/capabilities/order-fulfillment-simple
|
| 423 |
+
β Returns: { id: "order-fulfillment-simple", ... }
|
| 424 |
+
|
| 425 |
+
# Not found
|
| 426 |
+
GET /api/capabilities/non-existent
|
| 427 |
+
β Returns 404: { error: "Capability not found" }
|
| 428 |
+
```
|
| 429 |
+
|
| 430 |
+
**Dependencies**: MORPH-104
|
| 431 |
+
|
| 432 |
+
**Testing**:
|
| 433 |
+
- Valid ID returns capability
|
| 434 |
+
- Invalid ID returns 404
|
| 435 |
+
- Response includes all fields
|
| 436 |
+
|
| 437 |
+
---
|
| 438 |
+
|
| 439 |
+
### MORPH-106: Build Capability β OD Mapper Service
|
| 440 |
+
|
| 441 |
+
**Type**: Story
|
| 442 |
+
**Priority**: High
|
| 443 |
+
**Estimate**: 2 points (1 day)
|
| 444 |
+
**Status**: β
DONE
|
| 445 |
+
**Completed**: 2025-11-19
|
| 446 |
+
|
| 447 |
+
**Description**:
|
| 448 |
+
Create service that maps capability IDs to existing OD builders and executes them.
|
| 449 |
+
|
| 450 |
+
**Acceptance Criteria**:
|
| 451 |
+
- [ ] File created: `src/services/capability-executor.service.ts`
|
| 452 |
+
- [ ] `CapabilityExecutor` class implemented
|
| 453 |
+
- [ ] Method: `execute(capabilityId, inputs)` runs OD
|
| 454 |
+
- [ ] Uses existing OD builders (no refactoring)
|
| 455 |
+
- [ ] Returns OD execution results
|
| 456 |
+
- [ ] Handles errors gracefully
|
| 457 |
+
|
| 458 |
+
**Technical Details**:
|
| 459 |
+
```typescript
|
| 460 |
+
// src/services/capability-executor.service.ts
|
| 461 |
+
import { capabilityCatalog } from './capability-catalog.service';
|
| 462 |
+
import { executeOD } from '../operational-descriptor/executor.od';
|
| 463 |
+
|
| 464 |
+
export class CapabilityExecutor {
|
| 465 |
+
async execute(
|
| 466 |
+
capabilityId: string,
|
| 467 |
+
worldId: string,
|
| 468 |
+
inputs: any
|
| 469 |
+
): Promise<any> {
|
| 470 |
+
// 1. Get capability
|
| 471 |
+
const capability = capabilityCatalog.getById(capabilityId);
|
| 472 |
+
if (!capability) {
|
| 473 |
+
throw new Error(`Capability not found: ${capabilityId}`);
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
// 2. Get OD (for now, assume OD exists in registry)
|
| 477 |
+
const odId = capability.odId;
|
| 478 |
+
|
| 479 |
+
// 3. Execute OD using existing executor
|
| 480 |
+
const result = await executeOD(odId, worldId, inputs);
|
| 481 |
+
|
| 482 |
+
return {
|
| 483 |
+
capabilityId,
|
| 484 |
+
odId,
|
| 485 |
+
worldId,
|
| 486 |
+
result,
|
| 487 |
+
executedAt: new Date()
|
| 488 |
+
};
|
| 489 |
+
}
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
export const capabilityExecutor = new CapabilityExecutor();
|
| 493 |
+
```
|
| 494 |
+
|
| 495 |
+
**Dependencies**: MORPH-103
|
| 496 |
+
|
| 497 |
+
**Testing**:
|
| 498 |
+
- Can execute order-fulfillment-simple
|
| 499 |
+
- Returns proper result structure
|
| 500 |
+
- Throws error for non-existent capability
|
| 501 |
+
- OD execution works correctly
|
| 502 |
+
|
| 503 |
+
---
|
| 504 |
+
|
| 505 |
+
### MORPH-107: Create POST /api/capabilities/:id/execute Endpoint
|
| 506 |
+
|
| 507 |
+
**Type**: Story
|
| 508 |
+
**Priority**: High
|
| 509 |
+
**Estimate**: 2 points (1 day)
|
| 510 |
+
**Status**: β
DONE
|
| 511 |
+
**Completed**: 2025-11-19
|
| 512 |
+
|
| 513 |
+
**Description**:
|
| 514 |
+
Create REST API endpoint to execute a capability.
|
| 515 |
+
|
| 516 |
+
**Acceptance Criteria**:
|
| 517 |
+
- [ ] `POST /api/capabilities/:id/execute` endpoint created
|
| 518 |
+
- [ ] Accepts `worldId` and `inputs` in request body
|
| 519 |
+
- [ ] Executes capability via CapabilityExecutor
|
| 520 |
+
- [ ] Returns execution results
|
| 521 |
+
- [ ] Proper error handling (404, 400, 500)
|
| 522 |
+
- [ ] Request validation
|
| 523 |
+
|
| 524 |
+
**Technical Details**:
|
| 525 |
+
```typescript
|
| 526 |
+
// Add to src/routes/capabilities.route.ts
|
| 527 |
+
router.post('/:id/execute', async (req, res) => {
|
| 528 |
+
try {
|
| 529 |
+
const { id } = req.params;
|
| 530 |
+
const { worldId, inputs } = req.body;
|
| 531 |
+
|
| 532 |
+
// Validation
|
| 533 |
+
if (!worldId) {
|
| 534 |
+
return res.status(400).json({ error: 'worldId is required' });
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
// Execute
|
| 538 |
+
const result = await capabilityExecutor.execute(id, worldId, inputs);
|
| 539 |
+
|
| 540 |
+
res.json(result);
|
| 541 |
+
} catch (error) {
|
| 542 |
+
if (error.message.includes('not found')) {
|
| 543 |
+
return res.status(404).json({ error: error.message });
|
| 544 |
+
}
|
| 545 |
+
res.status(500).json({ error: error.message });
|
| 546 |
+
}
|
| 547 |
+
});
|
| 548 |
+
```
|
| 549 |
+
|
| 550 |
+
**API Examples**:
|
| 551 |
+
```bash
|
| 552 |
+
# Execute capability
|
| 553 |
+
POST /api/capabilities/order-fulfillment-simple/execute
|
| 554 |
+
Body: {
|
| 555 |
+
"worldId": "world-123",
|
| 556 |
+
"inputs": {
|
| 557 |
+
"orderId": "ORD-001"
|
| 558 |
+
}
|
| 559 |
+
}
|
| 560 |
+
β Returns: {
|
| 561 |
+
"capabilityId": "order-fulfillment-simple",
|
| 562 |
+
"odId": "order-fulfillment-standard-v1",
|
| 563 |
+
"result": { ... },
|
| 564 |
+
"executedAt": "2025-11-14T10:30:00Z"
|
| 565 |
+
}
|
| 566 |
+
```
|
| 567 |
+
|
| 568 |
+
**Dependencies**: MORPH-106
|
| 569 |
+
|
| 570 |
+
**Testing**:
|
| 571 |
+
- Successful execution returns results
|
| 572 |
+
- Missing worldId returns 400
|
| 573 |
+
- Invalid capability ID returns 404
|
| 574 |
+
- OD execution errors return 500
|
| 575 |
+
|
| 576 |
+
---
|
| 577 |
+
|
| 578 |
+
### MORPH-108: Register Capability Routes in App
|
| 579 |
+
|
| 580 |
+
**Type**: Task
|
| 581 |
+
**Priority**: High
|
| 582 |
+
**Estimate**: 1 point (0.5 days)
|
| 583 |
+
**Status**: β
DONE
|
| 584 |
+
**Completed**: 2025-11-19
|
| 585 |
+
|
| 586 |
+
**Description**:
|
| 587 |
+
Register the new capability routes in the main Express app.
|
| 588 |
+
|
| 589 |
+
**Acceptance Criteria**:
|
| 590 |
+
- [ ] Capability routes mounted in main app
|
| 591 |
+
- [ ] Routes accessible via `/api/capabilities`
|
| 592 |
+
- [ ] Routes work in development environment
|
| 593 |
+
- [ ] No breaking changes to existing routes
|
| 594 |
+
|
| 595 |
+
**Technical Details**:
|
| 596 |
+
```typescript
|
| 597 |
+
// In main app file (e.g., src/app.ts or src/index.ts)
|
| 598 |
+
import capabilitiesRouter from './routes/capabilities.route';
|
| 599 |
+
|
| 600 |
+
// Register routes
|
| 601 |
+
app.use('/api/capabilities', capabilitiesRouter);
|
| 602 |
+
```
|
| 603 |
+
|
| 604 |
+
**Dependencies**: MORPH-107
|
| 605 |
+
|
| 606 |
+
**Testing**:
|
| 607 |
+
- All capability endpoints accessible
|
| 608 |
+
- Existing routes still work
|
| 609 |
+
- Server starts without errors
|
| 610 |
+
|
| 611 |
+
---
|
| 612 |
+
|
| 613 |
+
### MORPH-109: Integration Testing
|
| 614 |
+
|
| 615 |
+
**Type**: Task
|
| 616 |
+
**Priority**: Medium
|
| 617 |
+
**Estimate**: 2 points (1 day)
|
| 618 |
+
**Status**: βΈοΈ ON HOLD
|
| 619 |
+
**Note**: Requires MongoDB setup - will complete after environment setup
|
| 620 |
+
|
| 621 |
+
**Description**:
|
| 622 |
+
Create integration tests for the end-to-end capability flow.
|
| 623 |
+
|
| 624 |
+
**Acceptance Criteria**:
|
| 625 |
+
- [ ] Test file created: `tests/capabilities.integration.test.ts`
|
| 626 |
+
- [ ] Test: List all capabilities
|
| 627 |
+
- [ ] Test: Get capability by ID
|
| 628 |
+
- [ ] Test: Filter capabilities
|
| 629 |
+
- [ ] Test: Execute capability end-to-end
|
| 630 |
+
- [ ] All tests pass
|
| 631 |
+
|
| 632 |
+
**Technical Details**:
|
| 633 |
+
```typescript
|
| 634 |
+
// tests/capabilities.integration.test.ts
|
| 635 |
+
describe('Capabilities API', () => {
|
| 636 |
+
describe('GET /api/capabilities', () => {
|
| 637 |
+
it('should return all 5 capabilities', async () => {
|
| 638 |
+
const res = await request(app).get('/api/capabilities');
|
| 639 |
+
expect(res.status).toBe(200);
|
| 640 |
+
expect(res.body).toHaveLength(5);
|
| 641 |
+
});
|
| 642 |
+
|
| 643 |
+
it('should filter by domain', async () => {
|
| 644 |
+
const res = await request(app)
|
| 645 |
+
.get('/api/capabilities?domain=fulfillment');
|
| 646 |
+
expect(res.status).toBe(200);
|
| 647 |
+
expect(res.body.every(c => c.tags.domain.includes('fulfillment'))).toBe(true);
|
| 648 |
+
});
|
| 649 |
+
});
|
| 650 |
+
|
| 651 |
+
describe('GET /api/capabilities/:id', () => {
|
| 652 |
+
it('should return capability details', async () => {
|
| 653 |
+
const res = await request(app)
|
| 654 |
+
.get('/api/capabilities/order-fulfillment-simple');
|
| 655 |
+
expect(res.status).toBe(200);
|
| 656 |
+
expect(res.body.id).toBe('order-fulfillment-simple');
|
| 657 |
+
});
|
| 658 |
+
|
| 659 |
+
it('should return 404 for invalid ID', async () => {
|
| 660 |
+
const res = await request(app)
|
| 661 |
+
.get('/api/capabilities/invalid');
|
| 662 |
+
expect(res.status).toBe(404);
|
| 663 |
+
});
|
| 664 |
+
});
|
| 665 |
+
|
| 666 |
+
describe('POST /api/capabilities/:id/execute', () => {
|
| 667 |
+
it('should execute capability', async () => {
|
| 668 |
+
const res = await request(app)
|
| 669 |
+
.post('/api/capabilities/order-fulfillment-simple/execute')
|
| 670 |
+
.send({
|
| 671 |
+
worldId: 'test-world',
|
| 672 |
+
inputs: { orderId: 'TEST-001' }
|
| 673 |
+
});
|
| 674 |
+
expect(res.status).toBe(200);
|
| 675 |
+
expect(res.body.capabilityId).toBe('order-fulfillment-simple');
|
| 676 |
+
expect(res.body.result).toBeDefined();
|
| 677 |
+
});
|
| 678 |
+
});
|
| 679 |
+
});
|
| 680 |
+
```
|
| 681 |
+
|
| 682 |
+
**Dependencies**: MORPH-108
|
| 683 |
+
|
| 684 |
+
**Testing**:
|
| 685 |
+
- Run tests: `npm test`
|
| 686 |
+
- All tests pass
|
| 687 |
+
- Coverage > 80%
|
| 688 |
+
|
| 689 |
+
---
|
| 690 |
+
|
| 691 |
+
### MORPH-110: API Documentation
|
| 692 |
+
|
| 693 |
+
**Type**: Task
|
| 694 |
+
**Priority**: Medium
|
| 695 |
+
**Estimate**: 2 points (1 day)
|
| 696 |
+
**Status**: β
DONE
|
| 697 |
+
**Completed**: 2025-11-19
|
| 698 |
+
|
| 699 |
+
**Description**:
|
| 700 |
+
Document the new capability API endpoints.
|
| 701 |
+
|
| 702 |
+
**Acceptance Criteria**:
|
| 703 |
+
- [ ] Document created: `docs/api/capabilities.md`
|
| 704 |
+
- [ ] All 3 endpoints documented
|
| 705 |
+
- [ ] Request/response examples provided
|
| 706 |
+
- [ ] Error codes documented
|
| 707 |
+
- [ ] Example curl commands included
|
| 708 |
+
|
| 709 |
+
**Technical Details**:
|
| 710 |
+
```markdown
|
| 711 |
+
# Capabilities API
|
| 712 |
+
|
| 713 |
+
## Endpoints
|
| 714 |
+
|
| 715 |
+
### GET /api/capabilities
|
| 716 |
+
List all capabilities with optional filtering.
|
| 717 |
+
|
| 718 |
+
**Query Parameters**:
|
| 719 |
+
- `domain` (string[]): Filter by domain
|
| 720 |
+
- `complexity` (string): Filter by complexity
|
| 721 |
+
- `services` (string[]): Filter by services
|
| 722 |
+
|
| 723 |
+
**Example**:
|
| 724 |
+
curl http://localhost:3000/api/capabilities?domain=fulfillment
|
| 725 |
+
|
| 726 |
+
### GET /api/capabilities/:id
|
| 727 |
+
Get details of a single capability.
|
| 728 |
+
|
| 729 |
+
**Example**:
|
| 730 |
+
curl http://localhost:3000/api/capabilities/order-fulfillment-simple
|
| 731 |
+
|
| 732 |
+
### POST /api/capabilities/:id/execute
|
| 733 |
+
Execute a capability.
|
| 734 |
+
|
| 735 |
+
**Body**:
|
| 736 |
+
{
|
| 737 |
+
"worldId": "string",
|
| 738 |
+
"inputs": object
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
**Example**:
|
| 742 |
+
curl -X POST http://localhost:3000/api/capabilities/order-fulfillment-simple/execute \
|
| 743 |
+
-H "Content-Type: application/json" \
|
| 744 |
+
-d '{"worldId":"world-123","inputs":{"orderId":"ORD-001"}}'
|
| 745 |
+
```
|
| 746 |
+
|
| 747 |
+
**Dependencies**: MORPH-109
|
| 748 |
+
|
| 749 |
+
**Testing**:
|
| 750 |
+
- Documentation is clear
|
| 751 |
+
- Examples work
|
| 752 |
+
- Covers all endpoints
|
| 753 |
+
|
| 754 |
+
---
|
| 755 |
+
|
| 756 |
+
### MORPH-111: Phase 0 Demo Preparation
|
| 757 |
+
|
| 758 |
+
**Type**: Task
|
| 759 |
+
**Priority**: Medium
|
| 760 |
+
**Estimate**: 1 point (0.5 days)
|
| 761 |
+
**Status**: β
DONE
|
| 762 |
+
**Completed**: 2025-11-19
|
| 763 |
+
|
| 764 |
+
**Description**:
|
| 765 |
+
Prepare demo script and materials for Phase 0 review.
|
| 766 |
+
|
| 767 |
+
**Acceptance Criteria**:
|
| 768 |
+
- [ ] Demo script created
|
| 769 |
+
- [ ] Example requests prepared (Postman/curl)
|
| 770 |
+
- [ ] Can demonstrate end-to-end flow
|
| 771 |
+
- [ ] Demo shows all 3 endpoints working
|
| 772 |
+
- [ ] Demo execution is successful
|
| 773 |
+
|
| 774 |
+
**Demo Script**:
|
| 775 |
+
```bash
|
| 776 |
+
# 1. List all capabilities
|
| 777 |
+
curl http://localhost:3000/api/capabilities
|
| 778 |
+
|
| 779 |
+
# 2. Filter by domain
|
| 780 |
+
curl http://localhost:3000/api/capabilities?domain=fulfillment
|
| 781 |
+
|
| 782 |
+
# 3. Get capability details
|
| 783 |
+
curl http://localhost:3000/api/capabilities/order-fulfillment-simple
|
| 784 |
+
|
| 785 |
+
# 4. Execute capability
|
| 786 |
+
curl -X POST http://localhost:3000/api/capabilities/order-fulfillment-simple/execute \
|
| 787 |
+
-H "Content-Type: application/json" \
|
| 788 |
+
-d '{"worldId":"demo-world","inputs":{"orderId":"DEMO-001"}}'
|
| 789 |
+
|
| 790 |
+
# 5. Show execution result
|
| 791 |
+
```
|
| 792 |
+
|
| 793 |
+
**Dependencies**: MORPH-110
|
| 794 |
+
|
| 795 |
+
**Testing**:
|
| 796 |
+
- Demo runs successfully
|
| 797 |
+
- All endpoints work
|
| 798 |
+
- Results are as expected
|
| 799 |
+
|
| 800 |
+
---
|
| 801 |
+
|
| 802 |
+
### MORPH-112: Phase 0 Retrospective & Decision
|
| 803 |
+
|
| 804 |
+
**Type**: Task
|
| 805 |
+
**Priority**: High
|
| 806 |
+
**Estimate**: 1 point (0.5 days)
|
| 807 |
+
**Status**: π TODO
|
| 808 |
+
**Assignee**: _Unassigned_
|
| 809 |
+
|
| 810 |
+
**Description**:
|
| 811 |
+
Conduct Phase 0 retrospective and make go/no-go decision for Phase 1.
|
| 812 |
+
|
| 813 |
+
**Acceptance Criteria**:
|
| 814 |
+
- [ ] Team demo completed
|
| 815 |
+
- [ ] Feedback collected
|
| 816 |
+
- [ ] Decision documented: Continue to Phase 1 or Pivot
|
| 817 |
+
- [ ] Learnings documented for Phase 1 planning
|
| 818 |
+
|
| 819 |
+
**Discussion Points**:
|
| 820 |
+
1. Does this approach provide value to researchers?
|
| 821 |
+
2. Is the API intuitive?
|
| 822 |
+
3. Are we on the right track?
|
| 823 |
+
4. What should we adjust for Phase 1?
|
| 824 |
+
|
| 825 |
+
**Deliverables**:
|
| 826 |
+
- Meeting notes
|
| 827 |
+
- Decision: GO / NO-GO / PIVOT
|
| 828 |
+
- Feedback incorporated into Phase 1 planning
|
| 829 |
+
|
| 830 |
+
**Dependencies**: MORPH-111
|
| 831 |
+
|
| 832 |
+
**Testing**:
|
| 833 |
+
- Decision is clear
|
| 834 |
+
- Feedback is actionable
|
| 835 |
+
|
| 836 |
+
---
|
| 837 |
+
|
| 838 |
+
## Phase 0 Summary
|
| 839 |
+
|
| 840 |
+
**Total Tickets**: 12
|
| 841 |
+
**Total Story Points**: 21 points (~2-3 weeks with 1 developer)
|
| 842 |
+
|
| 843 |
+
**Ticket Breakdown**:
|
| 844 |
+
- Setup & Foundation: 3 tickets (8 points)
|
| 845 |
+
- Capability System: 4 tickets (8 points)
|
| 846 |
+
- API Endpoints: 3 tickets (3 points)
|
| 847 |
+
- Testing & Documentation: 2 tickets (2 points)
|
| 848 |
+
|
| 849 |
+
**Critical Path**:
|
| 850 |
+
MORPH-101 β MORPH-102 β MORPH-103 β MORPH-104 β MORPH-106 β MORPH-107 β MORPH-108 β MORPH-109
|
| 851 |
+
|
| 852 |
+
**Parallelizable**:
|
| 853 |
+
- MORPH-105 can be done alongside MORPH-106
|
| 854 |
+
- MORPH-110 can be done alongside MORPH-109
|
| 855 |
+
|
| 856 |
+
---
|
| 857 |
+
|
| 858 |
+
</details>
|
| 859 |
+
|
| 860 |
+
<details>
|
| 861 |
+
<summary>Phase 1 Tickets (ARCHIVED - See implementation/phase1/tasks.md)</summary>
|
| 862 |
+
|
| 863 |
+
### MORPH-201: Create OD Registry Service
|
| 864 |
+
|
| 865 |
+
**Type**: Story
|
| 866 |
+
**Priority**: High
|
| 867 |
+
**Estimate**: 5 points (2-3 days)
|
| 868 |
+
**Status**: π TODO
|
| 869 |
+
**Assignee**: _Unassigned_
|
| 870 |
+
|
| 871 |
+
**Description**:
|
| 872 |
+
Create a centralized OD Registry that maps capability IDs to actual OD builder functions. This registry will be used by the CapabilityExecutor to instantiate and build ODs for execution.
|
| 873 |
+
|
| 874 |
+
**Acceptance Criteria**:
|
| 875 |
+
- [ ] File created: `src/services/od-registry.service.ts`
|
| 876 |
+
- [ ] `ODRegistry` class implemented with builder registration
|
| 877 |
+
- [ ] Method: `registerBuilder(odId, builderFactory)` to register OD builders
|
| 878 |
+
- [ ] Method: `getBuilder(odId)` returns builder factory or null
|
| 879 |
+
- [ ] Method: `buildOD(odId, config)` builds and returns OD instance
|
| 880 |
+
- [ ] Registry supports all existing OD builders (WMS, EDI, TMS)
|
| 881 |
+
- [ ] Singleton pattern for global access
|
| 882 |
+
- [ ] Initial registration for 5 Phase 0 ODs
|
| 883 |
+
|
| 884 |
+
**Dependencies**: None (foundational)
|
| 885 |
+
|
| 886 |
+
**Testing**:
|
| 887 |
+
- Can register builder without error
|
| 888 |
+
- Can retrieve registered builder
|
| 889 |
+
- `buildOD()` returns valid OperationalDescriptor
|
| 890 |
+
- Throws error for non-existent OD ID
|
| 891 |
+
|
| 892 |
+
---
|
| 893 |
+
|
| 894 |
+
### MORPH-202: Integrate Real OD Execution in CapabilityExecutor
|
| 895 |
+
|
| 896 |
+
**Type**: Story
|
| 897 |
+
**Priority**: High
|
| 898 |
+
**Estimate**: 5 points (2-3 days)
|
| 899 |
+
**Status**: π TODO
|
| 900 |
+
**Assignee**: _Unassigned_
|
| 901 |
+
|
| 902 |
+
**Description**:
|
| 903 |
+
Replace stub implementation in CapabilityExecutor with real OD execution using the OD Registry, world initialization, and existing OD executor.
|
| 904 |
+
|
| 905 |
+
**Acceptance Criteria**:
|
| 906 |
+
- [ ] Update `capability-executor.service.ts` to use real execution
|
| 907 |
+
- [ ] Initialize world context using `initOperationalDescriptor()`
|
| 908 |
+
- [ ] Build OD from registry using capability's `odId`
|
| 909 |
+
- [ ] Execute OD using `executeOperationalDescriptor()`
|
| 910 |
+
- [ ] Return properly formatted execution results
|
| 911 |
+
- [ ] Handle errors gracefully with proper status codes
|
| 912 |
+
- [ ] Include logger from capability execution context
|
| 913 |
+
- [ ] Pass chaos policy from capability to OD
|
| 914 |
+
|
| 915 |
+
**Dependencies**: MORPH-201
|
| 916 |
+
|
| 917 |
+
**Testing**:
|
| 918 |
+
- Execute order-fulfillment-simple returns real results
|
| 919 |
+
- World context initialized correctly
|
| 920 |
+
- OD executes with proper steps
|
| 921 |
+
- Errors handled and returned with 'failed' status
|
| 922 |
+
|
| 923 |
+
---
|
| 924 |
+
|
| 925 |
+
### MORPH-203: Build 15 Additional OD Builders
|
| 926 |
+
|
| 927 |
+
**Type**: Task
|
| 928 |
+
**Priority**: High
|
| 929 |
+
**Estimate**: 8 points (4-5 days)
|
| 930 |
+
**Status**: π TODO
|
| 931 |
+
**Assignee**: _Unassigned_
|
| 932 |
+
|
| 933 |
+
**Description**:
|
| 934 |
+
Create 15 new OD builders to expand from 5 to 20 total capabilities. Focus on common supply chain workflows across WMS, EDI, TMS, and ERP domains.
|
| 935 |
+
|
| 936 |
+
**Acceptance Criteria**:
|
| 937 |
+
- [ ] 15 new OD builder functions created
|
| 938 |
+
- [ ] Each builder registered in OD Registry
|
| 939 |
+
- [ ] Mix of simple (5), medium (7), complex (3) workflows
|
| 940 |
+
- [ ] Cover all major domains: fulfillment, inventory, warehousing, EDI, transportation
|
| 941 |
+
- [ ] Use GenericODBuilder for consistent structure
|
| 942 |
+
- [ ] Include appropriate chaos scenarios for each
|
| 943 |
+
- [ ] All builders tested and working
|
| 944 |
+
|
| 945 |
+
**OD Builders to Create**:
|
| 946 |
+
1. inventory-adjustment-simple-v1 (Simple, WMS)
|
| 947 |
+
2. shipment-status-check-v1 (Simple, TMS)
|
| 948 |
+
3. edi-856-asn-generation-v1 (Simple, EDI)
|
| 949 |
+
4. order-cancellation-simple-v1 (Simple, ERP)
|
| 950 |
+
5. dock-schedule-query-v1 (Simple, WMS)
|
| 951 |
+
6. cycle-count-workflow-v1 (Medium, WMS)
|
| 952 |
+
7. outbound-picking-v1 (Medium, WMS)
|
| 953 |
+
8. edi-810-invoice-v1 (Medium, EDI+ERP)
|
| 954 |
+
9. cross-dock-workflow-v1 (Medium, WMS+TMS)
|
| 955 |
+
10. replenishment-workflow-v1 (Medium, WMS)
|
| 956 |
+
11. edi-855-po-ack-v1 (Medium, EDI)
|
| 957 |
+
12. load-planning-v1 (Medium, TMS)
|
| 958 |
+
13. returns-processing-v1 (Complex, ERP+WMS+TMS)
|
| 959 |
+
14. wave-picking-v1 (Complex, WMS)
|
| 960 |
+
15. multi-location-transfer-v1 (Complex, WMS+TMS)
|
| 961 |
+
|
| 962 |
+
**Dependencies**: MORPH-201
|
| 963 |
+
|
| 964 |
+
**Testing**:
|
| 965 |
+
- Each OD builds successfully
|
| 966 |
+
- ODs execute without errors (with mock data)
|
| 967 |
+
- Step structure is valid
|
| 968 |
+
|
| 969 |
+
---
|
| 970 |
+
|
| 971 |
+
### MORPH-204: Expand Capability Catalog to 20 Capabilities
|
| 972 |
+
|
| 973 |
+
**Type**: Task
|
| 974 |
+
**Priority**: High
|
| 975 |
+
**Estimate**: 3 points (1.5-2 days)
|
| 976 |
+
**Status**: π TODO
|
| 977 |
+
**Assignee**: _Unassigned_
|
| 978 |
+
|
| 979 |
+
**Description**:
|
| 980 |
+
Add 15 new capability definitions to the catalog, mapping to the new OD builders. Ensure comprehensive metadata, tags, and descriptions.
|
| 981 |
+
|
| 982 |
+
**Acceptance Criteria**:
|
| 983 |
+
- [ ] Add 15 new capabilities to `catalog.ts`
|
| 984 |
+
- [ ] Each capability maps to an OD from MORPH-203
|
| 985 |
+
- [ ] Complete metadata: description, tags, personas, patterns
|
| 986 |
+
- [ ] Estimated durations realistic
|
| 987 |
+
- [ ] Exported as `EXPANDED_CAPABILITIES` array
|
| 988 |
+
- [ ] Update CapabilityCatalog to load expanded set
|
| 989 |
+
|
| 990 |
+
**Dependencies**: MORPH-203
|
| 991 |
+
|
| 992 |
+
**Testing**:
|
| 993 |
+
- Catalog loads 20 capabilities
|
| 994 |
+
- All capabilities have valid `odId` references
|
| 995 |
+
- Filtering by tags works correctly
|
| 996 |
+
- No duplicate capability IDs
|
| 997 |
+
|
| 998 |
+
---
|
| 999 |
+
|
| 1000 |
+
### MORPH-205: Create Chaos Preset Configuration Files
|
| 1001 |
+
|
| 1002 |
+
**Type**: Task
|
| 1003 |
+
**Priority**: Medium
|
| 1004 |
+
**Estimate**: 2 points (1 day)
|
| 1005 |
+
**Status**: π TODO
|
| 1006 |
+
**Assignee**: _Unassigned_
|
| 1007 |
+
|
| 1008 |
+
**Description**:
|
| 1009 |
+
Create JSON configuration files for chaos presets (light, moderate, aggressive, realistic) that can be applied to capabilities and worlds.
|
| 1010 |
+
|
| 1011 |
+
**Acceptance Criteria**:
|
| 1012 |
+
- [ ] Directory created: `config/chaos-presets/`
|
| 1013 |
+
- [ ] 4 preset files created: `light.json`, `moderate.json`, `aggressive.json`, `realistic.json`
|
| 1014 |
+
- [ ] Each preset defines probability and scenario weights
|
| 1015 |
+
- [ ] Presets cover all chaos scenario types
|
| 1016 |
+
- [ ] README documenting preset usage
|
| 1017 |
+
|
| 1018 |
+
**Dependencies**: None
|
| 1019 |
+
|
| 1020 |
+
**Testing**:
|
| 1021 |
+
- All JSON files valid
|
| 1022 |
+
- Probabilities sum correctly
|
| 1023 |
+
- Scenario weights reasonable
|
| 1024 |
+
|
| 1025 |
+
---
|
| 1026 |
+
|
| 1027 |
+
### MORPH-206: Build Chaos Config Registry Service
|
| 1028 |
+
|
| 1029 |
+
**Type**: Story
|
| 1030 |
+
**Priority**: Medium
|
| 1031 |
+
**Estimate**: 4 points (2 days)
|
| 1032 |
+
**Status**: π TODO
|
| 1033 |
+
**Assignee**: _Unassigned_
|
| 1034 |
+
|
| 1035 |
+
**Description**:
|
| 1036 |
+
Create a Chaos Config Registry that loads presets, manages chaos configuration, and provides chaos resolution based on environment variables and context.
|
| 1037 |
+
|
| 1038 |
+
**Acceptance Criteria**:
|
| 1039 |
+
- [ ] File created: `src/services/chaos-config.registry.ts`
|
| 1040 |
+
- [ ] Loads presets from JSON files on initialization
|
| 1041 |
+
- [ ] Method: `loadPreset(presetId)` returns ChaosPolicy
|
| 1042 |
+
- [ ] Method: `listPresets()` returns available presets
|
| 1043 |
+
- [ ] Method: `isChaosEnabled()` checks CHAOS_ENABLED env var
|
| 1044 |
+
- [ ] Method: `resolveChaosPolicy(context)` applies priority cascade
|
| 1045 |
+
- [ ] Respects environment variable overrides
|
| 1046 |
+
- [ ] Singleton pattern
|
| 1047 |
+
|
| 1048 |
+
**Dependencies**: MORPH-205
|
| 1049 |
+
|
| 1050 |
+
**Testing**:
|
| 1051 |
+
- Loads all 4 presets on initialization
|
| 1052 |
+
- `isChaosEnabled()` respects env var
|
| 1053 |
+
- `resolveChaosPolicy()` follows priority cascade
|
| 1054 |
+
- CHAOS_ENABLED=false disables all chaos
|
| 1055 |
+
|
| 1056 |
+
---
|
| 1057 |
+
|
| 1058 |
+
### MORPH-207: Integrate Chaos Registry with Capability Executor
|
| 1059 |
+
|
| 1060 |
+
**Type**: Story
|
| 1061 |
+
**Priority**: Medium
|
| 1062 |
+
**Estimate**: 3 points (1.5 days)
|
| 1063 |
+
**Status**: π TODO
|
| 1064 |
+
**Assignee**: _Unassigned_
|
| 1065 |
+
|
| 1066 |
+
**Description**:
|
| 1067 |
+
Integrate ChaosConfigRegistry into CapabilityExecutor so chaos policies are resolved and applied during OD execution.
|
| 1068 |
+
|
| 1069 |
+
**Acceptance Criteria**:
|
| 1070 |
+
- [ ] CapabilityExecutor uses ChaosConfigRegistry
|
| 1071 |
+
- [ ] Resolves chaos policy before building OD
|
| 1072 |
+
- [ ] Passes resolved chaos to OD builder
|
| 1073 |
+
- [ ] Capability-level chaos in catalog respected
|
| 1074 |
+
- [ ] Environment variables control chaos behavior
|
| 1075 |
+
- [ ] Chaos telemetry logged in execution results
|
| 1076 |
+
|
| 1077 |
+
**Dependencies**: MORPH-206, MORPH-202
|
| 1078 |
+
|
| 1079 |
+
**Testing**:
|
| 1080 |
+
- Chaos disabled when CHAOS_ENABLED=false
|
| 1081 |
+
- Capability-level chaos overrides default
|
| 1082 |
+
- Resolved chaos passed to OD builder
|
| 1083 |
+
- Chaos telemetry in execution results
|
| 1084 |
+
|
| 1085 |
+
---
|
| 1086 |
+
|
| 1087 |
+
### MORPH-208: Add Chaos Support to Capability Type
|
| 1088 |
+
|
| 1089 |
+
**Type**: Task
|
| 1090 |
+
**Priority**: Medium
|
| 1091 |
+
**Estimate**: 1 point (0.5 days)
|
| 1092 |
+
**Status**: π TODO
|
| 1093 |
+
**Assignee**: _Unassigned_
|
| 1094 |
+
|
| 1095 |
+
**Description**:
|
| 1096 |
+
Extend Capability type definition to support chaos configuration at capability level.
|
| 1097 |
+
|
| 1098 |
+
**Acceptance Criteria**:
|
| 1099 |
+
- [ ] Add optional `chaos` field to Capability type
|
| 1100 |
+
- [ ] Update catalog with chaos configs for select capabilities
|
| 1101 |
+
- [ ] Type supports both preset reference and inline policy
|
| 1102 |
+
- [ ] Backward compatible (chaos optional)
|
| 1103 |
+
|
| 1104 |
+
**Dependencies**: MORPH-204
|
| 1105 |
+
|
| 1106 |
+
**Testing**:
|
| 1107 |
+
- Types compile correctly
|
| 1108 |
+
- Catalog capabilities with chaos load properly
|
| 1109 |
+
- Preset references resolve correctly
|
| 1110 |
+
|
| 1111 |
+
---
|
| 1112 |
+
|
| 1113 |
+
### MORPH-209: Enhanced Filtering with Search
|
| 1114 |
+
|
| 1115 |
+
**Type**: Story
|
| 1116 |
+
**Priority**: Medium
|
| 1117 |
+
**Estimate**: 3 points (1.5 days)
|
| 1118 |
+
**Status**: π TODO
|
| 1119 |
+
**Assignee**: _Unassigned_
|
| 1120 |
+
|
| 1121 |
+
**Description**:
|
| 1122 |
+
Add full-text search and enhanced filtering capabilities to CapabilityCatalog for better discoverability.
|
| 1123 |
+
|
| 1124 |
+
**Acceptance Criteria**:
|
| 1125 |
+
- [ ] Method: `search(query)` performs full-text search
|
| 1126 |
+
- [ ] Search across name, description, tags
|
| 1127 |
+
- [ ] Filter by multiple tags simultaneously
|
| 1128 |
+
- [ ] Filter by persona
|
| 1129 |
+
- [ ] Filter by pattern
|
| 1130 |
+
- [ ] Case-insensitive search
|
| 1131 |
+
- [ ] Returns ranked results (most relevant first)
|
| 1132 |
+
|
| 1133 |
+
**Dependencies**: MORPH-204
|
| 1134 |
+
|
| 1135 |
+
**Testing**:
|
| 1136 |
+
- Search for 'inventory' returns relevant capabilities
|
| 1137 |
+
- Multiple filters work together (AND logic)
|
| 1138 |
+
- Empty query returns all
|
| 1139 |
+
|
| 1140 |
+
---
|
| 1141 |
+
|
| 1142 |
+
### MORPH-210: Update GET /api/capabilities with Search
|
| 1143 |
+
|
| 1144 |
+
**Type**: Task
|
| 1145 |
+
**Priority**: Medium
|
| 1146 |
+
**Estimate**: 2 points (1 day)
|
| 1147 |
+
**Status**: π TODO
|
| 1148 |
+
**Assignee**: _Unassigned_
|
| 1149 |
+
|
| 1150 |
+
**Description**:
|
| 1151 |
+
Update the capabilities API endpoint to support full-text search and enhanced filtering.
|
| 1152 |
+
|
| 1153 |
+
**Acceptance Criteria**:
|
| 1154 |
+
- [ ] Add `q` query parameter for search
|
| 1155 |
+
- [ ] Add `persona` query parameter
|
| 1156 |
+
- [ ] Add `pattern` query parameter
|
| 1157 |
+
- [ ] Update to use `filterEnhanced()` method
|
| 1158 |
+
- [ ] Return count metadata
|
| 1159 |
+
- [ ] Backward compatible with existing filters
|
| 1160 |
+
|
| 1161 |
+
**Dependencies**: MORPH-209
|
| 1162 |
+
|
| 1163 |
+
**Testing**:
|
| 1164 |
+
- Search queries return relevant results
|
| 1165 |
+
- Multiple filters work correctly
|
| 1166 |
+
- Response includes count metadata
|
| 1167 |
+
|
| 1168 |
+
---
|
| 1169 |
+
|
| 1170 |
+
### MORPH-211: Add GET /api/chaos/presets Endpoint
|
| 1171 |
+
|
| 1172 |
+
**Type**: Task
|
| 1173 |
+
**Priority**: Low
|
| 1174 |
+
**Estimate**: 2 points (1 day)
|
| 1175 |
+
**Status**: π TODO
|
| 1176 |
+
**Assignee**: _Unassigned_
|
| 1177 |
+
|
| 1178 |
+
**Description**:
|
| 1179 |
+
Create API endpoints for chaos preset management and inspection.
|
| 1180 |
+
|
| 1181 |
+
**Acceptance Criteria**:
|
| 1182 |
+
- [ ] `GET /api/chaos/presets` lists all presets
|
| 1183 |
+
- [ ] `GET /api/chaos/presets/:id` returns preset details
|
| 1184 |
+
- [ ] `GET /api/chaos/status` returns chaos configuration status
|
| 1185 |
+
- [ ] Returns preset metadata and configuration
|
| 1186 |
+
- [ ] Documents chaos environment variables
|
| 1187 |
+
|
| 1188 |
+
**Dependencies**: MORPH-206
|
| 1189 |
+
|
| 1190 |
+
**Testing**:
|
| 1191 |
+
- Lists all 4 presets
|
| 1192 |
+
- Returns 404 for invalid preset ID
|
| 1193 |
+
- Status endpoint shows env vars
|
| 1194 |
+
|
| 1195 |
+
---
|
| 1196 |
+
|
| 1197 |
+
### MORPH-212: Service Tools Enhancement for New ODs
|
| 1198 |
+
|
| 1199 |
+
**Type**: Task
|
| 1200 |
+
**Priority**: Medium
|
| 1201 |
+
**Estimate**: 5 points (2-3 days)
|
| 1202 |
+
**Status**: π TODO
|
| 1203 |
+
**Assignee**: _Unassigned_
|
| 1204 |
+
|
| 1205 |
+
**Description**:
|
| 1206 |
+
Add new service tool methods to support the 15 new OD builders. Enhance existing WMS, EDI, and TMS service tools.
|
| 1207 |
+
|
| 1208 |
+
**Acceptance Criteria**:
|
| 1209 |
+
- [ ] Add 10-15 new tool methods across WMS, EDI, TMS
|
| 1210 |
+
- [ ] Tools support new capability workflows
|
| 1211 |
+
- [ ] Tools follow existing patterns (repositories, logging)
|
| 1212 |
+
- [ ] Mock implementations for missing backend
|
| 1213 |
+
- [ ] Proper error handling
|
| 1214 |
+
|
| 1215 |
+
**New Tools Needed**:
|
| 1216 |
+
- WMS: selectCycleCountLocations, performCycleCount, reconcileInventory, performReplenishment, createPickTask
|
| 1217 |
+
- EDI: generate856ASN, generate855POAck, generate810Invoice, validateEDIDocument
|
| 1218 |
+
- TMS: planLoad, optimizeRoute, trackMultipleShipments
|
| 1219 |
+
|
| 1220 |
+
**Dependencies**: MORPH-203
|
| 1221 |
+
|
| 1222 |
+
**Testing**:
|
| 1223 |
+
- Each new tool callable without errors
|
| 1224 |
+
- Returns expected data structure
|
| 1225 |
+
- Handles invalid inputs gracefully
|
| 1226 |
+
|
| 1227 |
+
---
|
| 1228 |
+
|
| 1229 |
+
### MORPH-213: Update API Documentation
|
| 1230 |
+
|
| 1231 |
+
**Type**: Task
|
| 1232 |
+
**Priority**: Medium
|
| 1233 |
+
**Estimate**: 2 points (1 day)
|
| 1234 |
+
**Status**: π TODO
|
| 1235 |
+
**Assignee**: _Unassigned_
|
| 1236 |
+
|
| 1237 |
+
**Description**:
|
| 1238 |
+
Update API documentation to reflect Phase 1 enhancements: search, filtering, chaos endpoints.
|
| 1239 |
+
|
| 1240 |
+
**Acceptance Criteria**:
|
| 1241 |
+
- [ ] Update `docs/api/capabilities.md` with new query params
|
| 1242 |
+
- [ ] Document search functionality with examples
|
| 1243 |
+
- [ ] Document chaos endpoints
|
| 1244 |
+
- [ ] Add filtering examples
|
| 1245 |
+
- [ ] Update Swagger/OpenAPI spec if exists
|
| 1246 |
+
- [ ] Include chaos configuration guide
|
| 1247 |
+
|
| 1248 |
+
**Dependencies**: MORPH-210, MORPH-211
|
| 1249 |
+
|
| 1250 |
+
**Testing**:
|
| 1251 |
+
- Documentation accurate
|
| 1252 |
+
- Examples work as shown
|
| 1253 |
+
- All new features documented
|
| 1254 |
+
|
| 1255 |
+
---
|
| 1256 |
+
|
| 1257 |
+
### MORPH-214: Integration Testing for Phase 1
|
| 1258 |
+
|
| 1259 |
+
**Type**: Task
|
| 1260 |
+
**Priority**: High
|
| 1261 |
+
**Estimate**: 5 points (2-3 days)
|
| 1262 |
+
**Status**: π TODO
|
| 1263 |
+
**Assignee**: _Unassigned_
|
| 1264 |
+
|
| 1265 |
+
**Description**:
|
| 1266 |
+
Create comprehensive integration tests for Phase 1 features: real OD execution, filtering, search, chaos.
|
| 1267 |
+
|
| 1268 |
+
**Acceptance Criteria**:
|
| 1269 |
+
- [ ] Test file: `tests/phase1-integration.test.ts`
|
| 1270 |
+
- [ ] Test: Execute all 20 capabilities successfully
|
| 1271 |
+
- [ ] Test: Search and filtering combinations
|
| 1272 |
+
- [ ] Test: Chaos disabled with CHAOS_ENABLED=false
|
| 1273 |
+
- [ ] Test: Different chaos presets produce different results
|
| 1274 |
+
- [ ] Test: OD execution returns proper RunResult
|
| 1275 |
+
- [ ] All tests pass
|
| 1276 |
+
- [ ] Coverage > 80%
|
| 1277 |
+
|
| 1278 |
+
**Dependencies**: MORPH-202, MORPH-210, MORPH-211
|
| 1279 |
+
|
| 1280 |
+
**Testing**:
|
| 1281 |
+
- All test suites pass
|
| 1282 |
+
- Tests cover happy path and error cases
|
| 1283 |
+
- Tests run in CI/CD pipeline
|
| 1284 |
+
|
| 1285 |
+
---
|
| 1286 |
+
|
| 1287 |
+
### MORPH-215: Performance Baseline Metrics
|
| 1288 |
+
|
| 1289 |
+
**Type**: Task
|
| 1290 |
+
**Priority**: Low
|
| 1291 |
+
**Estimate**: 2 points (1 day)
|
| 1292 |
+
**Status**: π TODO
|
| 1293 |
+
**Assignee**: _Unassigned_
|
| 1294 |
+
|
| 1295 |
+
**Description**:
|
| 1296 |
+
Establish performance baselines for Phase 1 to track improvements in later phases.
|
| 1297 |
+
|
| 1298 |
+
**Acceptance Criteria**:
|
| 1299 |
+
- [ ] Measure capability list endpoint performance
|
| 1300 |
+
- [ ] Measure capability execution time (per complexity)
|
| 1301 |
+
- [ ] Measure search and filter performance
|
| 1302 |
+
- [ ] Document baseline metrics
|
| 1303 |
+
- [ ] Set up basic performance monitoring
|
| 1304 |
+
|
| 1305 |
+
**Baseline Targets**:
|
| 1306 |
+
- List 20 capabilities: < 50ms
|
| 1307 |
+
- Search capabilities: < 100ms
|
| 1308 |
+
- Execute simple capability: < 5s
|
| 1309 |
+
- Execute medium capability: < 15s
|
| 1310 |
+
|
| 1311 |
+
**Dependencies**: MORPH-214
|
| 1312 |
+
|
| 1313 |
+
**Testing**:
|
| 1314 |
+
- Performance tests run successfully
|
| 1315 |
+
- Baselines documented
|
| 1316 |
+
|
| 1317 |
+
---
|
| 1318 |
+
|
| 1319 |
+
### MORPH-216: Add 10 More Capabilities (30 Total)
|
| 1320 |
+
|
| 1321 |
+
**Type**: Task
|
| 1322 |
+
**Priority**: Low
|
| 1323 |
+
**Estimate**: 5 points (2-3 days)
|
| 1324 |
+
**Status**: π TODO
|
| 1325 |
+
**Assignee**: _Unassigned_
|
| 1326 |
+
|
| 1327 |
+
**Description**:
|
| 1328 |
+
Expand capability catalog from 20 to 30 capabilities for more comprehensive coverage. Optional based on Phase 1 decision point.
|
| 1329 |
+
|
| 1330 |
+
**Acceptance Criteria**:
|
| 1331 |
+
- [ ] 10 additional OD builders created
|
| 1332 |
+
- [ ] 10 additional capabilities defined
|
| 1333 |
+
- [ ] Mix of all complexity levels
|
| 1334 |
+
- [ ] Cover edge cases and variants
|
| 1335 |
+
- [ ] All tested and working
|
| 1336 |
+
|
| 1337 |
+
**Additional Capabilities**:
|
| 1338 |
+
1. multi-order-fulfillment-v1
|
| 1339 |
+
2. emergency-stock-transfer-v1
|
| 1340 |
+
3. quality-hold-workflow-v1
|
| 1341 |
+
4. edi-940-warehouse-order-v1
|
| 1342 |
+
5. carrier-appointment-v1
|
| 1343 |
+
6. labor-planning-v1
|
| 1344 |
+
7. exception-resolution-v1
|
| 1345 |
+
8. returns-authorization-v1
|
| 1346 |
+
9. kitting-assembly-v1
|
| 1347 |
+
10. bulk-location-update-v1
|
| 1348 |
+
|
| 1349 |
+
**Dependencies**: MORPH-203, MORPH-204
|
| 1350 |
+
|
| 1351 |
+
**Testing**:
|
| 1352 |
+
- All 30 capabilities execute successfully
|
| 1353 |
+
- Coverage across all domains
|
| 1354 |
+
|
| 1355 |
+
---
|
| 1356 |
+
|
| 1357 |
+
### MORPH-217: Phase 1 Demo Preparation
|
| 1358 |
+
|
| 1359 |
+
**Type**: Task
|
| 1360 |
+
**Priority**: Medium
|
| 1361 |
+
**Estimate**: 2 points (1 day)
|
| 1362 |
+
**Status**: π TODO
|
| 1363 |
+
**Assignee**: _Unassigned_
|
| 1364 |
+
|
| 1365 |
+
**Description**:
|
| 1366 |
+
Prepare demo materials and script for Phase 1 review and decision point.
|
| 1367 |
+
|
| 1368 |
+
**Acceptance Criteria**:
|
| 1369 |
+
- [ ] Demo script created showing all Phase 1 features
|
| 1370 |
+
- [ ] Postman collection with example requests
|
| 1371 |
+
- [ ] Demo data setup script
|
| 1372 |
+
- [ ] Slides or presentation materials
|
| 1373 |
+
- [ ] Comparison with Phase 0 stub
|
| 1374 |
+
|
| 1375 |
+
**Dependencies**: All Phase 1 tickets
|
| 1376 |
+
|
| 1377 |
+
**Testing**:
|
| 1378 |
+
- Demo runs successfully
|
| 1379 |
+
- All features demonstrated
|
| 1380 |
+
- Clear value proposition shown
|
| 1381 |
+
|
| 1382 |
+
---
|
| 1383 |
+
|
| 1384 |
+
### MORPH-218: Phase 1 Retrospective & Decision
|
| 1385 |
+
|
| 1386 |
+
**Type**: Task
|
| 1387 |
+
**Priority**: High
|
| 1388 |
+
**Estimate**: 1 point (0.5 days)
|
| 1389 |
+
**Status**: π TODO
|
| 1390 |
+
**Assignee**: _Unassigned_
|
| 1391 |
+
|
| 1392 |
+
**Description**:
|
| 1393 |
+
Conduct Phase 1 retrospective and make go/no-go decision for Phase 2.
|
| 1394 |
+
|
| 1395 |
+
**Acceptance Criteria**:
|
| 1396 |
+
- [ ] Team demo completed
|
| 1397 |
+
- [ ] Feedback collected from researchers
|
| 1398 |
+
- [ ] Performance metrics reviewed
|
| 1399 |
+
- [ ] Decision documented: Continue to Phase 2 or Pivot
|
| 1400 |
+
- [ ] Learnings documented for Phase 2 planning
|
| 1401 |
+
|
| 1402 |
+
**Discussion Points**:
|
| 1403 |
+
1. Are 20-30 capabilities enough for meaningful research?
|
| 1404 |
+
2. Is real OD execution meeting needs?
|
| 1405 |
+
3. Are chaos presets providing value?
|
| 1406 |
+
4. What should we add/change for Phase 2?
|
| 1407 |
+
|
| 1408 |
+
**Dependencies**: MORPH-217
|
| 1409 |
+
|
| 1410 |
+
**Testing**:
|
| 1411 |
+
- Decision is clear and documented
|
| 1412 |
+
- Feedback is actionable
|
| 1413 |
+
|
| 1414 |
+
---
|
| 1415 |
+
|
| 1416 |
+
### MORPH-219: Update README and Getting Started Guide
|
| 1417 |
+
|
| 1418 |
+
**Type**: Task
|
| 1419 |
+
**Priority**: Medium
|
| 1420 |
+
**Estimate**: 2 points (1 day)
|
| 1421 |
+
**Status**: π TODO
|
| 1422 |
+
**Assignee**: _Unassigned_
|
| 1423 |
+
|
| 1424 |
+
**Description**:
|
| 1425 |
+
Update project README and getting started documentation to reflect Phase 1 capabilities.
|
| 1426 |
+
|
| 1427 |
+
**Acceptance Criteria**:
|
| 1428 |
+
- [ ] README updated with Phase 1 features
|
| 1429 |
+
- [ ] Getting started guide includes search examples
|
| 1430 |
+
- [ ] Chaos configuration documented
|
| 1431 |
+
- [ ] Environment variables documented
|
| 1432 |
+
- [ ] Migration notes from Phase 0
|
| 1433 |
+
|
| 1434 |
+
**Dependencies**: MORPH-217
|
| 1435 |
+
|
| 1436 |
+
**Testing**:
|
| 1437 |
+
- Documentation accurate
|
| 1438 |
+
- Examples work
|
| 1439 |
+
- Links valid
|
| 1440 |
+
|
| 1441 |
+
---
|
| 1442 |
+
|
| 1443 |
+
### MORPH-220: Code Cleanup and Refactoring
|
| 1444 |
+
|
| 1445 |
+
**Type**: Task
|
| 1446 |
+
**Priority**: Low
|
| 1447 |
+
**Estimate**: 3 points (1.5 days)
|
| 1448 |
+
**Status**: π TODO
|
| 1449 |
+
**Assignee**: _Unassigned_
|
| 1450 |
+
|
| 1451 |
+
**Description**:
|
| 1452 |
+
Clean up code, remove Phase 0 stubs, improve code quality and consistency.
|
| 1453 |
+
|
| 1454 |
+
**Acceptance Criteria**:
|
| 1455 |
+
- [ ] Remove stub implementation comments
|
| 1456 |
+
- [ ] Consistent error handling across services
|
| 1457 |
+
- [ ] Add JSDoc comments to all public methods
|
| 1458 |
+
- [ ] Extract common patterns to utilities
|
| 1459 |
+
- [ ] Lint and format all code
|
| 1460 |
+
- [ ] Update TypeScript strict mode compliance
|
| 1461 |
+
|
| 1462 |
+
**Dependencies**: All Phase 1 tickets
|
| 1463 |
+
|
| 1464 |
+
**Testing**:
|
| 1465 |
+
- All tests still pass
|
| 1466 |
+
- No regressions
|
| 1467 |
+
- Linting passes
|
| 1468 |
+
|
| 1469 |
+
---
|
| 1470 |
+
|
| 1471 |
+
## Phase 1 Summary
|
| 1472 |
+
|
| 1473 |
+
**Total Tickets**: 20
|
| 1474 |
+
**Total Story Points**: 57 points (~3-4 weeks with 2 developers)
|
| 1475 |
+
|
| 1476 |
+
**Ticket Breakdown by Type**:
|
| 1477 |
+
- Foundation (Registry & Execution): 2 tickets (10 points)
|
| 1478 |
+
- Capability Expansion: 3 tickets (16 points)
|
| 1479 |
+
- Chaos Management: 4 tickets (10 points)
|
| 1480 |
+
- Search & Filtering: 2 tickets (5 points)
|
| 1481 |
+
- API & Documentation: 3 tickets (6 points)
|
| 1482 |
+
- Testing & Quality: 3 tickets (12 points)
|
| 1483 |
+
- Cleanup & Polish: 3 tickets (8 points)
|
| 1484 |
+
|
| 1485 |
+
**Critical Path**:
|
| 1486 |
+
MORPH-201 β MORPH-202 β MORPH-203 β MORPH-204 β MORPH-214 β MORPH-217 β MORPH-218
|
| 1487 |
+
|
| 1488 |
+
**Parallelizable Work**:
|
| 1489 |
+
- MORPH-205, MORPH-206, MORPH-207 (Chaos stream)
|
| 1490 |
+
- MORPH-209, MORPH-210 (Search stream)
|
| 1491 |
+
- MORPH-212 (Service tools - parallel to OD builders)
|
| 1492 |
+
- MORPH-213, MORPH-219 (Documentation - parallel to development)
|
| 1493 |
+
|
| 1494 |
+
**Priority Tiers**:
|
| 1495 |
+
- **High Priority (Must Have)**: MORPH-201, 202, 203, 204, 214, 217, 218
|
| 1496 |
+
- **Medium Priority (Should Have)**: MORPH-205, 206, 207, 209, 210, 212, 213, 219
|
| 1497 |
+
- **Low Priority (Nice to Have)**: MORPH-208, 211, 215, 216, 220
|
| 1498 |
+
|
| 1499 |
+
**Estimated Velocity**:
|
| 1500 |
+
- Week 1: 12-15 points (Foundation + Core ODs)
|
| 1501 |
+
- Week 2: 15-18 points (Chaos + Filtering + Service Tools)
|
| 1502 |
+
- Week 3: 12-15 points (Testing + Documentation)
|
| 1503 |
+
- Week 4: 8-10 points (Polish + Demo + Retrospective)
|
| 1504 |
+
|
| 1505 |
+
</details>
|
| 1506 |
+
|
| 1507 |
+
---
|
| 1508 |
+
|
| 1509 |
+
## Tracking Metrics
|
| 1510 |
+
|
| 1511 |
+
### Overall Progress
|
| 1512 |
+
|
| 1513 |
+
| Phase | Story Points | Status | Completion |
|
| 1514 |
+
|-------|--------------|--------|------------|
|
| 1515 |
+
| Phase 0 | 21 | β
DONE | 100% |
|
| 1516 |
+
| Phase 1 | 57 | β
DONE | 100% |
|
| 1517 |
+
| Phase 2 | 22 | π TODO | 0% |
|
| 1518 |
+
| Phase 3+ | TBD | π LOCKED | - |
|
| 1519 |
+
|
| 1520 |
+
**Total Completed**: 78 story points
|
| 1521 |
+
**Next Phase**: Phase 2 (22 points, 2.5-3 weeks)
|
| 1522 |
+
|
| 1523 |
+
---
|
| 1524 |
+
|
| 1525 |
+
## Related Documents
|
| 1526 |
+
|
| 1527 |
+
- [README](./README.md) - Architecture overview and navigation
|
| 1528 |
+
- [08. Implementation Roadmap](./08-implementation-roadmap.md) - High-level phases
|
| 1529 |
+
- [06. Open Questions & Decisions](./06-open-questions.md) - Architectural decisions
|
| 1530 |
+
- [02. Conceptual Model](./02-conceptual-model.md) - System architecture
|
| 1531 |
+
|
| 1532 |
+
---
|
| 1533 |
+
|
| 1534 |
+
## Definition of Done
|
| 1535 |
+
|
| 1536 |
+
**For Each Ticket**:
|
| 1537 |
+
- All acceptance criteria met
|
| 1538 |
+
- Code reviewed
|
| 1539 |
+
- Tests passing
|
| 1540 |
+
- Documentation updated
|
| 1541 |
+
- No regressions
|
| 1542 |
+
|
| 1543 |
+
**For Each Phase**:
|
| 1544 |
+
- All tickets completed
|
| 1545 |
+
- Demo executed successfully
|
| 1546 |
+
- Test results documented
|
| 1547 |
+
- Retrospective conducted
|
| 1548 |
+
- Go/no-go decision made
|
docs/od-architecture/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Operational Descriptor (OD) Architecture
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
This directory contains architectural documentation for the OD Management System redesign. The goal is to transform Morpheus from a collection of scattered operational descriptors into a well-organized, capability-based system that AI researchers can easily configure and use.
|
| 6 |
+
|
| 7 |
+
## The Problem
|
| 8 |
+
|
| 9 |
+
Currently, Morpheus has:
|
| 10 |
+
- **162 tools** across 4 main services (WMS: 64, ERP: 34, TMS: 33, EDI: 15)
|
| 11 |
+
- **Scattered ODs** across multiple builder files with no central registry
|
| 12 |
+
- **No persona model** - unclear who can execute what
|
| 13 |
+
- **No capability mapping** - can't answer "what can a store manager do?"
|
| 14 |
+
- **Unmanageable chaos configuration** - hardcoded in 14+ files
|
| 15 |
+
- **No way to sample/configure** - researchers can't easily customize worlds
|
| 16 |
+
|
| 17 |
+
## The Vision
|
| 18 |
+
|
| 19 |
+
Transform the system to support:
|
| 20 |
+
|
| 21 |
+
1. **Capability-Based Organization**: ODs organized by business capabilities, not just services
|
| 22 |
+
2. **Persona Model**: Clear mapping of which personas can perform which capabilities
|
| 23 |
+
3. **Knowledge Graph**: Intelligent discovery of valid OD compositions from available tools
|
| 24 |
+
4. **World Configuration**: Researchers can sample capabilities and configure worlds
|
| 25 |
+
5. **Centralized Management**: OD registry, versioning, and customization
|
| 26 |
+
|
| 27 |
+
## Implementation Files
|
| 28 |
+
|
| 29 |
+
### Phase-Specific Documentation
|
| 30 |
+
|
| 31 |
+
All phase-specific implementation details are organized in the `implementation/` directory:
|
| 32 |
+
|
| 33 |
+
```
|
| 34 |
+
implementation/
|
| 35 |
+
βββ phase0/ # Walking Skeleton
|
| 36 |
+
β βββ tasks.md # 12 tickets, 21 story points
|
| 37 |
+
β βββ demo.md # Demo walkthrough
|
| 38 |
+
β βββ test-results.md
|
| 39 |
+
βββ phase1/ # Core Capability System
|
| 40 |
+
β βββ tasks.md # 20 tickets, 57 story points
|
| 41 |
+
β βββ demo-script.md
|
| 42 |
+
β βββ test-results.md
|
| 43 |
+
β βββ retrospective.md
|
| 44 |
+
βββ phase2/ # World Configuration
|
| 45 |
+
βββ tasks.md # 10 tickets, 22 story points (REVISED)
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
See [09. Implementation Tasks](./09-implementation-tasks.md) for quick navigation links.
|
| 49 |
+
|
| 50 |
+
---
|
| 51 |
+
|
| 52 |
+
## Architecture Documents
|
| 53 |
+
|
| 54 |
+
### [01. Current State](./01-current-state.md)
|
| 55 |
+
Complete inventory of the existing system:
|
| 56 |
+
- Services and tools catalog
|
| 57 |
+
- Existing OD patterns
|
| 58 |
+
- Current organization
|
| 59 |
+
- Critical gaps
|
| 60 |
+
|
| 61 |
+
### [02. Conceptual Model](./02-conceptual-model.md)
|
| 62 |
+
Proposed architectural model:
|
| 63 |
+
- Persona β Capability β OD β Tool β Service layering
|
| 64 |
+
- Definitions and relationships
|
| 65 |
+
- Design questions to resolve
|
| 66 |
+
|
| 67 |
+
### [03. Knowledge Graph](./03-knowledge-graph.md)
|
| 68 |
+
Graph-based capability discovery:
|
| 69 |
+
- Graph structure (nodes, edges)
|
| 70 |
+
- Use cases (OD discovery, validation, suggestions)
|
| 71 |
+
- Implementation approaches
|
| 72 |
+
|
| 73 |
+
### [04. Taxonomy & Organization](./04-taxonomy-organization.md)
|
| 74 |
+
How to categorize and organize ODs:
|
| 75 |
+
- Taxonomy options (domain, persona, complexity)
|
| 76 |
+
- Tagging and filtering strategies
|
| 77 |
+
- Discovery patterns
|
| 78 |
+
|
| 79 |
+
### [05. Sampling & World Configuration](./05-sampling-world-config.md)
|
| 80 |
+
Enabling researcher customization:
|
| 81 |
+
- World configuration scenarios
|
| 82 |
+
- Sampling strategies
|
| 83 |
+
- Use cases and workflows
|
| 84 |
+
|
| 85 |
+
### [06. Open Questions & Decisions](./06-open-questions.md)
|
| 86 |
+
Architectural decisions made:
|
| 87 |
+
- β
All critical and important questions decided
|
| 88 |
+
- Decision rationale and implementation notes
|
| 89 |
+
- Priority 3 recommendations for later phases
|
| 90 |
+
|
| 91 |
+
### [07. Chaos Integration](./07-chaos-integration.md)
|
| 92 |
+
How chaos management integrates with OD architecture:
|
| 93 |
+
- Chaos configuration cascade (World β Capability β OD β Step)
|
| 94 |
+
- Integration points and workflows
|
| 95 |
+
- Chaos presets and telemetry
|
| 96 |
+
- Best practices for researchers
|
| 97 |
+
|
| 98 |
+
### [08. Implementation Roadmap](./08-implementation-roadmap.md)
|
| 99 |
+
Value-driven implementation plan:
|
| 100 |
+
- Incremental phases delivering researcher value
|
| 101 |
+
- Phase 0: Walking skeleton (2-3 weeks)
|
| 102 |
+
- Phase 1-4: Core features (14-20 weeks)
|
| 103 |
+
- Migration strategy and risk mitigation
|
| 104 |
+
|
| 105 |
+
### [09. Implementation Tasks](./09-implementation-tasks.md)
|
| 106 |
+
Master index for all implementation tasks:
|
| 107 |
+
- Phase 0: β
COMPLETED (12 tickets, 21 story points)
|
| 108 |
+
- Phase 1: β
COMPLETED (20 tickets, 57 story points)
|
| 109 |
+
- Phase 2: π TODO - Ready to Start (12 tickets, 30 story points)
|
| 110 |
+
- Detailed tasks in `implementation/phaseN/` folders
|
| 111 |
+
- Quick navigation table with links to all phase documents
|
| 112 |
+
|
| 113 |
+
## Key Concepts
|
| 114 |
+
|
| 115 |
+
### Service
|
| 116 |
+
A simulated enterprise system (ERP, WMS, TMS, EDI) that exposes tools/APIs.
|
| 117 |
+
|
| 118 |
+
### Tool
|
| 119 |
+
An API endpoint that performs a specific action (e.g., `getOrder`, `updateInventory`, `scheduleShipment`).
|
| 120 |
+
|
| 121 |
+
### Operational Descriptor (OD)
|
| 122 |
+
A declarative workflow that orchestrates multiple tools to accomplish an end-to-end business process. Contains steps, input bindings, assertions, retry policies, and chaos configuration.
|
| 123 |
+
|
| 124 |
+
### Capability
|
| 125 |
+
A semantic business function or process (e.g., "Order Fulfillment", "Inventory Management", "Shipment Tracking"). Capabilities are implemented by one or more ODs.
|
| 126 |
+
|
| 127 |
+
### Persona
|
| 128 |
+
A role or actor in the system (e.g., Store Manager, Warehouse Worker, Logistics Coordinator). Personas have access to specific capabilities.
|
| 129 |
+
|
| 130 |
+
### Knowledge Graph
|
| 131 |
+
A graph representation of relationships between services, tools, data entities, ODs, capabilities, and personas. Used for discovery, validation, and intelligent suggestions.
|
| 132 |
+
|
| 133 |
+
## Status
|
| 134 |
+
|
| 135 |
+
**Phase**: Phase 2 Implementation (World Configuration)
|
| 136 |
+
**Last Updated**: 2025-11-21
|
| 137 |
+
**Contributors**: System Architects, AI Research Team
|
| 138 |
+
|
| 139 |
+
**Completed**:
|
| 140 |
+
- β
Architecture designed (Persona β Capability β OD β Tool β Service)
|
| 141 |
+
- β
All critical decisions made (9/9 questions)
|
| 142 |
+
- β
Implementation roadmap created (value-driven, 6 phases)
|
| 143 |
+
- β
Phase 0: Walking Skeleton (12 tickets, 21 points) - DONE
|
| 144 |
+
- β
Phase 1: Core Capability System (20 tickets, 57 points) - DONE
|
| 145 |
+
- 4 working capabilities with real OD execution
|
| 146 |
+
- Chaos engineering integrated
|
| 147 |
+
- Search/filtering APIs functional
|
| 148 |
+
|
| 149 |
+
**Current**: Phase 2 - World Configuration (10 tickets, 22 points)
|
| 150 |
+
- Extends existing World model (27% effort reduction)
|
| 151 |
+
- Capability sampling: filter, random, seeded
|
| 152 |
+
- World-level chaos configuration with CRUD API
|
| 153 |
+
- Capability-level chaos overrides
|
| 154 |
+
- Critical bug fix: capability executor chaos integration
|
| 155 |
+
- Reproducibility via seeds
|
| 156 |
+
|
| 157 |
+
## Next Steps
|
| 158 |
+
|
| 159 |
+
1. β
~~Review and discuss each architecture document~~ **DONE**
|
| 160 |
+
2. β
~~Answer open questions and make design decisions~~ **DONE**
|
| 161 |
+
3. β
~~Create implementation plan~~ **DONE**
|
| 162 |
+
4. β
~~Complete Phase 0 - Walking Skeleton~~ **DONE**
|
| 163 |
+
5. β
~~Complete Phase 1 - Core Capability System~~ **DONE**
|
| 164 |
+
6. **NOW**: Start Phase 2 - World Configuration (3-4 weeks)
|
| 165 |
+
- Implement world configuration schema
|
| 166 |
+
- Build sampling strategies (filter, random, seeded)
|
| 167 |
+
- Add world-level chaos with seed support
|
| 168 |
+
- Create world management API endpoints
|
| 169 |
+
7. **NEXT**: Continue through remaining phases based on learnings
|
| 170 |
+
|
| 171 |
+
## Related Documentation
|
| 172 |
+
|
| 173 |
+
- [Main Architecture](../01-architecture.md) - Overall system architecture
|
| 174 |
+
- [Operational Descriptors](../02-operational-descriptors.md) - Current OD implementation
|
| 175 |
+
- [Chaos Engineering](../03-chaos-engineering.md) - Chaos injection framework
|
| 176 |
+
- [Chaos Management](../chaos/) - Chaos configuration and management system
|
| 177 |
+
- [Business Rules](../business-rules/) - Business rules system
|
| 178 |
+
|
| 179 |
+
## Feedback
|
| 180 |
+
|
| 181 |
+
This is a living document. If you have questions, suggestions, or concerns about the proposed architecture, please discuss in the team channels or create an issue.
|
morpheus.local.pwd.yaml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
mongodb:
|
| 3 |
+
image: mongo:7
|
| 4 |
+
ports:
|
| 5 |
+
- 27017:27017
|
| 6 |
+
volumes:
|
| 7 |
+
- ./morpheus-data/mongodb:/data/db
|
| 8 |
+
restart: unless-stopped
|
| 9 |
+
|
| 10 |
+
controlmart:
|
| 11 |
+
env_file:
|
| 12 |
+
- packages/controlmart/.env
|
| 13 |
+
build:
|
| 14 |
+
context: .
|
| 15 |
+
dockerfile: packages/controlmart/Dockerfile
|
| 16 |
+
image: controlmart-local
|
| 17 |
+
environment:
|
| 18 |
+
MONGO_URI: mongodb://mongodb:27017
|
| 19 |
+
ports:
|
| 20 |
+
- "8282:8282"
|
| 21 |
+
restart: unless-stopped
|
| 22 |
+
depends_on:
|
| 23 |
+
- mongodb
|
| 24 |
+
|
| 25 |
+
volumes:
|
| 26 |
+
mongodb-data:
|
morpheus.pwd.yaml
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version: "3.8"
|
| 2 |
+
|
| 3 |
+
services:
|
| 4 |
+
mongodb:
|
| 5 |
+
image: mongo:7
|
| 6 |
+
ports:
|
| 7 |
+
- 27017:27017
|
| 8 |
+
volumes:
|
| 9 |
+
- /mnt/morpheus-data:/data/db
|
| 10 |
+
restart: unless-stopped
|
| 11 |
+
labels:
|
| 12 |
+
- "com.centurylinklabs.watchtower.enable=false"
|
| 13 |
+
|
| 14 |
+
controlmart:
|
| 15 |
+
image: 129875285541.dkr.ecr.us-east-1.amazonaws.com/skyfall/morpheus:latest
|
| 16 |
+
labels:
|
| 17 |
+
- "com.centurylinklabs.watchtower.enable=true"
|
| 18 |
+
environment:
|
| 19 |
+
NODE_ENV: production
|
| 20 |
+
PORT: 8282
|
| 21 |
+
MONGO_URI: mongodb://mongodb:27017
|
| 22 |
+
DB_NAME: controlmart
|
| 23 |
+
LOG_LEVEL: debug
|
| 24 |
+
ENABLE_CORS: true
|
| 25 |
+
ports:
|
| 26 |
+
- "8282:8282"
|
| 27 |
+
restart: unless-stopped
|
| 28 |
+
depends_on:
|
| 29 |
+
- mongodb
|
| 30 |
+
|
| 31 |
+
watchtower:
|
| 32 |
+
image: containrrr/watchtower
|
| 33 |
+
labels:
|
| 34 |
+
- "com.centurylinklabs.watchtower.enable=false"
|
| 35 |
+
volumes:
|
| 36 |
+
- /var/run/docker.sock:/var/run/docker.sock
|
| 37 |
+
- /home/ubuntu/.docker:/config:ro
|
| 38 |
+
environment:
|
| 39 |
+
DOCKER_CONFIG: /config
|
| 40 |
+
WATCHTOWER_CLEANUP: "true"
|
| 41 |
+
WATCHTOWER_POLL_INTERVAL: 60
|
| 42 |
+
WATCHTOWER_DEBUG: "true"
|
| 43 |
+
restart: unless-stopped
|
| 44 |
+
|
| 45 |
+
nginx:
|
| 46 |
+
image: nginx:1.25
|
| 47 |
+
container_name: nginx-proxy
|
| 48 |
+
labels:
|
| 49 |
+
- "com.centurylinklabs.watchtower.enable=false"
|
| 50 |
+
ports:
|
| 51 |
+
- "80:80"
|
| 52 |
+
- "443:443"
|
| 53 |
+
volumes:
|
| 54 |
+
- /mnt/morpheus-data/morpheus/nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
| 55 |
+
- /mnt/morpheus-data/morpheus/nginx/certs:/etc/ssl:ro
|
| 56 |
+
depends_on:
|
| 57 |
+
- controlmart
|
| 58 |
+
restart: unless-stopped
|
| 59 |
+
|
| 60 |
+
volumes:
|
| 61 |
+
mongodb-data:
|
nginx/nginx.conf
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
server {
|
| 2 |
+
listen 80;
|
| 3 |
+
server_name _;
|
| 4 |
+
|
| 5 |
+
proxy_buffering off;
|
| 6 |
+
proxy_request_buffering off;
|
| 7 |
+
proxy_http_version 1.1;
|
| 8 |
+
proxy_set_header Accept-Encoding "";
|
| 9 |
+
|
| 10 |
+
proxy_connect_timeout 60s;
|
| 11 |
+
proxy_send_timeout 60s;
|
| 12 |
+
proxy_read_timeout 60s;
|
| 13 |
+
|
| 14 |
+
location / {
|
| 15 |
+
proxy_pass http://controlmart:8282;
|
| 16 |
+
proxy_set_header Host $host;
|
| 17 |
+
proxy_set_header X-Real-IP $remote_addr;
|
| 18 |
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 19 |
+
proxy_set_header X-Forwarded-Proto $scheme;
|
| 20 |
+
proxy_redirect off;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
access_log /var/log/nginx/access.log;
|
| 24 |
+
error_log /var/log/nginx/error.log;
|
| 25 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "morpheus",
|
| 3 |
+
"module": "index.ts",
|
| 4 |
+
"type": "module",
|
| 5 |
+
"private": true,
|
| 6 |
+
"devDependencies": {
|
| 7 |
+
"@types/bun": "latest"
|
| 8 |
+
},
|
| 9 |
+
"peerDependencies": {
|
| 10 |
+
"typescript": "^5"
|
| 11 |
+
},
|
| 12 |
+
"workspaces": [
|
| 13 |
+
"packages/controlmart"
|
| 14 |
+
],
|
| 15 |
+
"dependencies": {
|
| 16 |
+
"axios": "^1.12.2"
|
| 17 |
+
}
|
| 18 |
+
}
|
packages/controlmart/.dockerignore
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Node / Bun deps
|
| 2 |
+
node_modules
|
| 3 |
+
bun.lockb.bak
|
| 4 |
+
*.log
|
| 5 |
+
|
| 6 |
+
# Bun cache
|
| 7 |
+
.bun
|
| 8 |
+
.cache
|
| 9 |
+
.vscode
|
| 10 |
+
|
| 11 |
+
# Git / version control
|
| 12 |
+
.git
|
| 13 |
+
.gitignore
|
| 14 |
+
|
| 15 |
+
# Docker junk
|
| 16 |
+
Dockerfile*
|
| 17 |
+
docker-compose*
|
| 18 |
+
.dockerignore
|
| 19 |
+
|
| 20 |
+
# OS + editor noise
|
| 21 |
+
.DS_Store
|
| 22 |
+
Thumbs.db
|
| 23 |
+
|
| 24 |
+
# Build output
|
| 25 |
+
dist
|
| 26 |
+
build
|
| 27 |
+
tmp
|
| 28 |
+
coverage
|
| 29 |
+
|
| 30 |
+
# Environment and secrets
|
| 31 |
+
.env
|
| 32 |
+
.env.*
|
| 33 |
+
!.env.example
|
packages/controlmart/.gitignore
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# dependencies (bun install)
|
| 2 |
+
node_modules
|
| 3 |
+
|
| 4 |
+
# output
|
| 5 |
+
out
|
| 6 |
+
dist
|
| 7 |
+
build-dist
|
| 8 |
+
*.tgz
|
| 9 |
+
|
| 10 |
+
# code coverage
|
| 11 |
+
coverage
|
| 12 |
+
*.lcov
|
| 13 |
+
|
| 14 |
+
# logs
|
| 15 |
+
logs
|
| 16 |
+
_.log
|
| 17 |
+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
| 18 |
+
|
| 19 |
+
# dotenv environment variable files
|
| 20 |
+
.env
|
| 21 |
+
.env.development.local
|
| 22 |
+
.env.test.local
|
| 23 |
+
.env.production.local
|
| 24 |
+
.env.local
|
| 25 |
+
|
| 26 |
+
# caches
|
| 27 |
+
.eslintcache
|
| 28 |
+
.cache
|
| 29 |
+
*.tsbuildinfo
|
| 30 |
+
|
| 31 |
+
# IntelliJ based IDEs
|
| 32 |
+
.idea
|
| 33 |
+
|
| 34 |
+
# Finder (MacOS) folder config
|
| 35 |
+
.DS_Store
|
| 36 |
+
|
| 37 |
+
tests/implementation-tests
|
packages/controlmart/.prettierignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
dist
|
| 3 |
+
build
|
| 4 |
+
bun.lockb
|
| 5 |
+
coverage
|
| 6 |
+
.env
|
packages/controlmart/.prettierrc
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://json.schemastore.org/prettierrc",
|
| 3 |
+
"printWidth": 100,
|
| 4 |
+
"tabWidth": 2,
|
| 5 |
+
"useTabs": false,
|
| 6 |
+
"semi": true,
|
| 7 |
+
"singleQuote": false,
|
| 8 |
+
"trailingComma": "all",
|
| 9 |
+
"bracketSpacing": true,
|
| 10 |
+
"arrowParens": "always",
|
| 11 |
+
"endOfLine": "lf",
|
| 12 |
+
"quoteProps": "as-needed",
|
| 13 |
+
"jsxSingleQuote": false,
|
| 14 |
+
"proseWrap": "preserve",
|
| 15 |
+
"embeddedLanguageFormatting": "auto",
|
| 16 |
+
"singleAttributePerLine": false
|
| 17 |
+
}
|
packages/controlmart/Dockerfile
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM oven/bun:latest
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY bun.lock package.json ./
|
| 6 |
+
|
| 7 |
+
COPY packages/controlmart/package.json packages/controlmart/
|
| 8 |
+
|
| 9 |
+
RUN bun install
|
| 10 |
+
|
| 11 |
+
COPY . .
|
| 12 |
+
|
| 13 |
+
WORKDIR /app/packages/controlmart
|
| 14 |
+
RUN bun run build:ui
|
| 15 |
+
|
| 16 |
+
WORKDIR /app/packages/controlmart
|
| 17 |
+
|
| 18 |
+
ENV NODE_ENV=production
|
| 19 |
+
ENV PORT=8282
|
| 20 |
+
|
| 21 |
+
EXPOSE ${PORT}
|
| 22 |
+
|
| 23 |
+
CMD ["bun", "run", "start"]
|
packages/controlmart/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ControlMart - Capability Orchestration Engine
|
| 2 |
+
|
| 3 |
+
ControlMart is Morpheus's capability orchestration engine that provides a semantic layer over Operational Descriptors (ODs) for executing business capabilities with chaos engineering support.
|
| 4 |
+
|
| 5 |
+
## Features
|
| 6 |
+
|
| 7 |
+
- **4 Phase 1 Capabilities**: Inventory Check, Shipment Tracking, Equipment Availability, Dock Appointment Scheduling
|
| 8 |
+
- **Semantic Discovery**: Search and filter capabilities by domain, complexity, services, personas, and patterns
|
| 9 |
+
- **Chaos Engineering**: Built-in resilience testing with configurable chaos scenarios and presets
|
| 10 |
+
- **World Isolation**: Execute capabilities in isolated world contexts with independent data and business rules
|
| 11 |
+
- **RESTful API**: Simple HTTP endpoints for capability discovery and execution
|
| 12 |
+
|
| 13 |
+
## Quick Start
|
| 14 |
+
|
| 15 |
+
### Prerequisites
|
| 16 |
+
|
| 17 |
+
- Bun v1.2.15+
|
| 18 |
+
- MongoDB running on localhost:27017
|
| 19 |
+
|
| 20 |
+
### Installation
|
| 21 |
+
|
| 22 |
+
```bash
|
| 23 |
+
bun install
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
### Running the Server
|
| 27 |
+
|
| 28 |
+
```bash
|
| 29 |
+
# Development mode
|
| 30 |
+
bun run index.ts
|
| 31 |
+
|
| 32 |
+
# With environment variables
|
| 33 |
+
MONGO_URI="mongodb://localhost:27017" DB_NAME="morpheus-test" PORT=4000 bun run index.ts
|
| 34 |
+
|
| 35 |
+
# With chaos enabled
|
| 36 |
+
CHAOS_ENABLED=true CHAOS_PRESET=realistic bun run index.ts
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
### Basic Usage
|
| 40 |
+
|
| 41 |
+
```bash
|
| 42 |
+
# List all capabilities
|
| 43 |
+
curl http://localhost:4000/capabilities
|
| 44 |
+
|
| 45 |
+
# Search for capabilities
|
| 46 |
+
curl "http://localhost:4000/capabilities?q=inventory"
|
| 47 |
+
|
| 48 |
+
# Get capability details
|
| 49 |
+
curl http://localhost:4000/capabilities/inventory-check
|
| 50 |
+
|
| 51 |
+
# Execute a capability
|
| 52 |
+
curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 53 |
+
-H "Content-Type: application/json" \
|
| 54 |
+
-d '{
|
| 55 |
+
"worldId": "your-world-id",
|
| 56 |
+
"inputs": {
|
| 57 |
+
"sku": "SKU-001",
|
| 58 |
+
"locationId": "WH-01"
|
| 59 |
+
}
|
| 60 |
+
}'
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
## Environment Variables
|
| 64 |
+
|
| 65 |
+
| Variable | Description | Default |
|
| 66 |
+
|----------|-------------|---------|
|
| 67 |
+
| `MONGO_URI` | MongoDB connection string | `mongodb://localhost:27017` |
|
| 68 |
+
| `DB_NAME` | Database name | `morpheus-test` |
|
| 69 |
+
| `PORT` | Server port | `4000` |
|
| 70 |
+
| `CHAOS_ENABLED` | Enable chaos injection | `false` |
|
| 71 |
+
| `CHAOS_PRESET` | Chaos preset (`light`/`moderate`/`realistic`/`aggressive`) | `realistic` |
|
| 72 |
+
|
| 73 |
+
## Available Capabilities
|
| 74 |
+
|
| 75 |
+
### 1. Inventory Check
|
| 76 |
+
Check current inventory levels for SKUs across warehouse locations.
|
| 77 |
+
|
| 78 |
+
**Inputs**: `sku` (required), `locationId` (optional)
|
| 79 |
+
|
| 80 |
+
### 2. Shipment Tracking
|
| 81 |
+
Track shipment status and location through the transportation network.
|
| 82 |
+
|
| 83 |
+
**Inputs**: `shipmentId` (required)
|
| 84 |
+
|
| 85 |
+
### 3. Equipment Availability Check
|
| 86 |
+
Check available warehouse equipment (forklifts, pallet jacks, etc.) by type and zone.
|
| 87 |
+
|
| 88 |
+
**Inputs**: `equipmentType` (required), `zoneId` (optional)
|
| 89 |
+
|
| 90 |
+
### 4. Dock Appointment Scheduling
|
| 91 |
+
Find available dock appointment time slots and view current schedule.
|
| 92 |
+
|
| 93 |
+
**Inputs**: `date` (required), `dockDoorId` (required), `appointmentType` (optional)
|
| 94 |
+
|
| 95 |
+
## Chaos Engineering
|
| 96 |
+
|
| 97 |
+
ControlMart includes built-in chaos engineering for resilience testing:
|
| 98 |
+
|
| 99 |
+
```bash
|
| 100 |
+
# Check chaos status
|
| 101 |
+
curl http://localhost:4000/chaos/status
|
| 102 |
+
|
| 103 |
+
# List available presets
|
| 104 |
+
curl http://localhost:4000/chaos/presets
|
| 105 |
+
|
| 106 |
+
# Run with aggressive chaos
|
| 107 |
+
CHAOS_PRESET=aggressive bun run index.ts
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
**Chaos Presets:**
|
| 111 |
+
- `light` (5%): Minimal chaos for production-like testing
|
| 112 |
+
- `moderate` (15%): Balanced chaos for resilience testing
|
| 113 |
+
- `realistic` (10%): Production-realistic failure rates
|
| 114 |
+
- `aggressive` (30%): High chaos for stress testing
|
| 115 |
+
|
| 116 |
+
## Performance Measurement
|
| 117 |
+
|
| 118 |
+
Measure baseline performance for all capabilities:
|
| 119 |
+
|
| 120 |
+
```bash
|
| 121 |
+
bun run scripts/measure-performance.ts
|
| 122 |
+
```
|
| 123 |
+
|
| 124 |
+
Results are saved to `config/performance-baselines.json`.
|
| 125 |
+
|
| 126 |
+
## Documentation
|
| 127 |
+
|
| 128 |
+
- **API Reference**: [docs/api/capabilities-api.md](docs/api/capabilities-api.md)
|
| 129 |
+
- **Architecture**: [../../docs/od-architecture/](../../docs/od-architecture/)
|
| 130 |
+
|
| 131 |
+
## Project Structure
|
| 132 |
+
|
| 133 |
+
```
|
| 134 |
+
src/
|
| 135 |
+
βββ capabilities/ # Capability catalog
|
| 136 |
+
βββ ods/ # Operational Descriptor builders
|
| 137 |
+
βββ routes/ # API routes (capabilities, chaos)
|
| 138 |
+
βββ services/ # Core services (executor, catalog, chaos)
|
| 139 |
+
βββ types/ # TypeScript type definitions
|
| 140 |
+
scripts/
|
| 141 |
+
βββ measure-performance.ts # Performance measurement tool
|
| 142 |
+
docs/
|
| 143 |
+
βββ api/ # API documentation
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
## Development
|
| 147 |
+
|
| 148 |
+
Built with [Bun](https://bun.sh) - a fast all-in-one JavaScript runtime.
|
packages/controlmart/bootstrap.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { existsSync } from "fs";
|
| 2 |
+
import path from "path";
|
| 3 |
+
|
| 4 |
+
// Bootstrap
|
| 5 |
+
(async () => {
|
| 6 |
+
// Check for environment file relative to executable
|
| 7 |
+
const execDir = path.dirname(process.execPath);
|
| 8 |
+
const localEnvPath = path.join(execDir, ".env");
|
| 9 |
+
const devEnvPath = path.resolve(execDir, "../../..", ".env"); // For dev/source runs
|
| 10 |
+
|
| 11 |
+
const envPath = existsSync(localEnvPath) ? localEnvPath : devEnvPath;
|
| 12 |
+
|
| 13 |
+
if (!existsSync(envPath)) {
|
| 14 |
+
console.log(`[bootstrap] No .env file found at ${envPath}. Launching Setup Mode...`);
|
| 15 |
+
const { startSetup } = await import("./src/application/setup.app");
|
| 16 |
+
await startSetup();
|
| 17 |
+
} else {
|
| 18 |
+
// Launch Main Application
|
| 19 |
+
console.log("[bootstrap] Environment found. Starting Application...");
|
| 20 |
+
await import("./main");
|
| 21 |
+
}
|
| 22 |
+
})();
|
packages/controlmart/config/chaos-presets/aggressive.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "aggressive",
|
| 3 |
+
"name": "Aggressive Chaos",
|
| 4 |
+
"description": "High probability chaos with all scenario types. Tests extreme resilience under heavy failure conditions.",
|
| 5 |
+
"globalProbability": 0.3,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "data_corruption",
|
| 9 |
+
"weight": 10,
|
| 10 |
+
"description": "Severe data corruption",
|
| 11 |
+
"config": {
|
| 12 |
+
"corruptFields": ["*"],
|
| 13 |
+
"corruptionType": "random_value"
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"type": "missing_data",
|
| 18 |
+
"weight": 9,
|
| 19 |
+
"description": "Frequent missing records",
|
| 20 |
+
"config": {
|
| 21 |
+
"missingRecords": true,
|
| 22 |
+
"throwError": true
|
| 23 |
+
}
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"type": "stale_data",
|
| 27 |
+
"weight": 8,
|
| 28 |
+
"description": "Very stale data",
|
| 29 |
+
"config": {
|
| 30 |
+
"staleDataAge": 120
|
| 31 |
+
}
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"type": "rate_limit",
|
| 35 |
+
"weight": 8,
|
| 36 |
+
"description": "Aggressive rate limiting",
|
| 37 |
+
"config": {
|
| 38 |
+
"rateLimitDelay": 3000,
|
| 39 |
+
"rateLimitMessage": "Rate limit exceeded - too many requests"
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"type": "format_change",
|
| 44 |
+
"weight": 7,
|
| 45 |
+
"description": "Breaking schema changes",
|
| 46 |
+
"config": {
|
| 47 |
+
"schemaChanges": [
|
| 48 |
+
{
|
| 49 |
+
"field": "id",
|
| 50 |
+
"change": "rename",
|
| 51 |
+
"newName": "order_id"
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"field": "status",
|
| 55 |
+
"change": "change_type",
|
| 56 |
+
"newType": "number"
|
| 57 |
+
}
|
| 58 |
+
]
|
| 59 |
+
}
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"type": "partial_data",
|
| 63 |
+
"weight": 7,
|
| 64 |
+
"description": "Heavily incomplete data",
|
| 65 |
+
"config": {
|
| 66 |
+
"partialResults": {
|
| 67 |
+
"percentage": 50,
|
| 68 |
+
"randomize": true
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"type": "permission_denied",
|
| 74 |
+
"weight": 6,
|
| 75 |
+
"description": "Frequent authorization failures",
|
| 76 |
+
"config": {
|
| 77 |
+
"permissionError": "Access denied - chaos injection"
|
| 78 |
+
}
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"type": "duplicate_data",
|
| 82 |
+
"weight": 6,
|
| 83 |
+
"description": "Heavy duplicate records",
|
| 84 |
+
"config": {}
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"type": "invalid_state",
|
| 88 |
+
"weight": 5,
|
| 89 |
+
"description": "Records in invalid states",
|
| 90 |
+
"config": {
|
| 91 |
+
"invalidStates": ["deleted", "suspended", "inactive", "pending_deletion"]
|
| 92 |
+
}
|
| 93 |
+
},
|
| 94 |
+
{
|
| 95 |
+
"type": "dependency_failure",
|
| 96 |
+
"weight": 4,
|
| 97 |
+
"description": "Service dependency failures",
|
| 98 |
+
"config": {
|
| 99 |
+
"dependencyService": "downstream-service"
|
| 100 |
+
}
|
| 101 |
+
},
|
| 102 |
+
{
|
| 103 |
+
"type": "timing_issue",
|
| 104 |
+
"weight": 3,
|
| 105 |
+
"description": "Timestamp inconsistencies",
|
| 106 |
+
"config": {}
|
| 107 |
+
}
|
| 108 |
+
]
|
| 109 |
+
}
|
packages/controlmart/config/chaos-presets/infra.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "infra",
|
| 3 |
+
"name": "Infrastructure Chaos",
|
| 4 |
+
"description": "System-level faults: rate limits, timeouts, dependency failures. NO data corruption.",
|
| 5 |
+
"globalProbability": 0.1,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "rate_limit",
|
| 9 |
+
"weight": 50,
|
| 10 |
+
"description": "API throttling (429 Too Many Requests)",
|
| 11 |
+
"config": {
|
| 12 |
+
"rateLimitDelay": 1500,
|
| 13 |
+
"rateLimitMessage": "Rate limit exceeded"
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"type": "dependency_failure",
|
| 18 |
+
"weight": 30,
|
| 19 |
+
"description": "Dependency service outage (502/503)",
|
| 20 |
+
"config": {
|
| 21 |
+
"dependencyService": "database-shard-01"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"type": "permission_denied",
|
| 26 |
+
"weight": 20,
|
| 27 |
+
"description": "Authorization failures (403 Forbidden)",
|
| 28 |
+
"config": {
|
| 29 |
+
"permissionError": "Insufficient permissions"
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
]
|
| 33 |
+
}
|
packages/controlmart/config/chaos-presets/light.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "light",
|
| 3 |
+
"name": "Light Chaos",
|
| 4 |
+
"description": "Low probability chaos for basic resilience testing. Simulates common, low-impact scenarios like eventual consistency and rate limiting.",
|
| 5 |
+
"globalProbability": 0.05,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "stale_data",
|
| 9 |
+
"weight": 10,
|
| 10 |
+
"description": "Simulate eventual consistency delays - most common in distributed systems",
|
| 11 |
+
"config": {
|
| 12 |
+
"staleDataAge": 30
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"type": "rate_limit",
|
| 17 |
+
"weight": 5,
|
| 18 |
+
"description": "API throttling and rate limiting",
|
| 19 |
+
"config": {
|
| 20 |
+
"rateLimitDelay": 1000,
|
| 21 |
+
"rateLimitMessage": "Rate limit exceeded - please retry"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"type": "missing_data",
|
| 26 |
+
"weight": 3,
|
| 27 |
+
"description": "Occasional missing records or null results",
|
| 28 |
+
"config": {
|
| 29 |
+
"missingRecords": true,
|
| 30 |
+
"throwError": false
|
| 31 |
+
}
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"type": "partial_data",
|
| 35 |
+
"weight": 2,
|
| 36 |
+
"description": "Incomplete data sets returned",
|
| 37 |
+
"config": {
|
| 38 |
+
"partialResults": {
|
| 39 |
+
"percentage": 80,
|
| 40 |
+
"randomize": false
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
]
|
| 45 |
+
}
|
packages/controlmart/config/chaos-presets/moderate.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "moderate",
|
| 3 |
+
"name": "Moderate Chaos",
|
| 4 |
+
"description": "Medium probability chaos with diverse scenario types. Good balance for resilience testing without overwhelming the system.",
|
| 5 |
+
"globalProbability": 0.15,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "stale_data",
|
| 9 |
+
"weight": 12,
|
| 10 |
+
"description": "Eventual consistency delays",
|
| 11 |
+
"config": {
|
| 12 |
+
"staleDataAge": 60
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"type": "data_corruption",
|
| 17 |
+
"weight": 8,
|
| 18 |
+
"description": "Data quality issues and field corruption",
|
| 19 |
+
"config": {
|
| 20 |
+
"corruptFields": ["email", "status", "timestamp"],
|
| 21 |
+
"corruptionType": "wrong_type"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"type": "rate_limit",
|
| 26 |
+
"weight": 7,
|
| 27 |
+
"description": "API throttling",
|
| 28 |
+
"config": {
|
| 29 |
+
"rateLimitDelay": 2000,
|
| 30 |
+
"rateLimitMessage": "Rate limit exceeded"
|
| 31 |
+
}
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"type": "partial_data",
|
| 35 |
+
"weight": 6,
|
| 36 |
+
"description": "Incomplete result sets",
|
| 37 |
+
"config": {
|
| 38 |
+
"partialResults": {
|
| 39 |
+
"percentage": 70,
|
| 40 |
+
"randomize": true
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"type": "missing_data",
|
| 46 |
+
"weight": 5,
|
| 47 |
+
"description": "Missing records and fields",
|
| 48 |
+
"config": {
|
| 49 |
+
"missingRecords": true,
|
| 50 |
+
"throwError": false
|
| 51 |
+
}
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"type": "permission_denied",
|
| 55 |
+
"weight": 3,
|
| 56 |
+
"description": "Authorization failures",
|
| 57 |
+
"config": {
|
| 58 |
+
"permissionError": "Access denied - insufficient permissions"
|
| 59 |
+
}
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"type": "duplicate_data",
|
| 63 |
+
"weight": 4,
|
| 64 |
+
"description": "Duplicate records in results",
|
| 65 |
+
"config": {}
|
| 66 |
+
}
|
| 67 |
+
]
|
| 68 |
+
}
|
packages/controlmart/config/chaos-presets/process.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "process",
|
| 3 |
+
"name": "Process Chaos",
|
| 4 |
+
"description": "Business logic and data integrity failures only. No infrastructure or system faults.",
|
| 5 |
+
"globalProbability": 0.1,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "stale_data",
|
| 9 |
+
"weight": 30,
|
| 10 |
+
"description": "Eventual consistency delays (e.g. order not found immediately after creation)",
|
| 11 |
+
"config": {
|
| 12 |
+
"staleDataAge": 45
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"type": "partial_data",
|
| 17 |
+
"weight": 20,
|
| 18 |
+
"description": "Pagination and partial results (e.g. search returns subset)",
|
| 19 |
+
"config": {
|
| 20 |
+
"partialResults": {
|
| 21 |
+
"percentage": 75,
|
| 22 |
+
"randomize": false
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"type": "data_corruption",
|
| 28 |
+
"weight": 20,
|
| 29 |
+
"description": "Data quality issues (invalid enums, wrong formats)",
|
| 30 |
+
"config": {
|
| 31 |
+
"corruptFields": [
|
| 32 |
+
"orderStatus",
|
| 33 |
+
"orderPriority",
|
| 34 |
+
"warehouseId",
|
| 35 |
+
"customerId"
|
| 36 |
+
],
|
| 37 |
+
"corruptionType": "invalid_format"
|
| 38 |
+
}
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"type": "missing_data",
|
| 42 |
+
"weight": 15,
|
| 43 |
+
"description": "Missing required or optional fields",
|
| 44 |
+
"config": {
|
| 45 |
+
"missingFields": [
|
| 46 |
+
"customerName",
|
| 47 |
+
"shipToAddress",
|
| 48 |
+
"lines"
|
| 49 |
+
],
|
| 50 |
+
"throwError": false
|
| 51 |
+
}
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"type": "duplicate_data",
|
| 55 |
+
"weight": 10,
|
| 56 |
+
"description": "Duplicate records in list responses",
|
| 57 |
+
"config": {}
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"type": "invalid_state",
|
| 61 |
+
"weight": 5,
|
| 62 |
+
"description": "Records in logic-breaking states",
|
| 63 |
+
"config": {
|
| 64 |
+
"invalidStates": [
|
| 65 |
+
"SUSPENDED",
|
| 66 |
+
"ARCHIVED",
|
| 67 |
+
"UNKNOWN"
|
| 68 |
+
]
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
]
|
| 72 |
+
}
|
packages/controlmart/config/chaos-presets/realistic.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "realistic",
|
| 3 |
+
"name": "Realistic Chaos",
|
| 4 |
+
"description": "Chaos distribution matching real-world production failure rates. Based on observability data from distributed systems.",
|
| 5 |
+
"globalProbability": 0.08,
|
| 6 |
+
"scenarios": [
|
| 7 |
+
{
|
| 8 |
+
"type": "stale_data",
|
| 9 |
+
"weight": 40,
|
| 10 |
+
"description": "Most common: eventual consistency delays",
|
| 11 |
+
"config": {
|
| 12 |
+
"staleDataAge": 45
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"type": "rate_limit",
|
| 17 |
+
"weight": 20,
|
| 18 |
+
"description": "Common: API throttling",
|
| 19 |
+
"config": {
|
| 20 |
+
"rateLimitDelay": 1500,
|
| 21 |
+
"rateLimitMessage": "Rate limit exceeded"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"type": "partial_data",
|
| 26 |
+
"weight": 15,
|
| 27 |
+
"description": "Common: pagination and partial results",
|
| 28 |
+
"config": {
|
| 29 |
+
"partialResults": {
|
| 30 |
+
"percentage": 75,
|
| 31 |
+
"randomize": false
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
"type": "data_corruption",
|
| 37 |
+
"weight": 10,
|
| 38 |
+
"description": "Occasional: data quality issues",
|
| 39 |
+
"config": {
|
| 40 |
+
"corruptFields": ["email", "phoneNumber"],
|
| 41 |
+
"corruptionType": "invalid_format"
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"type": "missing_data",
|
| 46 |
+
"weight": 7,
|
| 47 |
+
"description": "Occasional: missing optional fields",
|
| 48 |
+
"config": {
|
| 49 |
+
"missingFields": ["metadata", "description"],
|
| 50 |
+
"throwError": false
|
| 51 |
+
}
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"type": "duplicate_data",
|
| 55 |
+
"weight": 4,
|
| 56 |
+
"description": "Rare: duplicate records",
|
| 57 |
+
"config": {}
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"type": "permission_denied",
|
| 61 |
+
"weight": 3,
|
| 62 |
+
"description": "Rare: authorization failures",
|
| 63 |
+
"config": {
|
| 64 |
+
"permissionError": "Insufficient permissions"
|
| 65 |
+
}
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"type": "dependency_failure",
|
| 69 |
+
"weight": 1,
|
| 70 |
+
"description": "Very rare: complete service outages",
|
| 71 |
+
"config": {
|
| 72 |
+
"dependencyService": "external-service"
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
]
|
| 76 |
+
}
|
packages/controlmart/docs/api/capabilities-api.md
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Capabilities API Documentation
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
The Capabilities API provides endpoints for discovering and executing business capabilities in the Morpheus platform.
|
| 6 |
+
|
| 7 |
+
## Base URL
|
| 8 |
+
|
| 9 |
+
```
|
| 10 |
+
http://localhost:4000
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
## Endpoints
|
| 14 |
+
|
| 15 |
+
### 1. List All Capabilities
|
| 16 |
+
|
| 17 |
+
**GET** `/capabilities`
|
| 18 |
+
|
| 19 |
+
Returns all available capabilities with optional filtering and search.
|
| 20 |
+
|
| 21 |
+
**Query Parameters:**
|
| 22 |
+
- `q` (string, optional): Full-text search across name, description, and tags
|
| 23 |
+
- `domain` (string[], optional): Filter by domain(s)
|
| 24 |
+
- `complexity` (string, optional): Filter by complexity level (`simple`, `medium`, `complex`)
|
| 25 |
+
- `services` (string[], optional): Filter by service(s) used
|
| 26 |
+
- `personas` (string[], optional): Filter by persona(s)
|
| 27 |
+
- `patterns` (string[], optional): Filter by workflow pattern(s)
|
| 28 |
+
|
| 29 |
+
**Example Requests:**
|
| 30 |
+
|
| 31 |
+
```bash
|
| 32 |
+
# Get all capabilities
|
| 33 |
+
curl http://localhost:4000/capabilities
|
| 34 |
+
|
| 35 |
+
# Search for inventory-related capabilities
|
| 36 |
+
curl "http://localhost:4000/capabilities?q=inventory"
|
| 37 |
+
|
| 38 |
+
# Filter by domain
|
| 39 |
+
curl "http://localhost:4000/capabilities?domain=inventory&domain=warehousing"
|
| 40 |
+
|
| 41 |
+
# Filter by complexity
|
| 42 |
+
curl "http://localhost:4000/capabilities?complexity=simple"
|
| 43 |
+
|
| 44 |
+
# Combined search and filter
|
| 45 |
+
curl "http://localhost:4000/capabilities?q=check&complexity=simple"
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
**Response:**
|
| 49 |
+
|
| 50 |
+
```json
|
| 51 |
+
[
|
| 52 |
+
{
|
| 53 |
+
"id": "inventory-check",
|
| 54 |
+
"name": "Inventory Check",
|
| 55 |
+
"description": "Check current inventory levels for one or more SKUs...",
|
| 56 |
+
"tags": {
|
| 57 |
+
"domain": ["inventory", "warehousing"],
|
| 58 |
+
"complexity": "simple",
|
| 59 |
+
"services": ["wms"],
|
| 60 |
+
"personas": ["warehouse-worker", "store-manager"],
|
| 61 |
+
"patterns": ["sequential"]
|
| 62 |
+
},
|
| 63 |
+
"odId": "inventory-check-standard-v1",
|
| 64 |
+
"version": "1.0.0",
|
| 65 |
+
"metadata": {
|
| 66 |
+
"author": "morpheus-team",
|
| 67 |
+
"estimatedDuration": 2000
|
| 68 |
+
},
|
| 69 |
+
"chaos": {
|
| 70 |
+
"enabled": true,
|
| 71 |
+
"probability": 0.1,
|
| 72 |
+
"scenarios": [...]
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
]
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
### 2. Get Capability by ID
|
| 79 |
+
|
| 80 |
+
**GET** `/capabilities/:id`
|
| 81 |
+
|
| 82 |
+
Returns a single capability by its ID.
|
| 83 |
+
|
| 84 |
+
**Example:**
|
| 85 |
+
|
| 86 |
+
```bash
|
| 87 |
+
curl http://localhost:4000/capabilities/inventory-check
|
| 88 |
+
```
|
| 89 |
+
|
| 90 |
+
### 3. Execute Capability
|
| 91 |
+
|
| 92 |
+
**POST** `/capabilities/:id/execute`
|
| 93 |
+
|
| 94 |
+
Executes a capability within a world context.
|
| 95 |
+
|
| 96 |
+
**Request Body:**
|
| 97 |
+
|
| 98 |
+
```json
|
| 99 |
+
{
|
| 100 |
+
"worldId": "world-id-here",
|
| 101 |
+
"inputs": {
|
| 102 |
+
"sku": "SKU-001",
|
| 103 |
+
"locationId": "WH-01"
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
**Example:**
|
| 109 |
+
|
| 110 |
+
```bash
|
| 111 |
+
curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 112 |
+
-H "Content-Type: application/json" \
|
| 113 |
+
-d '{
|
| 114 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 115 |
+
"inputs": {
|
| 116 |
+
"sku": "SKU-001",
|
| 117 |
+
"locationId": "WH-01"
|
| 118 |
+
}
|
| 119 |
+
}'
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
**Response:**
|
| 123 |
+
|
| 124 |
+
```json
|
| 125 |
+
{
|
| 126 |
+
"capabilityId": "inventory-check",
|
| 127 |
+
"odId": "inventory-check-standard-v1",
|
| 128 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 129 |
+
"result": {
|
| 130 |
+
"runId": "inventory-check-standard-v1",
|
| 131 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 132 |
+
"descriptorId": "inventory-check-standard-v1",
|
| 133 |
+
"descriptorVersion": "1.0.0",
|
| 134 |
+
"status": "success",
|
| 135 |
+
"startTime": "2025-11-20T13:00:00.000Z",
|
| 136 |
+
"endTime": "2025-11-20T13:00:01.245Z",
|
| 137 |
+
"durationMs": 1245,
|
| 138 |
+
"stepResults": [...],
|
| 139 |
+
"totalSteps": 3,
|
| 140 |
+
"successfulSteps": 3,
|
| 141 |
+
"failedSteps": 0,
|
| 142 |
+
"skippedSteps": 0
|
| 143 |
+
},
|
| 144 |
+
"executedAt": "2025-11-20T13:00:00.000Z",
|
| 145 |
+
"durationMs": 1245,
|
| 146 |
+
"status": "success",
|
| 147 |
+
"capabilityInWorld": true,
|
| 148 |
+
"chaosMetadata": {
|
| 149 |
+
"enabled": true,
|
| 150 |
+
"injectionCount": 1,
|
| 151 |
+
"injections": [
|
| 152 |
+
{
|
| 153 |
+
"stepId": "fetch-inventory",
|
| 154 |
+
"stepName": "Fetch Inventory Records",
|
| 155 |
+
"scenarioType": "missing_data",
|
| 156 |
+
"scenarioDescription": "Records not found or empty results",
|
| 157 |
+
"configSource": "world",
|
| 158 |
+
"probability": 0.2,
|
| 159 |
+
"seed": "test-seed-123",
|
| 160 |
+
"timestamp": "2025-11-20T13:00:00.500Z",
|
| 161 |
+
"modifications": [
|
| 162 |
+
"Returned empty result set",
|
| 163 |
+
"Original had 5 records"
|
| 164 |
+
],
|
| 165 |
+
"config": {
|
| 166 |
+
"missingRecords": true,
|
| 167 |
+
"throwError": false
|
| 168 |
+
}
|
| 169 |
+
}
|
| 170 |
+
],
|
| 171 |
+
"cascadeResolution": {
|
| 172 |
+
"finalSource": "world"
|
| 173 |
+
},
|
| 174 |
+
"probability": 0.2,
|
| 175 |
+
"seed": "test-seed-123"
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
```
|
| 179 |
+
|
| 180 |
+
**Note:** The `chaosMetadata` field is only present when chaos engineering is enabled. See the [Chaos Telemetry](#chaos-telemetry) section below for details.
|
| 181 |
+
|
| 182 |
+
## Chaos Telemetry
|
| 183 |
+
|
| 184 |
+
When chaos engineering is enabled, capability execution responses include comprehensive telemetry about chaos injections that occurred during execution. This telemetry helps you understand exactly what chaos was injected, when, and from which configuration level.
|
| 185 |
+
|
| 186 |
+
### ChaosTelemetry Schema
|
| 187 |
+
|
| 188 |
+
```typescript
|
| 189 |
+
{
|
| 190 |
+
enabled: boolean; // Whether chaos was enabled for this execution
|
| 191 |
+
injectionCount: number; // Total number of chaos injections that occurred
|
| 192 |
+
injections: ChaosInjectionMetadata[]; // Details of each injection
|
| 193 |
+
cascadeResolution: {
|
| 194 |
+
finalSource: string; // Which config level provided the chaos policy
|
| 195 |
+
// Values: "env" | "step" | "od" | "capability" | "world" | "global"
|
| 196 |
+
};
|
| 197 |
+
probability: number; // Probability that was used (0.0 to 1.0)
|
| 198 |
+
seed?: string; // Seed used for reproducible chaos (if any)
|
| 199 |
+
}
|
| 200 |
+
```
|
| 201 |
+
|
| 202 |
+
### ChaosInjectionMetadata Schema
|
| 203 |
+
|
| 204 |
+
Each injection in the `injections` array contains:
|
| 205 |
+
|
| 206 |
+
```typescript
|
| 207 |
+
{
|
| 208 |
+
stepId: string; // OD step ID where chaos was injected
|
| 209 |
+
stepName: string; // Human-readable step name
|
| 210 |
+
scenarioType: string; // Type of chaos scenario (e.g., "missing_data", "data_corruption")
|
| 211 |
+
scenarioDescription: string; // Human-readable description
|
| 212 |
+
configSource: string; // Config level that provided the chaos scenario
|
| 213 |
+
// Values: "step" | "od" | "capability" | "world" | "global" | "env"
|
| 214 |
+
probability: number; // Probability setting at time of injection
|
| 215 |
+
seed?: string; // Seed if used for this injection
|
| 216 |
+
timestamp: string; // ISO 8601 timestamp of injection
|
| 217 |
+
modifications: string[]; // List of modifications made to the data
|
| 218 |
+
config?: object; // Scenario-specific configuration used
|
| 219 |
+
}
|
| 220 |
+
```
|
| 221 |
+
|
| 222 |
+
### Example: No Chaos Injected
|
| 223 |
+
|
| 224 |
+
When chaos is enabled but no injections occurred (due to probability):
|
| 225 |
+
|
| 226 |
+
```json
|
| 227 |
+
{
|
| 228 |
+
"capabilityId": "inventory-check",
|
| 229 |
+
"status": "success",
|
| 230 |
+
"chaosMetadata": {
|
| 231 |
+
"enabled": true,
|
| 232 |
+
"injectionCount": 0,
|
| 233 |
+
"injections": [],
|
| 234 |
+
"cascadeResolution": {
|
| 235 |
+
"finalSource": "world"
|
| 236 |
+
},
|
| 237 |
+
"probability": 0.1,
|
| 238 |
+
"seed": null
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
```
|
| 242 |
+
|
| 243 |
+
### Example: Multiple Chaos Injections
|
| 244 |
+
|
| 245 |
+
When multiple steps experience chaos:
|
| 246 |
+
|
| 247 |
+
```json
|
| 248 |
+
{
|
| 249 |
+
"capabilityId": "order-fulfillment",
|
| 250 |
+
"status": "partial",
|
| 251 |
+
"chaosMetadata": {
|
| 252 |
+
"enabled": true,
|
| 253 |
+
"injectionCount": 2,
|
| 254 |
+
"injections": [
|
| 255 |
+
{
|
| 256 |
+
"stepId": "fetch-order",
|
| 257 |
+
"stepName": "Fetch Order Details",
|
| 258 |
+
"scenarioType": "stale_data",
|
| 259 |
+
"scenarioDescription": "Return outdated data",
|
| 260 |
+
"configSource": "world",
|
| 261 |
+
"probability": 0.25,
|
| 262 |
+
"timestamp": "2025-11-20T14:30:00.100Z",
|
| 263 |
+
"modifications": [
|
| 264 |
+
"Made data appear 60 minutes old",
|
| 265 |
+
"Updated timestamp to 2025-11-20T13:30:00.000Z"
|
| 266 |
+
],
|
| 267 |
+
"config": {
|
| 268 |
+
"staleDataAge": 60
|
| 269 |
+
}
|
| 270 |
+
},
|
| 271 |
+
{
|
| 272 |
+
"stepId": "check-inventory",
|
| 273 |
+
"stepName": "Check Inventory Availability",
|
| 274 |
+
"scenarioType": "partial_data",
|
| 275 |
+
"scenarioDescription": "Return incomplete results",
|
| 276 |
+
"configSource": "world",
|
| 277 |
+
"probability": 0.25,
|
| 278 |
+
"timestamp": "2025-11-20T14:30:00.500Z",
|
| 279 |
+
"modifications": [
|
| 280 |
+
"Returned 3 out of 6 SKUs",
|
| 281 |
+
"Missing SKUs: SKU-004, SKU-005, SKU-006"
|
| 282 |
+
],
|
| 283 |
+
"config": {
|
| 284 |
+
"partialResults": {
|
| 285 |
+
"percentage": 50,
|
| 286 |
+
"randomize": true
|
| 287 |
+
}
|
| 288 |
+
}
|
| 289 |
+
}
|
| 290 |
+
],
|
| 291 |
+
"cascadeResolution": {
|
| 292 |
+
"finalSource": "world"
|
| 293 |
+
},
|
| 294 |
+
"probability": 0.25,
|
| 295 |
+
"seed": "test-123"
|
| 296 |
+
}
|
| 297 |
+
}
|
| 298 |
+
```
|
| 299 |
+
|
| 300 |
+
### Using Chaos Telemetry
|
| 301 |
+
|
| 302 |
+
**1. Debugging Test Failures**
|
| 303 |
+
|
| 304 |
+
When a test fails unexpectedly, check if chaos was injected:
|
| 305 |
+
|
| 306 |
+
```bash
|
| 307 |
+
curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 308 |
+
-H "Content-Type: application/json" \
|
| 309 |
+
-d '{"worldId": "..."}' | jq '.chaosMetadata'
|
| 310 |
+
```
|
| 311 |
+
|
| 312 |
+
**2. Analyzing Chaos Impact**
|
| 313 |
+
|
| 314 |
+
Track which scenarios are triggered most frequently:
|
| 315 |
+
|
| 316 |
+
```bash
|
| 317 |
+
# Execute capability multiple times
|
| 318 |
+
for i in {1..100}; do
|
| 319 |
+
curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 320 |
+
-H "Content-Type: application/json" \
|
| 321 |
+
-d '{"worldId": "..."}' >> chaos-results.json
|
| 322 |
+
done
|
| 323 |
+
|
| 324 |
+
# Analyze results
|
| 325 |
+
cat chaos-results.json | jq '.chaosMetadata.injections[].scenarioType' | sort | uniq -c
|
| 326 |
+
```
|
| 327 |
+
|
| 328 |
+
**3. Reproducing Specific Failures**
|
| 329 |
+
|
| 330 |
+
Use the seed from a failed execution to reproduce the exact same chaos:
|
| 331 |
+
|
| 332 |
+
```bash
|
| 333 |
+
# First execution - note the seed from response
|
| 334 |
+
RESPONSE=$(curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 335 |
+
-H "Content-Type: application/json" \
|
| 336 |
+
-d '{"worldId": "..."}')
|
| 337 |
+
|
| 338 |
+
SEED=$(echo $RESPONSE | jq -r '.chaosMetadata.seed')
|
| 339 |
+
|
| 340 |
+
# Configure world with the same seed to reproduce
|
| 341 |
+
curl -X PUT "http://localhost:4000/world/$WORLD_ID/chaos" \
|
| 342 |
+
-H "Content-Type: application/json" \
|
| 343 |
+
-d "{\"enabled\": true, \"probability\": 0.5, \"seed\": \"$SEED\", ...}"
|
| 344 |
+
```
|
| 345 |
+
|
| 346 |
+
**4. Understanding Config Source**
|
| 347 |
+
|
| 348 |
+
The `configSource` field in each injection tells you which configuration level provided the chaos scenario:
|
| 349 |
+
|
| 350 |
+
- `"env"` - From `CHAOS_PRESET` environment variable
|
| 351 |
+
- `"world"` - From world-specific chaos configuration
|
| 352 |
+
- `"capability"` - From capability-level override
|
| 353 |
+
- `"od"` - From operational descriptor definition
|
| 354 |
+
- `"step"` - From step-level chaos policy
|
| 355 |
+
- `"global"` - From global preset loaded at startup
|
| 356 |
+
|
| 357 |
+
This helps you understand the chaos configuration hierarchy and debug unexpected behavior.
|
| 358 |
+
|
| 359 |
+
For comprehensive chaos engineering documentation, including all chaos endpoints and configuration options, see the [Chaos Engineering API documentation](./chaos-api.md).
|
| 360 |
+
|
| 361 |
+
## Chaos Engineering API
|
| 362 |
+
|
| 363 |
+
### 1. List Chaos Presets
|
| 364 |
+
|
| 365 |
+
**GET** `/chaos/presets`
|
| 366 |
+
|
| 367 |
+
Returns all available chaos presets.
|
| 368 |
+
|
| 369 |
+
**Example:**
|
| 370 |
+
|
| 371 |
+
```bash
|
| 372 |
+
curl http://localhost:4000/chaos/presets
|
| 373 |
+
```
|
| 374 |
+
|
| 375 |
+
**Response:**
|
| 376 |
+
|
| 377 |
+
```json
|
| 378 |
+
[
|
| 379 |
+
{
|
| 380 |
+
"id": "light",
|
| 381 |
+
"name": "Light Chaos",
|
| 382 |
+
"description": "Minimal chaos for production-like testing",
|
| 383 |
+
"probability": 0.05,
|
| 384 |
+
"scenarios": 4
|
| 385 |
+
},
|
| 386 |
+
{
|
| 387 |
+
"id": "moderate",
|
| 388 |
+
"name": "Moderate Chaos",
|
| 389 |
+
"description": "Balanced chaos for resilience testing",
|
| 390 |
+
"probability": 0.15,
|
| 391 |
+
"scenarios": 7
|
| 392 |
+
}
|
| 393 |
+
]
|
| 394 |
+
```
|
| 395 |
+
|
| 396 |
+
### 2. Get Chaos Preset Details
|
| 397 |
+
|
| 398 |
+
**GET** `/chaos/presets/:id`
|
| 399 |
+
|
| 400 |
+
Returns detailed configuration for a specific chaos preset.
|
| 401 |
+
|
| 402 |
+
**Example:**
|
| 403 |
+
|
| 404 |
+
```bash
|
| 405 |
+
curl http://localhost:4000/chaos/presets/aggressive
|
| 406 |
+
```
|
| 407 |
+
|
| 408 |
+
### 3. Get Chaos Status
|
| 409 |
+
|
| 410 |
+
**GET** `/chaos/status`
|
| 411 |
+
|
| 412 |
+
Returns the current chaos system status.
|
| 413 |
+
|
| 414 |
+
**Example:**
|
| 415 |
+
|
| 416 |
+
```bash
|
| 417 |
+
curl http://localhost:4000/chaos/status
|
| 418 |
+
```
|
| 419 |
+
|
| 420 |
+
**Response:**
|
| 421 |
+
|
| 422 |
+
```json
|
| 423 |
+
{
|
| 424 |
+
"enabled": true,
|
| 425 |
+
"globalPreset": "realistic",
|
| 426 |
+
"availablePresets": ["light", "moderate", "realistic", "aggressive"],
|
| 427 |
+
"env": {
|
| 428 |
+
"CHAOS_ENABLED": "true",
|
| 429 |
+
"CHAOS_PRESET": "realistic"
|
| 430 |
+
}
|
| 431 |
+
}
|
| 432 |
+
```
|
| 433 |
+
|
| 434 |
+
## Capability Input Reference
|
| 435 |
+
|
| 436 |
+
### Inventory Check
|
| 437 |
+
|
| 438 |
+
```json
|
| 439 |
+
{
|
| 440 |
+
"sku": "SKU-001",
|
| 441 |
+
"locationId": "WH-01" // optional
|
| 442 |
+
}
|
| 443 |
+
```
|
| 444 |
+
|
| 445 |
+
### Shipment Tracking
|
| 446 |
+
|
| 447 |
+
```json
|
| 448 |
+
{
|
| 449 |
+
"shipmentId": "SHIP-001"
|
| 450 |
+
}
|
| 451 |
+
```
|
| 452 |
+
|
| 453 |
+
### Equipment Availability Check
|
| 454 |
+
|
| 455 |
+
```json
|
| 456 |
+
{
|
| 457 |
+
"equipmentType": "forklift",
|
| 458 |
+
"zoneId": "ZONE-A" // optional
|
| 459 |
+
}
|
| 460 |
+
```
|
| 461 |
+
|
| 462 |
+
### Dock Appointment Scheduling
|
| 463 |
+
|
| 464 |
+
```json
|
| 465 |
+
{
|
| 466 |
+
"date": "2025-11-21",
|
| 467 |
+
"dockDoorId": "DOCK-01",
|
| 468 |
+
"appointmentType": "inbound" // optional: "inbound" or "outbound"
|
| 469 |
+
}
|
| 470 |
+
```
|
| 471 |
+
|
| 472 |
+
## Environment Variables
|
| 473 |
+
|
| 474 |
+
- `CHAOS_ENABLED`: Enable/disable chaos injection (`true`/`false`)
|
| 475 |
+
- `CHAOS_PRESET`: Global chaos preset (`light`/`moderate`/`realistic`/`aggressive`)
|
| 476 |
+
- `MONGO_URI`: MongoDB connection string
|
| 477 |
+
- `DB_NAME`: Database name
|
| 478 |
+
- `PORT`: Server port (default: 4000)
|
| 479 |
+
|
| 480 |
+
## Related APIs
|
| 481 |
+
|
| 482 |
+
- [Persona API](./persona-api.md) - Discover personas and their capabilities
|
| 483 |
+
- [Chaos Engineering API](./chaos-api.md) - Configure chaos injection policies
|
| 484 |
+
- [World API](./world-api.md) - Manage world contexts for capability execution
|
packages/controlmart/docs/api/chaos-api.md
ADDED
|
@@ -0,0 +1,628 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Chaos Engineering API Documentation
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
The Chaos Engineering API provides endpoints for managing chaos injection configuration in the Morpheus platform. Chaos engineering helps test system resilience by intentionally injecting failures, data corruption, and other anomalies during capability execution.
|
| 6 |
+
|
| 7 |
+
## Base URL
|
| 8 |
+
|
| 9 |
+
```
|
| 10 |
+
http://localhost:4000
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
## Chaos Priority Cascade
|
| 14 |
+
|
| 15 |
+
The Morpheus platform uses a priority cascade for chaos configuration resolution:
|
| 16 |
+
|
| 17 |
+
1. **ENV** - Environment variables (`CHAOS_ENABLED`, `CHAOS_PRESET`)
|
| 18 |
+
2. **Step** - Step-level chaos policy (in OD definition)
|
| 19 |
+
3. **OD** - Operational Descriptor-level chaos policy
|
| 20 |
+
4. **Capability** - Capability-level chaos override
|
| 21 |
+
5. **World** - World-level chaos policy
|
| 22 |
+
6. **Global** - Global preset loaded at startup
|
| 23 |
+
|
| 24 |
+
Higher priority levels override lower levels. This allows fine-grained control over chaos injection at different granularities.
|
| 25 |
+
|
| 26 |
+
## Global Chaos Endpoints
|
| 27 |
+
|
| 28 |
+
### 1. List All Chaos Presets
|
| 29 |
+
|
| 30 |
+
**GET** `/chaos/presets`
|
| 31 |
+
|
| 32 |
+
Returns all available chaos presets with metadata. Presets are pre-configured chaos policies that can be applied at any level.
|
| 33 |
+
|
| 34 |
+
**Example:**
|
| 35 |
+
|
| 36 |
+
```bash
|
| 37 |
+
curl http://localhost:4000/chaos/presets
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
**Response:**
|
| 41 |
+
|
| 42 |
+
```json
|
| 43 |
+
{
|
| 44 |
+
"success": true,
|
| 45 |
+
"count": 4,
|
| 46 |
+
"data": [
|
| 47 |
+
{
|
| 48 |
+
"id": "light",
|
| 49 |
+
"name": "Light Chaos",
|
| 50 |
+
"description": "Minimal chaos for production-like testing",
|
| 51 |
+
"probability": 0.05,
|
| 52 |
+
"scenarioCount": 4
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"id": "moderate",
|
| 56 |
+
"name": "Moderate Chaos",
|
| 57 |
+
"description": "Balanced chaos for resilience testing",
|
| 58 |
+
"probability": 0.15,
|
| 59 |
+
"scenarioCount": 7
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"id": "realistic",
|
| 63 |
+
"name": "Realistic Chaos",
|
| 64 |
+
"description": "Real-world failure patterns for comprehensive testing",
|
| 65 |
+
"probability": 0.25,
|
| 66 |
+
"scenarioCount": 11
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"id": "aggressive",
|
| 70 |
+
"name": "Aggressive Chaos",
|
| 71 |
+
"description": "High-frequency chaos for stress testing",
|
| 72 |
+
"probability": 0.40,
|
| 73 |
+
"scenarioCount": 11
|
| 74 |
+
}
|
| 75 |
+
]
|
| 76 |
+
}
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
### 2. Get Chaos Preset Details
|
| 80 |
+
|
| 81 |
+
**GET** `/chaos/presets/:id`
|
| 82 |
+
|
| 83 |
+
Returns the full chaos policy configuration for a specific preset, including all scenarios and their configurations.
|
| 84 |
+
|
| 85 |
+
**Path Parameters:**
|
| 86 |
+
- `id` (string, required): Preset ID (e.g., "light", "moderate", "realistic", "aggressive")
|
| 87 |
+
|
| 88 |
+
**Example:**
|
| 89 |
+
|
| 90 |
+
```bash
|
| 91 |
+
curl http://localhost:4000/chaos/presets/realistic
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
**Response:**
|
| 95 |
+
|
| 96 |
+
```json
|
| 97 |
+
{
|
| 98 |
+
"success": true,
|
| 99 |
+
"data": {
|
| 100 |
+
"enabled": true,
|
| 101 |
+
"probability": 0.25,
|
| 102 |
+
"scenarios": [
|
| 103 |
+
{
|
| 104 |
+
"type": "missing_data",
|
| 105 |
+
"weight": 20,
|
| 106 |
+
"description": "Records not found or empty results",
|
| 107 |
+
"config": {
|
| 108 |
+
"missingRecords": true,
|
| 109 |
+
"throwError": true
|
| 110 |
+
}
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"type": "data_corruption",
|
| 114 |
+
"weight": 15,
|
| 115 |
+
"description": "Corrupt critical fields in responses",
|
| 116 |
+
"config": {
|
| 117 |
+
"corruptFields": ["id", "status"],
|
| 118 |
+
"corruptionType": "null"
|
| 119 |
+
}
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
"type": "stale_data",
|
| 123 |
+
"weight": 15,
|
| 124 |
+
"description": "Return outdated data",
|
| 125 |
+
"config": {
|
| 126 |
+
"staleDataAge": 60
|
| 127 |
+
}
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
"type": "partial_data",
|
| 131 |
+
"weight": 15,
|
| 132 |
+
"description": "Return incomplete results",
|
| 133 |
+
"config": {
|
| 134 |
+
"partialResults": {
|
| 135 |
+
"percentage": 50,
|
| 136 |
+
"randomize": true
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
],
|
| 141 |
+
"seed": undefined
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
### 3. Get Chaos System Status
|
| 147 |
+
|
| 148 |
+
**GET** `/chaos/status`
|
| 149 |
+
|
| 150 |
+
Returns the current global chaos system configuration and statistics.
|
| 151 |
+
|
| 152 |
+
**Example:**
|
| 153 |
+
|
| 154 |
+
```bash
|
| 155 |
+
curl http://localhost:4000/chaos/status
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
**Response:**
|
| 159 |
+
|
| 160 |
+
```json
|
| 161 |
+
{
|
| 162 |
+
"success": true,
|
| 163 |
+
"data": {
|
| 164 |
+
"enabled": true,
|
| 165 |
+
"activePreset": "realistic",
|
| 166 |
+
"stats": {
|
| 167 |
+
"presetCount": 4,
|
| 168 |
+
"worldPolicyCount": 2,
|
| 169 |
+
"capabilityOverrideCount": 0,
|
| 170 |
+
"odOverrideCount": 0
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
```
|
| 175 |
+
|
| 176 |
+
**Status Fields:**
|
| 177 |
+
- `enabled`: Whether chaos is globally enabled (from `CHAOS_ENABLED` env var)
|
| 178 |
+
- `activePreset`: Current global preset name (from `CHAOS_PRESET` env var)
|
| 179 |
+
- `stats.presetCount`: Number of available chaos presets
|
| 180 |
+
- `stats.worldPolicyCount`: Number of worlds with custom chaos policies
|
| 181 |
+
- `stats.capabilityOverrideCount`: Number of capabilities with chaos overrides
|
| 182 |
+
- `stats.odOverrideCount`: Number of ODs with chaos policies
|
| 183 |
+
|
| 184 |
+
## World-Specific Chaos Endpoints
|
| 185 |
+
|
| 186 |
+
Worlds can have their own chaos policies that override the global configuration for all capabilities executed in that world context.
|
| 187 |
+
|
| 188 |
+
### 4. Get World Chaos Configuration
|
| 189 |
+
|
| 190 |
+
**GET** `/world/:worldId/chaos`
|
| 191 |
+
|
| 192 |
+
Returns the chaos policy configured for a specific world.
|
| 193 |
+
|
| 194 |
+
**Path Parameters:**
|
| 195 |
+
- `worldId` (string, required): World ID (MongoDB ObjectId)
|
| 196 |
+
|
| 197 |
+
**Example:**
|
| 198 |
+
|
| 199 |
+
```bash
|
| 200 |
+
curl http://localhost:4000/world/673d9a8f1234567890abcdef/chaos
|
| 201 |
+
```
|
| 202 |
+
|
| 203 |
+
**Response:**
|
| 204 |
+
|
| 205 |
+
```json
|
| 206 |
+
{
|
| 207 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 208 |
+
"worldName": "chaos-test-world",
|
| 209 |
+
"chaos": {
|
| 210 |
+
"enabled": true,
|
| 211 |
+
"probability": 0.3,
|
| 212 |
+
"scenarios": [
|
| 213 |
+
{
|
| 214 |
+
"type": "missing_data",
|
| 215 |
+
"weight": 50,
|
| 216 |
+
"description": "Simulate missing inventory records",
|
| 217 |
+
"config": {
|
| 218 |
+
"missingRecords": true,
|
| 219 |
+
"throwError": false
|
| 220 |
+
}
|
| 221 |
+
},
|
| 222 |
+
{
|
| 223 |
+
"type": "data_corruption",
|
| 224 |
+
"weight": 30,
|
| 225 |
+
"description": "Corrupt quantity fields",
|
| 226 |
+
"config": {
|
| 227 |
+
"corruptFields": ["quantity", "available"],
|
| 228 |
+
"corruptionType": "wrong_type"
|
| 229 |
+
}
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"type": "rate_limit",
|
| 233 |
+
"weight": 20,
|
| 234 |
+
"description": "Simulate API rate limiting",
|
| 235 |
+
"config": {
|
| 236 |
+
"rateLimitDelay": 2000,
|
| 237 |
+
"rateLimitMessage": "Rate limit exceeded"
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
],
|
| 241 |
+
"seed": "test-seed-123"
|
| 242 |
+
}
|
| 243 |
+
}
|
| 244 |
+
```
|
| 245 |
+
|
| 246 |
+
**Default Response (No Chaos Configured):**
|
| 247 |
+
|
| 248 |
+
```json
|
| 249 |
+
{
|
| 250 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 251 |
+
"worldName": "normal-world",
|
| 252 |
+
"chaos": {
|
| 253 |
+
"enabled": false,
|
| 254 |
+
"probability": 0.0,
|
| 255 |
+
"scenarios": []
|
| 256 |
+
}
|
| 257 |
+
}
|
| 258 |
+
```
|
| 259 |
+
|
| 260 |
+
### 5. Update World Chaos Configuration
|
| 261 |
+
|
| 262 |
+
**PUT** `/world/:worldId/chaos`
|
| 263 |
+
|
| 264 |
+
Sets or updates the chaos policy for a specific world. This configuration will apply to all capabilities executed in this world.
|
| 265 |
+
|
| 266 |
+
**Path Parameters:**
|
| 267 |
+
- `worldId` (string, required): World ID (MongoDB ObjectId)
|
| 268 |
+
|
| 269 |
+
**Request Body:**
|
| 270 |
+
|
| 271 |
+
```json
|
| 272 |
+
{
|
| 273 |
+
"enabled": true,
|
| 274 |
+
"probability": 0.2,
|
| 275 |
+
"scenarios": [
|
| 276 |
+
{
|
| 277 |
+
"type": "missing_data",
|
| 278 |
+
"weight": 60,
|
| 279 |
+
"description": "Simulate missing records",
|
| 280 |
+
"config": {
|
| 281 |
+
"missingRecords": true,
|
| 282 |
+
"throwError": true
|
| 283 |
+
}
|
| 284 |
+
},
|
| 285 |
+
{
|
| 286 |
+
"type": "stale_data",
|
| 287 |
+
"weight": 40,
|
| 288 |
+
"description": "Return outdated data",
|
| 289 |
+
"config": {
|
| 290 |
+
"staleDataAge": 30
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
],
|
| 294 |
+
"seed": "reproducible-chaos-seed"
|
| 295 |
+
}
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
**Example:**
|
| 299 |
+
|
| 300 |
+
```bash
|
| 301 |
+
curl -X PUT http://localhost:4000/world/673d9a8f1234567890abcdef/chaos \
|
| 302 |
+
-H "Content-Type: application/json" \
|
| 303 |
+
-d '{
|
| 304 |
+
"enabled": true,
|
| 305 |
+
"probability": 0.2,
|
| 306 |
+
"scenarios": [
|
| 307 |
+
{
|
| 308 |
+
"type": "missing_data",
|
| 309 |
+
"weight": 60,
|
| 310 |
+
"description": "Simulate missing records",
|
| 311 |
+
"config": {
|
| 312 |
+
"missingRecords": true,
|
| 313 |
+
"throwError": true
|
| 314 |
+
}
|
| 315 |
+
}
|
| 316 |
+
]
|
| 317 |
+
}'
|
| 318 |
+
```
|
| 319 |
+
|
| 320 |
+
**Response:**
|
| 321 |
+
|
| 322 |
+
```json
|
| 323 |
+
{
|
| 324 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 325 |
+
"chaos": {
|
| 326 |
+
"enabled": true,
|
| 327 |
+
"probability": 0.2,
|
| 328 |
+
"scenarios": [...]
|
| 329 |
+
},
|
| 330 |
+
"message": "World chaos configuration updated successfully"
|
| 331 |
+
}
|
| 332 |
+
```
|
| 333 |
+
|
| 334 |
+
### 6. Delete World Chaos Configuration
|
| 335 |
+
|
| 336 |
+
**DELETE** `/world/:worldId/chaos`
|
| 337 |
+
|
| 338 |
+
Removes the custom chaos policy from a world, causing it to fall back to the global chaos configuration.
|
| 339 |
+
|
| 340 |
+
**Path Parameters:**
|
| 341 |
+
- `worldId` (string, required): World ID (MongoDB ObjectId)
|
| 342 |
+
|
| 343 |
+
**Example:**
|
| 344 |
+
|
| 345 |
+
```bash
|
| 346 |
+
curl -X DELETE http://localhost:4000/world/673d9a8f1234567890abcdef/chaos
|
| 347 |
+
```
|
| 348 |
+
|
| 349 |
+
**Response:**
|
| 350 |
+
|
| 351 |
+
```json
|
| 352 |
+
{
|
| 353 |
+
"worldId": "673d9a8f1234567890abcdef",
|
| 354 |
+
"message": "World chaos configuration removed successfully"
|
| 355 |
+
}
|
| 356 |
+
```
|
| 357 |
+
|
| 358 |
+
## Chaos Policy Schema
|
| 359 |
+
|
| 360 |
+
### ChaosPolicy Object
|
| 361 |
+
|
| 362 |
+
```typescript
|
| 363 |
+
{
|
| 364 |
+
enabled: boolean; // Whether chaos injection is enabled
|
| 365 |
+
probability: number; // 0.0 to 1.0 - overall chance chaos occurs
|
| 366 |
+
scenarios: ChaosScenario[]; // Array of possible chaos scenarios
|
| 367 |
+
seed?: string; // Optional seed for reproducible chaos
|
| 368 |
+
}
|
| 369 |
+
```
|
| 370 |
+
|
| 371 |
+
### ChaosScenario Object
|
| 372 |
+
|
| 373 |
+
```typescript
|
| 374 |
+
{
|
| 375 |
+
type: string; // Scenario type (see Chaos Scenario Types below)
|
| 376 |
+
weight: number; // Relative probability weight (higher = more likely)
|
| 377 |
+
description: string; // Human-readable description
|
| 378 |
+
config: ChaosConfig; // Scenario-specific configuration
|
| 379 |
+
}
|
| 380 |
+
```
|
| 381 |
+
|
| 382 |
+
## Chaos Scenario Types
|
| 383 |
+
|
| 384 |
+
### 1. missing_data
|
| 385 |
+
Simulates missing records or empty results from data sources.
|
| 386 |
+
|
| 387 |
+
**Config:**
|
| 388 |
+
```json
|
| 389 |
+
{
|
| 390 |
+
"missingRecords": true, // Return empty results
|
| 391 |
+
"missingFields": ["field1"], // Remove specific fields (optional)
|
| 392 |
+
"throwError": true // Throw error vs return empty (default: true)
|
| 393 |
+
}
|
| 394 |
+
```
|
| 395 |
+
|
| 396 |
+
### 2. data_corruption
|
| 397 |
+
Corrupts fields in response data with null, wrong types, or invalid values.
|
| 398 |
+
|
| 399 |
+
**Config:**
|
| 400 |
+
```json
|
| 401 |
+
{
|
| 402 |
+
"corruptFields": ["id", "status"],
|
| 403 |
+
"corruptionType": "null" | "wrong_type" | "invalid_format" | "random_value"
|
| 404 |
+
}
|
| 405 |
+
```
|
| 406 |
+
|
| 407 |
+
### 3. stale_data
|
| 408 |
+
Returns outdated data to simulate caching issues or sync delays.
|
| 409 |
+
|
| 410 |
+
**Config:**
|
| 411 |
+
```json
|
| 412 |
+
{
|
| 413 |
+
"staleDataAge": 60 // Age in minutes
|
| 414 |
+
}
|
| 415 |
+
```
|
| 416 |
+
|
| 417 |
+
### 4. format_change
|
| 418 |
+
Simulates breaking schema changes in data structures.
|
| 419 |
+
|
| 420 |
+
**Config:**
|
| 421 |
+
```json
|
| 422 |
+
{
|
| 423 |
+
"schemaChanges": [
|
| 424 |
+
{
|
| 425 |
+
"field": "oldField",
|
| 426 |
+
"change": "rename",
|
| 427 |
+
"newName": "newField"
|
| 428 |
+
}
|
| 429 |
+
]
|
| 430 |
+
}
|
| 431 |
+
```
|
| 432 |
+
|
| 433 |
+
### 5. permission_denied
|
| 434 |
+
Simulates access control failures.
|
| 435 |
+
|
| 436 |
+
**Config:**
|
| 437 |
+
```json
|
| 438 |
+
{
|
| 439 |
+
"permissionError": "Access denied: insufficient permissions"
|
| 440 |
+
}
|
| 441 |
+
```
|
| 442 |
+
|
| 443 |
+
### 6. rate_limit
|
| 444 |
+
Simulates API rate limiting with delays.
|
| 445 |
+
|
| 446 |
+
**Config:**
|
| 447 |
+
```json
|
| 448 |
+
{
|
| 449 |
+
"rateLimitDelay": 2000, // Delay in ms
|
| 450 |
+
"rateLimitMessage": "Rate limit exceeded, please retry"
|
| 451 |
+
}
|
| 452 |
+
```
|
| 453 |
+
|
| 454 |
+
### 7. partial_data
|
| 455 |
+
Returns incomplete data sets.
|
| 456 |
+
|
| 457 |
+
**Config:**
|
| 458 |
+
```json
|
| 459 |
+
{
|
| 460 |
+
"partialResults": {
|
| 461 |
+
"percentage": 50, // Percentage of data to return (0-100)
|
| 462 |
+
"randomize": true // Random subset vs first N items
|
| 463 |
+
}
|
| 464 |
+
}
|
| 465 |
+
```
|
| 466 |
+
|
| 467 |
+
### 8. duplicate_data
|
| 468 |
+
Injects duplicate records in results.
|
| 469 |
+
|
| 470 |
+
**Config:**
|
| 471 |
+
```json
|
| 472 |
+
{
|
| 473 |
+
"duplicateCount": 2 // Number of duplicates to create
|
| 474 |
+
}
|
| 475 |
+
```
|
| 476 |
+
|
| 477 |
+
### 9. invalid_state
|
| 478 |
+
Returns records in invalid or conflicting states.
|
| 479 |
+
|
| 480 |
+
**Config:**
|
| 481 |
+
```json
|
| 482 |
+
{
|
| 483 |
+
"invalidStates": ["CANCELLED_BUT_ACTIVE", "SHIPPED_NO_TRACKING"]
|
| 484 |
+
}
|
| 485 |
+
```
|
| 486 |
+
|
| 487 |
+
### 10. dependency_failure
|
| 488 |
+
Simulates downstream service failures.
|
| 489 |
+
|
| 490 |
+
**Config:**
|
| 491 |
+
```json
|
| 492 |
+
{
|
| 493 |
+
"dependencyService": "inventory-service",
|
| 494 |
+
"cascadeFailure": true // Propagate failure to other steps
|
| 495 |
+
}
|
| 496 |
+
```
|
| 497 |
+
|
| 498 |
+
### 11. timing_issue
|
| 499 |
+
Introduces timing-related problems like race conditions or delays.
|
| 500 |
+
|
| 501 |
+
**Config:**
|
| 502 |
+
```json
|
| 503 |
+
{
|
| 504 |
+
"delay": 5000, // Delay in ms
|
| 505 |
+
"timeout": true // Simulate timeout
|
| 506 |
+
}
|
| 507 |
+
```
|
| 508 |
+
|
| 509 |
+
## Chaos Telemetry
|
| 510 |
+
|
| 511 |
+
When chaos is enabled, capability execution responses include detailed telemetry about which chaos scenarios were injected. See the [Capabilities API documentation](./capabilities-api.md#chaos-telemetry) for details.
|
| 512 |
+
|
| 513 |
+
## Environment Variables
|
| 514 |
+
|
| 515 |
+
- `CHAOS_ENABLED`: Enable/disable chaos injection globally (`"true"`/`"false"`)
|
| 516 |
+
- `CHAOS_PRESET`: Global chaos preset to load at startup (`"light"`, `"moderate"`, `"realistic"`, `"aggressive"`)
|
| 517 |
+
- `CHAOS_SEED`: Global seed for reproducible chaos (optional)
|
| 518 |
+
|
| 519 |
+
## Use Cases
|
| 520 |
+
|
| 521 |
+
### 1. Testing System Resilience
|
| 522 |
+
|
| 523 |
+
Enable chaos to test how your system handles various failure modes:
|
| 524 |
+
|
| 525 |
+
```bash
|
| 526 |
+
# Set aggressive chaos for stress testing
|
| 527 |
+
export CHAOS_ENABLED=true
|
| 528 |
+
export CHAOS_PRESET=aggressive
|
| 529 |
+
|
| 530 |
+
# Run tests and observe behavior
|
| 531 |
+
```
|
| 532 |
+
|
| 533 |
+
### 2. World-Specific Testing
|
| 534 |
+
|
| 535 |
+
Create worlds with different chaos levels for controlled testing:
|
| 536 |
+
|
| 537 |
+
```bash
|
| 538 |
+
# Create a chaos test world
|
| 539 |
+
WORLD_ID=$(curl -X POST http://localhost:4000/world \
|
| 540 |
+
-H "Content-Type: application/json" \
|
| 541 |
+
-d '{"name": "chaos-test"}' | jq -r '.worldId')
|
| 542 |
+
|
| 543 |
+
# Configure aggressive chaos for this world only
|
| 544 |
+
curl -X PUT "http://localhost:4000/world/$WORLD_ID/chaos" \
|
| 545 |
+
-H "Content-Type: application/json" \
|
| 546 |
+
-d @realistic-chaos.json
|
| 547 |
+
|
| 548 |
+
# Execute capabilities in this world - they will experience chaos
|
| 549 |
+
curl -X POST http://localhost:4000/capabilities/inventory-check/execute \
|
| 550 |
+
-H "Content-Type: application/json" \
|
| 551 |
+
-d "{\"worldId\": \"$WORLD_ID\", \"inputs\": {}}"
|
| 552 |
+
```
|
| 553 |
+
|
| 554 |
+
### 3. Reproducible Chaos Testing
|
| 555 |
+
|
| 556 |
+
Use seeds for deterministic chaos injection:
|
| 557 |
+
|
| 558 |
+
```bash
|
| 559 |
+
# Configure chaos with a seed
|
| 560 |
+
curl -X PUT "http://localhost:4000/world/$WORLD_ID/chaos" \
|
| 561 |
+
-H "Content-Type: application/json" \
|
| 562 |
+
-d '{
|
| 563 |
+
"enabled": true,
|
| 564 |
+
"probability": 0.5,
|
| 565 |
+
"seed": "test-run-1",
|
| 566 |
+
"scenarios": [...]
|
| 567 |
+
}'
|
| 568 |
+
|
| 569 |
+
# Run the same test multiple times - chaos will be identical each time
|
| 570 |
+
```
|
| 571 |
+
|
| 572 |
+
### 4. Gradual Chaos Introduction
|
| 573 |
+
|
| 574 |
+
Start with light chaos and gradually increase:
|
| 575 |
+
|
| 576 |
+
```bash
|
| 577 |
+
# Week 1: Light chaos
|
| 578 |
+
export CHAOS_PRESET=light
|
| 579 |
+
|
| 580 |
+
# Week 2: Moderate chaos
|
| 581 |
+
export CHAOS_PRESET=moderate
|
| 582 |
+
|
| 583 |
+
# Week 3: Realistic chaos
|
| 584 |
+
export CHAOS_PRESET=realistic
|
| 585 |
+
|
| 586 |
+
# Observe application behavior at each level
|
| 587 |
+
```
|
| 588 |
+
|
| 589 |
+
## Error Responses
|
| 590 |
+
|
| 591 |
+
### 400 Bad Request
|
| 592 |
+
|
| 593 |
+
```json
|
| 594 |
+
{
|
| 595 |
+
"success": false,
|
| 596 |
+
"error": "worldId is required"
|
| 597 |
+
}
|
| 598 |
+
```
|
| 599 |
+
|
| 600 |
+
### 404 Not Found
|
| 601 |
+
|
| 602 |
+
```json
|
| 603 |
+
{
|
| 604 |
+
"success": false,
|
| 605 |
+
"error": "Chaos preset not found: invalid-preset"
|
| 606 |
+
}
|
| 607 |
+
```
|
| 608 |
+
|
| 609 |
+
```json
|
| 610 |
+
{
|
| 611 |
+
"success": false,
|
| 612 |
+
"error": "World not found"
|
| 613 |
+
}
|
| 614 |
+
```
|
| 615 |
+
|
| 616 |
+
### 500 Internal Server Error
|
| 617 |
+
|
| 618 |
+
```json
|
| 619 |
+
{
|
| 620 |
+
"success": false,
|
| 621 |
+
"error": "Failed to update world chaos"
|
| 622 |
+
}
|
| 623 |
+
```
|
| 624 |
+
|
| 625 |
+
## Related APIs
|
| 626 |
+
|
| 627 |
+
- [Capabilities API](./capabilities-api.md) - Execute capabilities and view chaos telemetry
|
| 628 |
+
- [World API](./world-api.md) - Manage worlds and their configurations
|
packages/controlmart/docs/api/persona-api.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Persona API Documentation
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
The Persona API provides endpoints for discovering personas (user roles) and their associated capabilities in the Morpheus platform. Personas represent different types of users in a supply chain environment (e.g., warehouse workers, store managers, logistics coordinators).
|
| 6 |
+
|
| 7 |
+
## Base URL
|
| 8 |
+
|
| 9 |
+
```
|
| 10 |
+
http://localhost:4000
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
## Endpoints
|
| 14 |
+
|
| 15 |
+
### 1. List All Personas
|
| 16 |
+
|
| 17 |
+
**GET** `/personas`
|
| 18 |
+
|
| 19 |
+
Returns all available personas with optional filtering by role, department, access level, or tags.
|
| 20 |
+
|
| 21 |
+
**Query Parameters:**
|
| 22 |
+
- `role` (string, optional): Filter by role (e.g., "operations", "management", "specialist")
|
| 23 |
+
- `department` (string, optional): Filter by department (e.g., "warehouse", "store", "logistics")
|
| 24 |
+
- `accessLevel` (string, optional): Filter by access level (e.g., "operational", "supervisory", "executive")
|
| 25 |
+
- `tags` (string, optional): Comma-separated list of tags to filter by
|
| 26 |
+
|
| 27 |
+
**Example Requests:**
|
| 28 |
+
|
| 29 |
+
```bash
|
| 30 |
+
# Get all personas
|
| 31 |
+
curl http://localhost:4000/personas
|
| 32 |
+
|
| 33 |
+
# Filter by role
|
| 34 |
+
curl "http://localhost:4000/personas?role=operations"
|
| 35 |
+
|
| 36 |
+
# Filter by department
|
| 37 |
+
curl "http://localhost:4000/personas?department=warehouse"
|
| 38 |
+
|
| 39 |
+
# Filter by access level
|
| 40 |
+
curl "http://localhost:4000/personas?accessLevel=operational"
|
| 41 |
+
|
| 42 |
+
# Filter by multiple tags
|
| 43 |
+
curl "http://localhost:4000/personas?tags=frontline,operational"
|
| 44 |
+
|
| 45 |
+
# Combined filters
|
| 46 |
+
curl "http://localhost:4000/personas?role=operations&department=warehouse"
|
| 47 |
+
```
|
| 48 |
+
|
| 49 |
+
**Response:**
|
| 50 |
+
|
| 51 |
+
```json
|
| 52 |
+
{
|
| 53 |
+
"count": 5,
|
| 54 |
+
"personas": [
|
| 55 |
+
{
|
| 56 |
+
"id": "warehouse-worker",
|
| 57 |
+
"name": "Warehouse Worker",
|
| 58 |
+
"description": "Frontline warehouse operations staff",
|
| 59 |
+
"role": "operations",
|
| 60 |
+
"department": "warehouse",
|
| 61 |
+
"accessLevel": "operational",
|
| 62 |
+
"capabilityIds": [
|
| 63 |
+
"inventory-check",
|
| 64 |
+
"shipment-tracking",
|
| 65 |
+
"equipment-availability"
|
| 66 |
+
],
|
| 67 |
+
"tags": ["frontline", "operational", "warehouse"]
|
| 68 |
+
},
|
| 69 |
+
{
|
| 70 |
+
"id": "store-manager",
|
| 71 |
+
"name": "Store Manager",
|
| 72 |
+
"description": "Retail store manager overseeing operations",
|
| 73 |
+
"role": "management",
|
| 74 |
+
"department": "store",
|
| 75 |
+
"accessLevel": "supervisory",
|
| 76 |
+
"capabilityIds": [
|
| 77 |
+
"inventory-check",
|
| 78 |
+
"order-fulfillment-status"
|
| 79 |
+
],
|
| 80 |
+
"tags": ["management", "retail", "supervisory"]
|
| 81 |
+
}
|
| 82 |
+
]
|
| 83 |
+
}
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
### 2. Get Persona by ID
|
| 87 |
+
|
| 88 |
+
**GET** `/personas/:personaId`
|
| 89 |
+
|
| 90 |
+
Returns a single persona by its ID.
|
| 91 |
+
|
| 92 |
+
**Path Parameters:**
|
| 93 |
+
- `personaId` (string, required): Unique identifier for the persona
|
| 94 |
+
|
| 95 |
+
**Example:**
|
| 96 |
+
|
| 97 |
+
```bash
|
| 98 |
+
curl http://localhost:4000/personas/warehouse-worker
|
| 99 |
+
```
|
| 100 |
+
|
| 101 |
+
**Response:**
|
| 102 |
+
|
| 103 |
+
```json
|
| 104 |
+
{
|
| 105 |
+
"id": "warehouse-worker",
|
| 106 |
+
"name": "Warehouse Worker",
|
| 107 |
+
"description": "Frontline warehouse operations staff performing daily tasks like receiving, putaway, picking, and shipping",
|
| 108 |
+
"role": "operations",
|
| 109 |
+
"department": "warehouse",
|
| 110 |
+
"accessLevel": "operational",
|
| 111 |
+
"capabilityIds": [
|
| 112 |
+
"inventory-check",
|
| 113 |
+
"shipment-tracking",
|
| 114 |
+
"equipment-availability",
|
| 115 |
+
"dock-appointment-check"
|
| 116 |
+
],
|
| 117 |
+
"tags": ["frontline", "operational", "warehouse", "physical-work"]
|
| 118 |
+
}
|
| 119 |
+
```
|
| 120 |
+
|
| 121 |
+
### 3. Get Capabilities for a Persona
|
| 122 |
+
|
| 123 |
+
**GET** `/personas/:personaId/capabilities`
|
| 124 |
+
|
| 125 |
+
Returns all capabilities associated with a specific persona, including full capability details.
|
| 126 |
+
|
| 127 |
+
**Path Parameters:**
|
| 128 |
+
- `personaId` (string, required): Unique identifier for the persona
|
| 129 |
+
|
| 130 |
+
**Example:**
|
| 131 |
+
|
| 132 |
+
```bash
|
| 133 |
+
curl http://localhost:4000/personas/warehouse-worker/capabilities
|
| 134 |
+
```
|
| 135 |
+
|
| 136 |
+
**Response:**
|
| 137 |
+
|
| 138 |
+
```json
|
| 139 |
+
{
|
| 140 |
+
"personaId": "warehouse-worker",
|
| 141 |
+
"personaName": "Warehouse Worker",
|
| 142 |
+
"capabilityCount": 4,
|
| 143 |
+
"capabilities": [
|
| 144 |
+
{
|
| 145 |
+
"id": "inventory-check",
|
| 146 |
+
"name": "Inventory Check",
|
| 147 |
+
"description": "Check current inventory levels for one or more SKUs",
|
| 148 |
+
"tags": {
|
| 149 |
+
"domain": ["inventory", "warehousing"],
|
| 150 |
+
"complexity": "simple",
|
| 151 |
+
"services": ["wms"],
|
| 152 |
+
"personas": ["warehouse-worker", "store-manager"],
|
| 153 |
+
"patterns": ["sequential"]
|
| 154 |
+
},
|
| 155 |
+
"odId": "inventory-check-standard-v1",
|
| 156 |
+
"version": "1.0.0",
|
| 157 |
+
"metadata": {
|
| 158 |
+
"author": "morpheus-team",
|
| 159 |
+
"estimatedDuration": 2000
|
| 160 |
+
}
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"id": "shipment-tracking",
|
| 164 |
+
"name": "Shipment Tracking",
|
| 165 |
+
"description": "Track a shipment and retrieve its status and location",
|
| 166 |
+
"tags": {
|
| 167 |
+
"domain": ["transportation", "logistics"],
|
| 168 |
+
"complexity": "simple",
|
| 169 |
+
"services": ["tms"],
|
| 170 |
+
"personas": ["warehouse-worker", "logistics-coordinator"],
|
| 171 |
+
"patterns": ["sequential"]
|
| 172 |
+
},
|
| 173 |
+
"odId": "shipment-tracking-standard-v1",
|
| 174 |
+
"version": "1.0.0"
|
| 175 |
+
}
|
| 176 |
+
]
|
| 177 |
+
}
|
| 178 |
+
```
|
| 179 |
+
|
| 180 |
+
## Persona Schema
|
| 181 |
+
|
| 182 |
+
### Persona Object
|
| 183 |
+
|
| 184 |
+
```typescript
|
| 185 |
+
{
|
| 186 |
+
id: string; // Unique identifier (e.g., "warehouse-worker")
|
| 187 |
+
name: string; // Display name (e.g., "Warehouse Worker")
|
| 188 |
+
description: string; // Detailed description of the persona
|
| 189 |
+
role: string; // Role category (operations, management, specialist)
|
| 190 |
+
department: string; // Department (warehouse, store, logistics, etc.)
|
| 191 |
+
accessLevel: string; // Access level (operational, supervisory, executive)
|
| 192 |
+
capabilityIds: string[]; // Array of capability IDs this persona can execute
|
| 193 |
+
tags: string[]; // Additional tags for filtering and categorization
|
| 194 |
+
}
|
| 195 |
+
```
|
| 196 |
+
|
| 197 |
+
## Use Cases
|
| 198 |
+
|
| 199 |
+
### 1. Building Role-Based UIs
|
| 200 |
+
|
| 201 |
+
Use the persona API to build role-specific interfaces that only show capabilities relevant to the current user's role:
|
| 202 |
+
|
| 203 |
+
```bash
|
| 204 |
+
# Get all capabilities for warehouse workers
|
| 205 |
+
curl http://localhost:4000/personas/warehouse-worker/capabilities
|
| 206 |
+
|
| 207 |
+
# Use the response to build a UI that shows only these capabilities
|
| 208 |
+
```
|
| 209 |
+
|
| 210 |
+
### 2. Capability Discovery
|
| 211 |
+
|
| 212 |
+
Find which personas can perform a specific capability:
|
| 213 |
+
|
| 214 |
+
```bash
|
| 215 |
+
# Get all personas
|
| 216 |
+
curl http://localhost:4000/personas
|
| 217 |
+
|
| 218 |
+
# Filter the response to find which personas include a specific capabilityId
|
| 219 |
+
```
|
| 220 |
+
|
| 221 |
+
### 3. Access Control
|
| 222 |
+
|
| 223 |
+
Validate whether a persona should have access to a capability:
|
| 224 |
+
|
| 225 |
+
```bash
|
| 226 |
+
# Get persona details
|
| 227 |
+
curl http://localhost:4000/personas/warehouse-worker
|
| 228 |
+
|
| 229 |
+
# Check if the desired capabilityId is in the persona's capabilityIds array
|
| 230 |
+
```
|
| 231 |
+
|
| 232 |
+
## Common Personas
|
| 233 |
+
|
| 234 |
+
The Morpheus platform includes these standard personas:
|
| 235 |
+
|
| 236 |
+
| Persona ID | Name | Department | Role | Typical Capabilities |
|
| 237 |
+
|------------|------|------------|------|---------------------|
|
| 238 |
+
| `warehouse-worker` | Warehouse Worker | Warehouse | Operations | Inventory check, shipment tracking, equipment availability |
|
| 239 |
+
| `store-manager` | Store Manager | Store | Management | Inventory check, order fulfillment status |
|
| 240 |
+
| `logistics-coordinator` | Logistics Coordinator | Logistics | Specialist | Shipment tracking, route optimization, carrier rate lookup |
|
| 241 |
+
| `supply-chain-manager` | Supply Chain Manager | Supply Chain | Management | Advanced analytics, network optimization |
|
| 242 |
+
| `inventory-analyst` | Inventory Analyst | Inventory | Specialist | Inventory analytics, forecasting, replenishment |
|
| 243 |
+
|
| 244 |
+
## Error Responses
|
| 245 |
+
|
| 246 |
+
### 404 Not Found
|
| 247 |
+
|
| 248 |
+
```json
|
| 249 |
+
{
|
| 250 |
+
"error": "Persona 'invalid-persona' not found"
|
| 251 |
+
}
|
| 252 |
+
```
|
| 253 |
+
|
| 254 |
+
### 500 Internal Server Error
|
| 255 |
+
|
| 256 |
+
```json
|
| 257 |
+
{
|
| 258 |
+
"error": "Error message describing what went wrong"
|
| 259 |
+
}
|
| 260 |
+
```
|
| 261 |
+
|
| 262 |
+
## Related APIs
|
| 263 |
+
|
| 264 |
+
- [Capabilities API](./capabilities-api.md) - Execute and discover capabilities
|
| 265 |
+
- [World API](./world-api.md) - Manage world contexts for capability execution
|
packages/controlmart/driver-service-mesh.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import { ServiceMesh } from './src/utils/service-mesh.util';
|
| 3 |
+
|
| 4 |
+
console.log('--- Service Mesh Driver & Test ---');
|
| 5 |
+
|
| 6 |
+
// 1. Inspect Registry Structure
|
| 7 |
+
const registry = ServiceMesh.getRegistry();
|
| 8 |
+
const registeredServices = Object.keys(registry);
|
| 9 |
+
console.log(`[INFO] Registered Services (${registeredServices.length}):`, registeredServices.join(', '));
|
| 10 |
+
|
| 11 |
+
// 2. Check for System Service Docs
|
| 12 |
+
console.log('\n--- Checking System Docs ---');
|
| 13 |
+
const systemEndpoints = ServiceMesh.findEndpoints('system');
|
| 14 |
+
console.log(`[INFO] Found ${systemEndpoints.length} System endpoints.`);
|
| 15 |
+
|
| 16 |
+
if (systemEndpoints.length > 0) {
|
| 17 |
+
systemEndpoints.forEach(ep => console.log(` -> [${ep.method.toUpperCase()}] ${ep.path}`));
|
| 18 |
+
console.log('\n--- Sample formatted doc for /docs/mesh ---');
|
| 19 |
+
const meshEp = systemEndpoints.find(ep => ep.path === '/docs/mesh');
|
| 20 |
+
if (meshEp) {
|
| 21 |
+
console.log(ServiceMesh.getFormattedEndpointDocs(meshEp));
|
| 22 |
+
}
|
| 23 |
+
} else {
|
| 24 |
+
console.error("[FAIL] No System endpoints found. Check docs.app.ts parsing.");
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
console.log('\n--- Driver Complete ---');
|
packages/controlmart/eslint.config.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tsParser from "@typescript-eslint/parser";
|
| 2 |
+
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
| 3 |
+
import importPlugin from "eslint-plugin-import";
|
| 4 |
+
import unusedImports from "eslint-plugin-unused-imports";
|
| 5 |
+
import prettierConfig from "eslint-config-prettier";
|
| 6 |
+
|
| 7 |
+
export default [
|
| 8 |
+
prettierConfig,
|
| 9 |
+
|
| 10 |
+
{
|
| 11 |
+
files: ["**/*.ts"],
|
| 12 |
+
ignores: ["dist", "build", "node_modules"],
|
| 13 |
+
|
| 14 |
+
languageOptions: {
|
| 15 |
+
parser: tsParser,
|
| 16 |
+
parserOptions: {
|
| 17 |
+
project: "./tsconfig.json",
|
| 18 |
+
tsconfigRootDir: process.cwd(),
|
| 19 |
+
},
|
| 20 |
+
sourceType: "module",
|
| 21 |
+
ecmaVersion: "latest",
|
| 22 |
+
},
|
| 23 |
+
|
| 24 |
+
plugins: {
|
| 25 |
+
"@typescript-eslint": tsPlugin,
|
| 26 |
+
import: importPlugin,
|
| 27 |
+
"unused-imports": unusedImports,
|
| 28 |
+
},
|
| 29 |
+
|
| 30 |
+
rules: {
|
| 31 |
+
"unused-imports/no-unused-imports": "error",
|
| 32 |
+
|
| 33 |
+
"unused-imports/no-unused-vars": [
|
| 34 |
+
"warn",
|
| 35 |
+
{
|
| 36 |
+
vars: "all",
|
| 37 |
+
varsIgnorePattern: "^_",
|
| 38 |
+
args: "after-used",
|
| 39 |
+
argsIgnorePattern: "^_",
|
| 40 |
+
},
|
| 41 |
+
],
|
| 42 |
+
|
| 43 |
+
"@typescript-eslint/no-unused-vars": "off",
|
| 44 |
+
|
| 45 |
+
"import/order": [
|
| 46 |
+
"warn",
|
| 47 |
+
{
|
| 48 |
+
groups: ["builtin", "external", "internal", ["parent", "sibling"], "index"],
|
| 49 |
+
"newlines-between": "always",
|
| 50 |
+
},
|
| 51 |
+
],
|
| 52 |
+
},
|
| 53 |
+
},
|
| 54 |
+
];
|
packages/controlmart/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { existsSync } from "fs";
|
| 2 |
+
import path from "path";
|
| 3 |
+
|
| 4 |
+
// Development Entry Point
|
| 5 |
+
// This bypasses the Setup UI and directly launches the main application.
|
| 6 |
+
// It assumes the developer has a .env file or environment variables set.
|
| 7 |
+
|
| 8 |
+
(async () => {
|
| 9 |
+
const envPath = path.join(process.cwd(), ".env");
|
| 10 |
+
|
| 11 |
+
if (!existsSync(envPath)) {
|
| 12 |
+
console.warn(`[dev] β οΈ No .env file found at ${envPath}. Application may fail if variables are missing.`);
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
// Import the main application logic (migrations, seeding, server start)
|
| 16 |
+
await import("./main");
|
| 17 |
+
})();
|
packages/controlmart/main.ts
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createApplication } from "./src/application/application.app";
|
| 2 |
+
import { World } from "./src/models/world.model";
|
| 3 |
+
import { WorldLog } from "./src/models/logs.model";
|
| 4 |
+
import {
|
| 5 |
+
createAppLogger,
|
| 6 |
+
createHttpLogger,
|
| 7 |
+
} from "./src/utils/logger.util";
|
| 8 |
+
import { getErrorMessage } from "./src/utils/error.util";
|
| 9 |
+
// Research branch imports
|
| 10 |
+
import { loadEnv } from "./src/utils/env.util";
|
| 11 |
+
import { registerTicketingJob } from "./src/jobs/ticketing.job";
|
| 12 |
+
import { registerDeleteLogQueueJob } from "./src/jobs/delete-logqueue.job";
|
| 13 |
+
import { startScheduler, stopScheduler } from "./src/services/scheduler.service";
|
| 14 |
+
import { initializeODScheduling } from "./src/operational-descriptor/schedule.od";
|
| 15 |
+
import { createCollectionsIfNotExist, connectMongo, syncModelIndexes } from "./src/services/mongo.service";
|
| 16 |
+
import { auditLogger } from "./src/services/audit-logger.service";
|
| 17 |
+
// od-arch branch imports
|
| 18 |
+
// import { seedBusinessRules } from "./src/business-rules/seed-rules"; // Temporarily disabled
|
| 19 |
+
import { initializeODRegistry } from "./src/ods/index";
|
| 20 |
+
import { WorldRepository } from "./src/repository";
|
| 21 |
+
import { ChaosConfigRegistry } from "./src/services/chaos-config.registry";
|
| 22 |
+
import { capabilityCatalog } from './src/services/capability-catalog.service';
|
| 23 |
+
import { personaRegistry } from './src/services/persona-registry.service';
|
| 24 |
+
import { autoSeedIfEmpty } from './src/services/auto-seed.service';
|
| 25 |
+
|
| 26 |
+
const envValues = loadEnv();
|
| 27 |
+
|
| 28 |
+
// Parse CLI arguments
|
| 29 |
+
const forceSeed = process.argv.includes('--force-seed');
|
| 30 |
+
|
| 31 |
+
export const logger = createAppLogger({});
|
| 32 |
+
|
| 33 |
+
// Timeout wrapper for startup operations to prevent indefinite hangs
|
| 34 |
+
const withTimeout = <T>(
|
| 35 |
+
promise: Promise<T>,
|
| 36 |
+
ms: number,
|
| 37 |
+
operation: string
|
| 38 |
+
): Promise<T> => {
|
| 39 |
+
return Promise.race([
|
| 40 |
+
promise,
|
| 41 |
+
new Promise<T>((_, reject) =>
|
| 42 |
+
setTimeout(
|
| 43 |
+
() => reject(new Error(`${operation} timed out after ${ms}ms`)),
|
| 44 |
+
ms
|
| 45 |
+
)
|
| 46 |
+
),
|
| 47 |
+
]);
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
export const httpLogger = createHttpLogger(logger);
|
| 52 |
+
export const mongoLogger = auditLogger;
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
try {
|
| 56 |
+
// 1. Validate Critical Configuration
|
| 57 |
+
if (!envValues.MONGO_URI || !envValues.OPENAI_API_KEY) {
|
| 58 |
+
logger.warn("[startup] Missing critical configuration (MONGO_URI or OPENAI_API_KEY). Launching Setup Mode...");
|
| 59 |
+
const { startSetup } = await import("./src/application/setup.app");
|
| 60 |
+
await startSetup();
|
| 61 |
+
// Keep process alive for setup server
|
| 62 |
+
await new Promise(() => { });
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// 2. Run Boot Check (Database Connection)
|
| 66 |
+
try {
|
| 67 |
+
await withTimeout(
|
| 68 |
+
connectMongo({
|
| 69 |
+
uri: envValues.MONGO_URI,
|
| 70 |
+
dbName: envValues.DB_NAME,
|
| 71 |
+
log: true,
|
| 72 |
+
}),
|
| 73 |
+
30000,
|
| 74 |
+
'connectMongo'
|
| 75 |
+
);
|
| 76 |
+
} catch (err) {
|
| 77 |
+
logger.error({ error: getErrorMessage(err) }, "[startup] Database connection failed. Launching Setup Mode...");
|
| 78 |
+
const { startSetup } = await import("./src/application/setup.app");
|
| 79 |
+
await startSetup();
|
| 80 |
+
// Keep process alive for setup server
|
| 81 |
+
await new Promise(() => { });
|
| 82 |
+
}
|
| 83 |
+
await withTimeout(
|
| 84 |
+
createCollectionsIfNotExist({
|
| 85 |
+
models: [World, WorldLog],
|
| 86 |
+
collectionNames: ["schedules"],
|
| 87 |
+
log: true,
|
| 88 |
+
}),
|
| 89 |
+
30000,
|
| 90 |
+
'createCollectionsIfNotExist'
|
| 91 |
+
);
|
| 92 |
+
|
| 93 |
+
// Seed business rules on startup
|
| 94 |
+
// await seedBusinessRules();
|
| 95 |
+
|
| 96 |
+
await withTimeout(startScheduler(), 30000, 'startScheduler');
|
| 97 |
+
initializeODScheduling();
|
| 98 |
+
|
| 99 |
+
// Register Ticketing Job
|
| 100 |
+
await withTimeout(registerTicketingJob(), 30000, 'registerTicketingJob');
|
| 101 |
+
|
| 102 |
+
// Register Log Cleanup Job
|
| 103 |
+
await withTimeout(registerDeleteLogQueueJob(), 30000, 'registerDeleteLogQueueJob');
|
| 104 |
+
|
| 105 |
+
// Initialize OD Registry with all available OD builders
|
| 106 |
+
initializeODRegistry();
|
| 107 |
+
logger.info('OD Registry initialized');
|
| 108 |
+
|
| 109 |
+
// Auto-seed database if collections are empty (or force mode)
|
| 110 |
+
if (forceSeed) {
|
| 111 |
+
logger.info('[startup] Force seed mode enabled via --force-seed');
|
| 112 |
+
}
|
| 113 |
+
const seedResult = await withTimeout(
|
| 114 |
+
autoSeedIfEmpty(logger, { force: forceSeed }),
|
| 115 |
+
120000,
|
| 116 |
+
'autoSeedIfEmpty'
|
| 117 |
+
);
|
| 118 |
+
if (seedResult.capabilities.seeded || seedResult.personas.seeded || seedResult.knowledgeGraph.seeded) {
|
| 119 |
+
logger.info({ seedResult }, 'Auto-seeding completed');
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// Initialize capability and persona services from MongoDB
|
| 123 |
+
const initializedServices: string[] = [];
|
| 124 |
+
|
| 125 |
+
// 1. Initialize Capability Catalog
|
| 126 |
+
try {
|
| 127 |
+
await withTimeout(capabilityCatalog.initialize(), 60000, 'capabilityCatalog.initialize');
|
| 128 |
+
initializedServices.push(`CapabilityCatalog (${capabilityCatalog.count()} capabilities)`);
|
| 129 |
+
} catch (error) {
|
| 130 |
+
const errorMsg = getErrorMessage(error);
|
| 131 |
+
if (errorMsg.includes('CapabilityCatalog not initialized')) {
|
| 132 |
+
logger.warn('Capability catalog database is empty. Run migration script: bun run scripts/migrate-capabilities.ts');
|
| 133 |
+
} else {
|
| 134 |
+
logger.error({ error: errorMsg }, 'Failed to initialize capability catalog');
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
// 2. Initialize Persona Registry
|
| 139 |
+
try {
|
| 140 |
+
await withTimeout(personaRegistry.initialize(), 60000, 'personaRegistry.initialize');
|
| 141 |
+
initializedServices.push(`PersonaRegistry (${personaRegistry.getCount()} personas)`);
|
| 142 |
+
} catch (error) {
|
| 143 |
+
const errorMsg = getErrorMessage(error);
|
| 144 |
+
if (errorMsg.includes('PersonaRegistry not initialized')) {
|
| 145 |
+
logger.warn('Persona registry database is empty. Run migration script: bun run scripts/migrate-personas.ts');
|
| 146 |
+
} else {
|
| 147 |
+
logger.error({ error: errorMsg }, 'Failed to initialize persona registry');
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
// 3. Initialize Knowledge Graph
|
| 152 |
+
try {
|
| 153 |
+
const { knowledgeGraph } = await import('./src/services/knowledge-graph.service');
|
| 154 |
+
await withTimeout(knowledgeGraph.initialize(), 60000, 'knowledgeGraph.initialize');
|
| 155 |
+
initializedServices.push('KnowledgeGraph');
|
| 156 |
+
} catch (error) {
|
| 157 |
+
const errorMsg = getErrorMessage(error);
|
| 158 |
+
if (errorMsg.includes('Knowledge graph database is empty')) {
|
| 159 |
+
logger.warn('Knowledge graph database is empty. Run migration script: bun run scripts/migrate-knowledge-graph.ts');
|
| 160 |
+
} else {
|
| 161 |
+
logger.error({ error: errorMsg }, 'Failed to initialize knowledge graph');
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
// Log summary of initialized services
|
| 166 |
+
if (initializedServices.length > 0) {
|
| 167 |
+
logger.info({ services: initializedServices }, 'Initialized services');
|
| 168 |
+
} else {
|
| 169 |
+
logger.warn('No services initialized - database appears empty. Application will start but some features may be unavailable.');
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// Load persisted world chaos configurations into registry
|
| 173 |
+
// Load persisted world chaos configurations into registry
|
| 174 |
+
try {
|
| 175 |
+
const worldsResult = await withTimeout(
|
| 176 |
+
WorldRepository.getAllWorlds(),
|
| 177 |
+
60000,
|
| 178 |
+
'WorldRepository.getAllWorlds'
|
| 179 |
+
);
|
| 180 |
+
// Handle both cursor pagination (items) and offset pagination (data) return types
|
| 181 |
+
const worldsList = 'items' in worldsResult ? worldsResult.items : worldsResult.data;
|
| 182 |
+
let chaosCount = 0;
|
| 183 |
+
for (const world of worldsList) {
|
| 184 |
+
if (world.chaos) {
|
| 185 |
+
const worldId = (world as any)._id?.toString() || '';
|
| 186 |
+
if (worldId) {
|
| 187 |
+
ChaosConfigRegistry.setWorldChaosConfiguration(worldId, world.chaos);
|
| 188 |
+
chaosCount++;
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
logger.info(
|
| 193 |
+
{ count: chaosCount },
|
| 194 |
+
'Loaded world chaos configurations'
|
| 195 |
+
);
|
| 196 |
+
} catch (error) {
|
| 197 |
+
logger.error({ error: getErrorMessage(error) }, 'Failed to load chaos configs');
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
createApplication({
|
| 201 |
+
port: envValues.PORT,
|
| 202 |
+
host: process.env.HOST,
|
| 203 |
+
env: envValues.NODE_ENV,
|
| 204 |
+
logger,
|
| 205 |
+
httpLogger,
|
| 206 |
+
});
|
| 207 |
+
|
| 208 |
+
// Open Browser
|
| 209 |
+
// Defaults to opening unless disabled via flag or env var
|
| 210 |
+
const noBrowserFlag = process.argv.includes("--no-browser");
|
| 211 |
+
const noBrowserEnv = process.env.NO_BROWSER === "true";
|
| 212 |
+
|
| 213 |
+
if (!noBrowserFlag && !noBrowserEnv) {
|
| 214 |
+
logger.info(`[app] Opening browser at http://localhost:${envValues.PORT}/admin`);
|
| 215 |
+
Bun.spawn(["open", `http://localhost:${envValues.PORT}/admin`]);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
syncModelIndexes({ log: true })
|
| 220 |
+
.then(() => logger.info('Index sync completed successfully'))
|
| 221 |
+
.catch((err) => logger.error({ error: getErrorMessage(err) }, 'Index sync failed'));
|
| 222 |
+
|
| 223 |
+
process.on("SIGTERM", async () => {
|
| 224 |
+
logger.info("SIGTERM received, shutting down gracefully");
|
| 225 |
+
await stopScheduler();
|
| 226 |
+
process.exit(0);
|
| 227 |
+
});
|
| 228 |
+
|
| 229 |
+
process.on("SIGINT", async () => {
|
| 230 |
+
logger.info("SIGINT received, shutting down gracefully");
|
| 231 |
+
await stopScheduler();
|
| 232 |
+
process.exit(0);
|
| 233 |
+
});
|
| 234 |
+
} catch (err) {
|
| 235 |
+
logger.error(
|
| 236 |
+
{
|
| 237 |
+
error: getErrorMessage(err),
|
| 238 |
+
},
|
| 239 |
+
"[app] Application failed to start:",
|
| 240 |
+
);
|
| 241 |
+
process.exit(1);
|
| 242 |
+
}
|
packages/controlmart/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "controlmart",
|
| 3 |
+
"module": "index.ts",
|
| 4 |
+
"type": "module",
|
| 5 |
+
"private": true,
|
| 6 |
+
"scripts": {
|
| 7 |
+
"start": "bun run src/application/bootcheck.app.ts && bun run index.ts",
|
| 8 |
+
"run:local": "bun run build:ui && bun run dev",
|
| 9 |
+
"run:hf": "bun run start --no-browser",
|
| 10 |
+
"validate:annotations": "bun run src/scripts/validate-tool-annotations.ts",
|
| 11 |
+
"prebuild": "bun run validate:annotations",
|
| 12 |
+
"build": "tsc -p tsconfig.json ",
|
| 13 |
+
"dev": "bun run src/application/bootcheck.app.ts && bun run --watch index.ts",
|
| 14 |
+
"generate": "bun run index.ts",
|
| 15 |
+
"seed-dev": "bun run scripts/seed-dev-data.ts",
|
| 16 |
+
"lint": "bunx eslint . --ext .ts",
|
| 17 |
+
"lint:fix": "bunx eslint . --ext .ts --fix",
|
| 18 |
+
"fmt:fix": "bunx prettier --write .",
|
| 19 |
+
"fmt": "bunx prettier --check .",
|
| 20 |
+
"build:ui": "cd ui && bun install && bun run build",
|
| 21 |
+
"dev:ui": "cd ui && bun run dev",
|
| 22 |
+
"dev:full": "bun run build:ui && bun run dev --no-browser",
|
| 23 |
+
"build:binary": "bun build ./bootstrap.ts --compile --outfile morpheus-server",
|
| 24 |
+
"build:app": "bun run scripts/build-macos-app.ts"
|
| 25 |
+
},
|
| 26 |
+
"devDependencies": {
|
| 27 |
+
"@types/bun": "latest",
|
| 28 |
+
"@types/compression": "^1.8.1",
|
| 29 |
+
"@types/cors": "^2.8.19",
|
| 30 |
+
"@types/graphlib": "^2.1.12",
|
| 31 |
+
"@types/morgan": "^1.9.10",
|
| 32 |
+
"@types/seedrandom": "^3.0.8",
|
| 33 |
+
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
| 34 |
+
"@typescript-eslint/parser": "^8.48.0",
|
| 35 |
+
"eslint": "^9.39.1",
|
| 36 |
+
"eslint-config-prettier": "^10.1.8",
|
| 37 |
+
"eslint-plugin-import": "^2.32.0",
|
| 38 |
+
"eslint-plugin-unused-imports": "^4.3.0",
|
| 39 |
+
"prettier": "^3.6.2"
|
| 40 |
+
},
|
| 41 |
+
"peerDependencies": {
|
| 42 |
+
"typescript": "^5"
|
| 43 |
+
},
|
| 44 |
+
"dependencies": {
|
| 45 |
+
"@faker-js/faker": "^10.0.0",
|
| 46 |
+
"@hokify/agenda": "^6.3.0",
|
| 47 |
+
"@scalar/express-api-reference": "^0.8.22",
|
| 48 |
+
"@types/express": "^5.0.3",
|
| 49 |
+
"@types/jmespath": "^0.15.2",
|
| 50 |
+
"@types/swagger-jsdoc": "^6.0.4",
|
| 51 |
+
"@types/swagger-ui-express": "^4.1.8",
|
| 52 |
+
"ajv": "^8.17.1",
|
| 53 |
+
"compression": "^1.8.1",
|
| 54 |
+
"cors": "^2.8.5",
|
| 55 |
+
"dotenv": "^17.2.3",
|
| 56 |
+
"express": "^5.1.0",
|
| 57 |
+
"graphlib": "^2.1.8",
|
| 58 |
+
"helmet": "^8.1.0",
|
| 59 |
+
"jmespath": "^0.16.0",
|
| 60 |
+
"mongoose": "^8.19.0",
|
| 61 |
+
"morgan": "^1.10.1",
|
| 62 |
+
"openai": "^6.10.0",
|
| 63 |
+
"pino": "^10.0.0",
|
| 64 |
+
"pino-http": "^11.0.0",
|
| 65 |
+
"pino-pretty": "^13.1.1",
|
| 66 |
+
"seedrandom": "^3.0.5",
|
| 67 |
+
"slugify": "^1.6.6",
|
| 68 |
+
"swagger-jsdoc": "^6.2.8",
|
| 69 |
+
"swagger-ui-express": "^5.0.1",
|
| 70 |
+
"uuid": "^13.0.0",
|
| 71 |
+
"zod": "^4.1.11"
|
| 72 |
+
}
|
| 73 |
+
}
|
packages/controlmart/scripts/build-macos-app.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { mkdirSync, chmodSync } from "node:fs";
|
| 2 |
+
import { $ } from "bun";
|
| 3 |
+
|
| 4 |
+
const APP_NAME = "Skyfall - Morpheus";
|
| 5 |
+
const BUILD_DIR = "build-dist";
|
| 6 |
+
const APP_BUNDLE = `${BUILD_DIR}/${APP_NAME}.app`;
|
| 7 |
+
const CONTENTS_DIR = `${APP_BUNDLE}/Contents`;
|
| 8 |
+
const MACOS_DIR = `${CONTENTS_DIR}/MacOS`;
|
| 9 |
+
const RESOURCES_DIR = `${CONTENTS_DIR}/Resources`;
|
| 10 |
+
|
| 11 |
+
console.log("Cleaning build directory...");
|
| 12 |
+
await $`rm -rf ${BUILD_DIR}`;
|
| 13 |
+
|
| 14 |
+
console.log("Building binary...");
|
| 15 |
+
try {
|
| 16 |
+
// Build the standalone executable from the bootstrap script
|
| 17 |
+
await $`bun build ./bootstrap.ts --compile --outfile morpheus-server`;
|
| 18 |
+
} catch (e) {
|
| 19 |
+
console.error("Build failed:", e);
|
| 20 |
+
process.exit(1);
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
console.log("Creating App Bundle structure...");
|
| 24 |
+
// Create directories
|
| 25 |
+
mkdirSync(MACOS_DIR, { recursive: true });
|
| 26 |
+
mkdirSync(RESOURCES_DIR, { recursive: true });
|
| 27 |
+
|
| 28 |
+
console.log("Moving binary...");
|
| 29 |
+
// Move the built binary to the App Bundle
|
| 30 |
+
// Move the built binary to the App Bundle
|
| 31 |
+
await $`mv morpheus-server ${MACOS_DIR}/`;
|
| 32 |
+
|
| 33 |
+
console.log("Copying UI assets...");
|
| 34 |
+
// Copy dist/ui to Contents/MacOS/ui so the binary encounters it at ./ui
|
| 35 |
+
try {
|
| 36 |
+
const uiSource = "dist/ui";
|
| 37 |
+
if (Bun.file(uiSource).size > 0 || (await $`ls ${uiSource}`.quiet()).exitCode === 0) {
|
| 38 |
+
await $`cp -R ${uiSource} ${MACOS_DIR}/ui`;
|
| 39 |
+
} else {
|
| 40 |
+
console.warn("Warning: dist/ui not found. UI will be missing.");
|
| 41 |
+
}
|
| 42 |
+
} catch (e) {
|
| 43 |
+
console.warn("Failed to copy UI assets:", e);
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
console.log("Copying .env file...");
|
| 47 |
+
try {
|
| 48 |
+
const envSource = ".env";
|
| 49 |
+
if (Bun.file(envSource).size > 0) {
|
| 50 |
+
await $`cp ${envSource} ${MACOS_DIR}/.env`;
|
| 51 |
+
} else {
|
| 52 |
+
console.warn("Warning: .env not found. App will launch in Setup Mode.");
|
| 53 |
+
}
|
| 54 |
+
} catch (e) {
|
| 55 |
+
console.warn("Failed to copy .env:", e);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
console.log("Copying App Icon...");
|
| 59 |
+
try {
|
| 60 |
+
const iconSource = "assets/icon.icns";
|
| 61 |
+
if (Bun.file(iconSource).size > 0) {
|
| 62 |
+
await $`cp ${iconSource} ${RESOURCES_DIR}/AppIcon.icns`;
|
| 63 |
+
} else {
|
| 64 |
+
console.warn("Warning: assets/icon.icns not found. App will have default icon.");
|
| 65 |
+
}
|
| 66 |
+
} catch (e) {
|
| 67 |
+
console.warn("Failed to copy icon:", e);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
console.log("Creating Info.plist...");
|
| 71 |
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
| 72 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 73 |
+
<plist version="1.0">
|
| 74 |
+
<dict>
|
| 75 |
+
<key>CFBundleName</key>
|
| 76 |
+
<string>${APP_NAME}</string>
|
| 77 |
+
<key>CFBundleDisplayName</key>
|
| 78 |
+
<string>Morpheus ControlMart</string>
|
| 79 |
+
<key>CFBundleIdentifier</key>
|
| 80 |
+
<string>com.talkshopclub.morpheus</string>
|
| 81 |
+
<key>CFBundleVersion</key>
|
| 82 |
+
<string>1.0.0</string>
|
| 83 |
+
<key>CFBundleShortVersionString</key>
|
| 84 |
+
<string>1.0.0</string>
|
| 85 |
+
<key>CFBundleIconFile</key>
|
| 86 |
+
<string>AppIcon</string>
|
| 87 |
+
<key>CFBundlePackageType</key>
|
| 88 |
+
<string>APPL</string>
|
| 89 |
+
<key>CFBundleExecutable</key>
|
| 90 |
+
<string>MorpheusLauncher</string>
|
| 91 |
+
<key>LSMinimumSystemVersion</key>
|
| 92 |
+
<string>11.0</string>
|
| 93 |
+
<key>LSUIElement</key>
|
| 94 |
+
<false/>
|
| 95 |
+
</dict>
|
| 96 |
+
</plist>`;
|
| 97 |
+
await Bun.write(`${CONTENTS_DIR}/Info.plist`, plist);
|
| 98 |
+
|
| 99 |
+
console.log("Creating Launcher script...");
|
| 100 |
+
const launcher = `#!/bin/bash
|
| 101 |
+
DIR=$(cd "$(dirname "$0")"; pwd)
|
| 102 |
+
# Change CWD to the folder containing the .app bundle so .env is stored there
|
| 103 |
+
cd "$DIR/../../.."
|
| 104 |
+
LOG_FILE="/tmp/morpheus_app.log"
|
| 105 |
+
|
| 106 |
+
# Kill any existing instances to prevent EADDRINUSE
|
| 107 |
+
pkill -f "morpheus-server" || true
|
| 108 |
+
|
| 109 |
+
export MORPHEUS_LAUNCHER=true
|
| 110 |
+
|
| 111 |
+
while true; do
|
| 112 |
+
echo "$(date): Starting Morpheus..." >> "$LOG_FILE"
|
| 113 |
+
|
| 114 |
+
# Run the server in background to allow signal trapping
|
| 115 |
+
"$DIR/morpheus-server" >> "$LOG_FILE" 2>&1 &
|
| 116 |
+
PID=$!
|
| 117 |
+
|
| 118 |
+
# helper to kill server on exit
|
| 119 |
+
cleanup() {
|
| 120 |
+
echo "Stopping Morpheus..." >> "$LOG_FILE"
|
| 121 |
+
kill $PID
|
| 122 |
+
exit 0
|
| 123 |
+
}
|
| 124 |
+
trap cleanup SIGINT SIGTERM
|
| 125 |
+
|
| 126 |
+
# Wait for the process to finish
|
| 127 |
+
wait $PID
|
| 128 |
+
EXIT_CODE=$?
|
| 129 |
+
|
| 130 |
+
# Remove trap for normal exit handling
|
| 131 |
+
trap - SIGINT SIGTERM
|
| 132 |
+
|
| 133 |
+
# Check for restart request (Exit Code 100)
|
| 134 |
+
if [ $EXIT_CODE -eq 100 ]; then
|
| 135 |
+
echo "Restart requested..." >> "$LOG_FILE"
|
| 136 |
+
sleep 1
|
| 137 |
+
continue
|
| 138 |
+
fi
|
| 139 |
+
|
| 140 |
+
if [ $EXIT_CODE -ne 0 ]; then
|
| 141 |
+
echo "Morpheus exited with code $EXIT_CODE" >> "$LOG_FILE"
|
| 142 |
+
|
| 143 |
+
# Write error msg to temp file for safe reading
|
| 144 |
+
ERROR_FILE="/tmp/morpheus_error.txt"
|
| 145 |
+
tail -n 15 "$LOG_FILE" > "$ERROR_FILE"
|
| 146 |
+
|
| 147 |
+
# Show native alert dialog reading from file
|
| 148 |
+
osascript -e "display dialog (read POSIX file \\"$ERROR_FILE\\") with title \\"Morpheus Error\\" buttons {\\"OK\\"} default button \\"OK\\" icon stop"
|
| 149 |
+
fi
|
| 150 |
+
|
| 151 |
+
# Break loop for normal exit or error
|
| 152 |
+
break
|
| 153 |
+
done
|
| 154 |
+
|
| 155 |
+
exit $EXIT_CODE
|
| 156 |
+
`;
|
| 157 |
+
|
| 158 |
+
const launcherPath = `${MACOS_DIR}/MorpheusLauncher`;
|
| 159 |
+
await Bun.write(launcherPath, launcher);
|
| 160 |
+
|
| 161 |
+
// Make executable
|
| 162 |
+
chmodSync(launcherPath, "755");
|
| 163 |
+
chmodSync(`${MACOS_DIR}/morpheus-server`, "755");
|
| 164 |
+
|
| 165 |
+
console.log("Signing app bundle (ad-hoc)...");
|
| 166 |
+
try {
|
| 167 |
+
await $`codesign --force --deep --sign - ${APP_BUNDLE}`;
|
| 168 |
+
} catch (e) {
|
| 169 |
+
console.warn("Warning: Ad-hoc signing failed. App strictly requires xattr -cr to run on other machines.");
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
console.log("Creating distribution zip...");
|
| 173 |
+
await $`cd ${BUILD_DIR} && zip -r "${APP_NAME}.zip" "${APP_NAME}.app"`;
|
| 174 |
+
|
| 175 |
+
console.log(`Successfully created ${APP_BUNDLE}`);
|
| 176 |
+
console.log(`Distribution zip ready: ${BUILD_DIR}/${APP_NAME}.zip`);
|
packages/controlmart/scripts/measure-performance.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bun
|
| 2 |
+
|
| 3 |
+
/**
|
| 4 |
+
* Performance Baseline Measurement Script
|
| 5 |
+
*
|
| 6 |
+
* Measures execution time for all Phase 1 capabilities to establish baseline performance metrics.
|
| 7 |
+
* Run with: bun run scripts/measure-performance.ts
|
| 8 |
+
*/
|
| 9 |
+
|
| 10 |
+
import { connectMongo, disconnectMongo } from '../src/services/mongo.service';
|
| 11 |
+
import { CapabilityExecutor } from '../src/services/capability-executor.service';
|
| 12 |
+
import { WorldRepository } from '../src/repository/world.repository';
|
| 13 |
+
import { capabilityCatalog } from '../src/services/capability-catalog.service';
|
| 14 |
+
import { initializeODRegistry } from '../src/ods';
|
| 15 |
+
|
| 16 |
+
interface PerformanceResult {
|
| 17 |
+
capabilityId: string;
|
| 18 |
+
capabilityName: string;
|
| 19 |
+
runs: number;
|
| 20 |
+
avgDurationMs: number;
|
| 21 |
+
minDurationMs: number;
|
| 22 |
+
maxDurationMs: number;
|
| 23 |
+
stdDeviation: number;
|
| 24 |
+
successRate: number;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
async function measureCapabilityPerformance(
|
| 28 |
+
executor: CapabilityExecutor,
|
| 29 |
+
capabilityId: string,
|
| 30 |
+
worldId: string,
|
| 31 |
+
inputs: any,
|
| 32 |
+
runs: number = 10
|
| 33 |
+
): Promise<PerformanceResult> {
|
| 34 |
+
const capability = capabilityCatalog.getById(capabilityId);
|
| 35 |
+
if (!capability) {
|
| 36 |
+
throw new Error(`Capability not found: ${capabilityId}`);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
const durations: number[] = [];
|
| 40 |
+
let successCount = 0;
|
| 41 |
+
|
| 42 |
+
console.log(`\nπ Measuring ${capability.name} (${runs} runs)...`);
|
| 43 |
+
|
| 44 |
+
for (let i = 0; i < runs; i++) {
|
| 45 |
+
try {
|
| 46 |
+
const result = await executor.execute({
|
| 47 |
+
capabilityId,
|
| 48 |
+
worldId,
|
| 49 |
+
inputs,
|
| 50 |
+
});
|
| 51 |
+
|
| 52 |
+
if (result.status === 'success' && result.durationMs) {
|
| 53 |
+
durations.push(result.durationMs);
|
| 54 |
+
successCount++;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
process.stdout.write('.');
|
| 58 |
+
} catch (error) {
|
| 59 |
+
process.stdout.write('x');
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
console.log(' Done!');
|
| 64 |
+
|
| 65 |
+
// Calculate statistics
|
| 66 |
+
const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
|
| 67 |
+
const minDuration = Math.min(...durations);
|
| 68 |
+
const maxDuration = Math.max(...durations);
|
| 69 |
+
|
| 70 |
+
// Calculate standard deviation
|
| 71 |
+
const variance =
|
| 72 |
+
durations.reduce((sum, d) => sum + Math.pow(d - avgDuration, 2), 0) /
|
| 73 |
+
durations.length;
|
| 74 |
+
const stdDeviation = Math.sqrt(variance);
|
| 75 |
+
|
| 76 |
+
const successRate = (successCount / runs) * 100;
|
| 77 |
+
|
| 78 |
+
return {
|
| 79 |
+
capabilityId,
|
| 80 |
+
capabilityName: capability.name,
|
| 81 |
+
runs,
|
| 82 |
+
avgDurationMs: Math.round(avgDuration),
|
| 83 |
+
minDurationMs: Math.round(minDuration),
|
| 84 |
+
maxDurationMs: Math.round(maxDuration),
|
| 85 |
+
stdDeviation: Math.round(stdDeviation),
|
| 86 |
+
successRate: Math.round(successRate),
|
| 87 |
+
};
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
async function main() {
|
| 91 |
+
console.log('π Performance Baseline Measurement');
|
| 92 |
+
console.log('==================================\n');
|
| 93 |
+
|
| 94 |
+
// Connect to database
|
| 95 |
+
console.log('π¦ Connecting to database...');
|
| 96 |
+
const mongoUri = process.env.MONGO_URI || 'mongodb://localhost:27017';
|
| 97 |
+
const dbName = process.env.DB_NAME || 'morpheus-test';
|
| 98 |
+
await connectMongo({ uri: mongoUri, dbName });
|
| 99 |
+
|
| 100 |
+
// Initialize OD Registry
|
| 101 |
+
console.log('π§ Initializing OD Registry...');
|
| 102 |
+
initializeODRegistry();
|
| 103 |
+
|
| 104 |
+
// Create test world
|
| 105 |
+
console.log('π Creating test world...');
|
| 106 |
+
const world = await WorldRepository.createWorld({
|
| 107 |
+
name: `perf-test-${Date.now()}`,
|
| 108 |
+
description: 'Performance testing world',
|
| 109 |
+
status: 'active',
|
| 110 |
+
});
|
| 111 |
+
console.log(`β
World created: ${world._id}`);
|
| 112 |
+
|
| 113 |
+
const executor = new CapabilityExecutor();
|
| 114 |
+
const results: PerformanceResult[] = [];
|
| 115 |
+
|
| 116 |
+
// Disable chaos for baseline measurements
|
| 117 |
+
process.env.CHAOS_ENABLED = 'false';
|
| 118 |
+
|
| 119 |
+
// Test each capability
|
| 120 |
+
const capabilities = [
|
| 121 |
+
{
|
| 122 |
+
id: 'inventory-check',
|
| 123 |
+
inputs: { sku: 'SKU-001', locationId: 'WH-01' },
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
id: 'shipment-tracking',
|
| 127 |
+
inputs: { shipmentId: 'SHIP-001' },
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
id: 'equipment-availability-check',
|
| 131 |
+
inputs: { equipmentType: 'forklift', zoneId: 'ZONE-A' },
|
| 132 |
+
},
|
| 133 |
+
{
|
| 134 |
+
id: 'dock-appointment-scheduling',
|
| 135 |
+
inputs: {
|
| 136 |
+
date: '2025-11-21',
|
| 137 |
+
dockDoorId: 'DOCK-01',
|
| 138 |
+
appointmentType: 'inbound',
|
| 139 |
+
},
|
| 140 |
+
},
|
| 141 |
+
];
|
| 142 |
+
|
| 143 |
+
for (const cap of capabilities) {
|
| 144 |
+
const result = await measureCapabilityPerformance(
|
| 145 |
+
executor,
|
| 146 |
+
cap.id,
|
| 147 |
+
world._id.toString(),
|
| 148 |
+
cap.inputs,
|
| 149 |
+
10
|
| 150 |
+
);
|
| 151 |
+
results.push(result);
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// Print results
|
| 155 |
+
console.log('\n\nπ Performance Baseline Results');
|
| 156 |
+
console.log('================================\n');
|
| 157 |
+
|
| 158 |
+
console.table(
|
| 159 |
+
results.map((r) => ({
|
| 160 |
+
Capability: r.capabilityName,
|
| 161 |
+
'Avg (ms)': r.avgDurationMs,
|
| 162 |
+
'Min (ms)': r.minDurationMs,
|
| 163 |
+
'Max (ms)': r.maxDurationMs,
|
| 164 |
+
'Std Dev': r.stdDeviation,
|
| 165 |
+
'Success Rate': `${r.successRate}%`,
|
| 166 |
+
}))
|
| 167 |
+
);
|
| 168 |
+
|
| 169 |
+
// Overall statistics
|
| 170 |
+
const totalAvg =
|
| 171 |
+
results.reduce((sum, r) => sum + r.avgDurationMs, 0) / results.length;
|
| 172 |
+
console.log(`\nπ Overall Average: ${Math.round(totalAvg)}ms`);
|
| 173 |
+
|
| 174 |
+
// Save results to file
|
| 175 |
+
const timestamp = new Date().toISOString();
|
| 176 |
+
const report = {
|
| 177 |
+
timestamp,
|
| 178 |
+
environment: {
|
| 179 |
+
nodeVersion: process.version,
|
| 180 |
+
platform: process.platform,
|
| 181 |
+
chaosEnabled: false,
|
| 182 |
+
},
|
| 183 |
+
results,
|
| 184 |
+
summary: {
|
| 185 |
+
totalCapabilities: results.length,
|
| 186 |
+
overallAvgMs: Math.round(totalAvg),
|
| 187 |
+
},
|
| 188 |
+
};
|
| 189 |
+
|
| 190 |
+
await Bun.write(
|
| 191 |
+
'config/performance-baselines.json',
|
| 192 |
+
JSON.stringify(report, null, 2)
|
| 193 |
+
);
|
| 194 |
+
console.log('\nπΎ Results saved to config/performance-baselines.json');
|
| 195 |
+
|
| 196 |
+
// Cleanup
|
| 197 |
+
console.log('\nπ§Ή Cleaning up...');
|
| 198 |
+
await WorldRepository.deleteWorld(world._id.toString());
|
| 199 |
+
await disconnectMongo();
|
| 200 |
+
|
| 201 |
+
console.log('β
Done!\n');
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
main().catch((error) => {
|
| 205 |
+
console.error('β Error:', error);
|
| 206 |
+
process.exit(1);
|
| 207 |
+
});
|
packages/controlmart/scripts/migrate-capabilities-to-db.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Capability Migration Script
|
| 3 |
+
*
|
| 4 |
+
* Migrates capabilities from src/capabilities/catalog.ts to MongoDB.
|
| 5 |
+
* Idempotent - safe to run multiple times.
|
| 6 |
+
*
|
| 7 |
+
* Usage:
|
| 8 |
+
* bun run scripts/migrate-capabilities-to-db.ts [--dry-run] [--force] [--clear-first]
|
| 9 |
+
*
|
| 10 |
+
* Options:
|
| 11 |
+
* --dry-run Preview changes without writing to database
|
| 12 |
+
* --force Update existing capabilities instead of skipping
|
| 13 |
+
* --clear-first Delete all existing capabilities before migration
|
| 14 |
+
*/
|
| 15 |
+
|
| 16 |
+
import { connectMongo, createCollectionsIfNotExist } from "../src/services/mongo.service";
|
| 17 |
+
import { Capability } from "../src/models/capability.model";
|
| 18 |
+
import { CapabilityRepository } from "../src/repository/capability.repository";
|
| 19 |
+
import { INITIAL_CAPABILITIES } from "../src/capabilities/catalog";
|
| 20 |
+
import { getErrorMessage } from "../src/utils/error.util";
|
| 21 |
+
import { loadEnv } from "../src/utils/env.util";
|
| 22 |
+
|
| 23 |
+
interface MigrateOptions {
|
| 24 |
+
dryRun?: boolean;
|
| 25 |
+
force?: boolean;
|
| 26 |
+
clearFirst?: boolean;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
interface MigrationStats {
|
| 30 |
+
created: number;
|
| 31 |
+
updated: number;
|
| 32 |
+
skipped: number;
|
| 33 |
+
errors: number;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
async function migrate(options: MigrateOptions = {}): Promise<void> {
|
| 37 |
+
console.log("[migrate-capabilities] Starting migration...");
|
| 38 |
+
console.log(`[migrate-capabilities] Options:`, {
|
| 39 |
+
dryRun: options.dryRun || false,
|
| 40 |
+
force: options.force || false,
|
| 41 |
+
clearFirst: options.clearFirst || false,
|
| 42 |
+
});
|
| 43 |
+
|
| 44 |
+
// Load environment variables
|
| 45 |
+
const env = loadEnv();
|
| 46 |
+
|
| 47 |
+
// Connect to MongoDB
|
| 48 |
+
await connectMongo({
|
| 49 |
+
uri: env.MONGO_URI,
|
| 50 |
+
dbName: env.DB_NAME,
|
| 51 |
+
log: true,
|
| 52 |
+
});
|
| 53 |
+
|
| 54 |
+
// Ensure collection exists with indexes
|
| 55 |
+
await createCollectionsIfNotExist({
|
| 56 |
+
models: [Capability],
|
| 57 |
+
log: true,
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
// Clear existing capabilities if requested
|
| 61 |
+
if (options.clearFirst) {
|
| 62 |
+
if (options.dryRun) {
|
| 63 |
+
console.log("[DRY-RUN] Would clear all existing capabilities");
|
| 64 |
+
} else {
|
| 65 |
+
console.log("[migrate-capabilities] Clearing existing capabilities...");
|
| 66 |
+
await (Capability as any).deleteMany({}).exec();
|
| 67 |
+
console.log("[migrate-capabilities] Cleared all capabilities");
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
// Migrate capabilities
|
| 72 |
+
console.log(`\n[migrate-capabilities] Migrating ${INITIAL_CAPABILITIES.length} capabilities...\n`);
|
| 73 |
+
|
| 74 |
+
const stats: MigrationStats = {
|
| 75 |
+
created: 0,
|
| 76 |
+
updated: 0,
|
| 77 |
+
skipped: 0,
|
| 78 |
+
errors: 0,
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
for (const capability of INITIAL_CAPABILITIES) {
|
| 82 |
+
try {
|
| 83 |
+
if (options.dryRun) {
|
| 84 |
+
console.log(`[DRY-RUN] Would create/update: ${capability.id} (${capability.name})`);
|
| 85 |
+
stats.created++;
|
| 86 |
+
} else {
|
| 87 |
+
// Check if capability already exists
|
| 88 |
+
const existing = await CapabilityRepository.findById(capability.id);
|
| 89 |
+
|
| 90 |
+
if (existing && !options.force) {
|
| 91 |
+
console.log(`βοΈ Skipping existing: ${capability.id} (${capability.name})`);
|
| 92 |
+
stats.skipped++;
|
| 93 |
+
} else if (existing && options.force) {
|
| 94 |
+
// Update existing capability
|
| 95 |
+
await CapabilityRepository.update(capability.id, capability);
|
| 96 |
+
console.log(`βοΈ Updated: ${capability.id} (${capability.name})`);
|
| 97 |
+
stats.updated++;
|
| 98 |
+
} else {
|
| 99 |
+
// Create new capability
|
| 100 |
+
await CapabilityRepository.create(capability);
|
| 101 |
+
console.log(`β
Created: ${capability.id} (${capability.name})`);
|
| 102 |
+
stats.created++;
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
} catch (error) {
|
| 106 |
+
console.error(`β Error migrating ${capability.id}:`, getErrorMessage(error));
|
| 107 |
+
stats.errors++;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// Print summary
|
| 112 |
+
console.log(`\n${"=".repeat(60)}`);
|
| 113 |
+
console.log("[migrate-capabilities] Migration complete");
|
| 114 |
+
console.log(`${"=".repeat(60)}`);
|
| 115 |
+
console.log(` Created: ${stats.created}`);
|
| 116 |
+
console.log(` Updated: ${stats.updated}`);
|
| 117 |
+
console.log(` Skipped: ${stats.skipped}`);
|
| 118 |
+
console.log(` Errors: ${stats.errors}`);
|
| 119 |
+
console.log(` Total: ${INITIAL_CAPABILITIES.length}`);
|
| 120 |
+
console.log(`${"=".repeat(60)}\n`);
|
| 121 |
+
|
| 122 |
+
if (options.dryRun) {
|
| 123 |
+
console.log("π‘ This was a dry-run. No changes were made to the database.");
|
| 124 |
+
console.log(" Run without --dry-run to apply changes.\n");
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
// Exit with appropriate code
|
| 128 |
+
if (stats.errors > 0) {
|
| 129 |
+
console.error("[migrate-capabilities] Migration completed with errors");
|
| 130 |
+
process.exit(1);
|
| 131 |
+
} else {
|
| 132 |
+
console.log("[migrate-capabilities] Migration successful");
|
| 133 |
+
process.exit(0);
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
// Main execution
|
| 138 |
+
async function main() {
|
| 139 |
+
// Parse command line arguments
|
| 140 |
+
const args = process.argv.slice(2);
|
| 141 |
+
const options: MigrateOptions = {
|
| 142 |
+
dryRun: args.includes('--dry-run'),
|
| 143 |
+
force: args.includes('--force'),
|
| 144 |
+
clearFirst: args.includes('--clear-first'),
|
| 145 |
+
};
|
| 146 |
+
|
| 147 |
+
// Validate conflicting options
|
| 148 |
+
if (options.clearFirst && options.force) {
|
| 149 |
+
console.warn("[migrate-capabilities] Warning: --clear-first and --force both specified.");
|
| 150 |
+
console.warn(" --clear-first will delete all capabilities before migration.");
|
| 151 |
+
console.warn(" Continuing in 3 seconds... (Ctrl+C to cancel)");
|
| 152 |
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
// Run migration
|
| 156 |
+
await migrate(options);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
// Execute main function
|
| 160 |
+
main().catch((err) => {
|
| 161 |
+
console.error("[migrate-capabilities] Fatal error:", getErrorMessage(err));
|
| 162 |
+
process.exit(1);
|
| 163 |
+
});
|
packages/controlmart/scripts/migrate-knowledge-graph-to-db.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Knowledge Graph Migration Script
|
| 3 |
+
*
|
| 4 |
+
* Builds knowledge graph from code annotations (ODs, capabilities, personas, tools)
|
| 5 |
+
* and persists it to MongoDB.
|
| 6 |
+
*
|
| 7 |
+
* Usage:
|
| 8 |
+
* bun run scripts/migrate-knowledge-graph-to-db.ts [--dry-run] [--clear-first]
|
| 9 |
+
*
|
| 10 |
+
* Options:
|
| 11 |
+
* --dry-run Preview graph build without writing to database
|
| 12 |
+
* --clear-first Delete existing graph before migration
|
| 13 |
+
*
|
| 14 |
+
* Dependencies:
|
| 15 |
+
* - Capabilities must be migrated first (run migrate-capabilities-to-db.ts)
|
| 16 |
+
* - Personas must be migrated first (run migrate-personas-to-db.ts)
|
| 17 |
+
*/
|
| 18 |
+
|
| 19 |
+
import { connectMongo, createCollectionsIfNotExist } from "../src/services/mongo.service";
|
| 20 |
+
import { KnowledgeGraphNode } from "../src/models/knowledge-graph-node.model";
|
| 21 |
+
import { KnowledgeGraphEdge } from "../src/models/knowledge-graph-edge.model";
|
| 22 |
+
import { knowledgeGraph } from "../src/services/knowledge-graph.service";
|
| 23 |
+
import { capabilityCatalog } from "../src/services/capability-catalog.service";
|
| 24 |
+
import { personaRegistry } from "../src/services/persona-registry.service";
|
| 25 |
+
import { initializeODRegistry } from "../src/ods/index";
|
| 26 |
+
import { getErrorMessage } from "../src/utils/error.util";
|
| 27 |
+
import { loadEnv } from "../src/utils/env.util";
|
| 28 |
+
|
| 29 |
+
interface MigrateOptions {
|
| 30 |
+
dryRun?: boolean;
|
| 31 |
+
clearFirst?: boolean;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
interface MigrationResult {
|
| 35 |
+
nodeCount: number;
|
| 36 |
+
edgeCount: number;
|
| 37 |
+
source: string;
|
| 38 |
+
status: 'success' | 'error';
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
/**
|
| 42 |
+
* Verify that dependencies (capabilities and personas) are already migrated
|
| 43 |
+
*/
|
| 44 |
+
async function verifyDependencies(): Promise<void> {
|
| 45 |
+
console.log("[migrate-knowledge-graph] Verifying dependencies...\n");
|
| 46 |
+
|
| 47 |
+
// Initialize capability catalog
|
| 48 |
+
try {
|
| 49 |
+
await capabilityCatalog.initialize();
|
| 50 |
+
const capCount = capabilityCatalog.count();
|
| 51 |
+
if (capCount === 0) {
|
| 52 |
+
console.error("β Error: No capabilities found in database");
|
| 53 |
+
console.error(" Run: bun run scripts/migrate-capabilities-to-db.ts\n");
|
| 54 |
+
process.exit(1);
|
| 55 |
+
}
|
| 56 |
+
console.log(` β
Capabilities: ${capCount} loaded`);
|
| 57 |
+
} catch (error) {
|
| 58 |
+
console.error("β Error: Failed to load capabilities");
|
| 59 |
+
console.error(` ${getErrorMessage(error)}`);
|
| 60 |
+
console.error(" Run: bun run scripts/migrate-capabilities-to-db.ts\n");
|
| 61 |
+
process.exit(1);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
// Initialize persona registry
|
| 65 |
+
try {
|
| 66 |
+
await personaRegistry.initialize();
|
| 67 |
+
const personaCount = personaRegistry.getCount();
|
| 68 |
+
if (personaCount === 0) {
|
| 69 |
+
console.error("β Error: No personas found in database");
|
| 70 |
+
console.error(" Run: bun run scripts/migrate-personas-to-db.ts\n");
|
| 71 |
+
process.exit(1);
|
| 72 |
+
}
|
| 73 |
+
console.log(` β
Personas: ${personaCount} loaded`);
|
| 74 |
+
} catch (error) {
|
| 75 |
+
console.error("β Error: Failed to load personas");
|
| 76 |
+
console.error(` ${getErrorMessage(error)}`);
|
| 77 |
+
console.error(" Run: bun run scripts/migrate-personas-to-db.ts\n");
|
| 78 |
+
process.exit(1);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
// Initialize OD Registry
|
| 82 |
+
try {
|
| 83 |
+
initializeODRegistry();
|
| 84 |
+
console.log(` β
OD Registry initialized`);
|
| 85 |
+
} catch (error) {
|
| 86 |
+
console.error("β Error: Failed to initialize OD Registry");
|
| 87 |
+
console.error(` ${getErrorMessage(error)}\n`);
|
| 88 |
+
process.exit(1);
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
console.log("");
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
/**
|
| 95 |
+
* Clear existing knowledge graph from database
|
| 96 |
+
*/
|
| 97 |
+
async function clearGraph(): Promise<void> {
|
| 98 |
+
console.log("[migrate-knowledge-graph] Clearing existing graph...");
|
| 99 |
+
await (KnowledgeGraphNode as any).deleteMany({}).exec();
|
| 100 |
+
await (KnowledgeGraphEdge as any).deleteMany({}).exec();
|
| 101 |
+
console.log("[migrate-knowledge-graph] Cleared all nodes and edges\n");
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
/**
|
| 105 |
+
* Main migration function
|
| 106 |
+
*/
|
| 107 |
+
async function migrate(options: MigrateOptions = {}): Promise<MigrationResult> {
|
| 108 |
+
console.log("[migrate-knowledge-graph] Starting migration...");
|
| 109 |
+
console.log(`[migrate-knowledge-graph] Options:`, {
|
| 110 |
+
dryRun: options.dryRun || false,
|
| 111 |
+
clearFirst: options.clearFirst || false,
|
| 112 |
+
});
|
| 113 |
+
console.log("");
|
| 114 |
+
|
| 115 |
+
// Load environment variables
|
| 116 |
+
const env = loadEnv();
|
| 117 |
+
|
| 118 |
+
// Connect to MongoDB
|
| 119 |
+
await connectMongo({
|
| 120 |
+
uri: env.MONGO_URI,
|
| 121 |
+
dbName: env.DB_NAME,
|
| 122 |
+
log: true,
|
| 123 |
+
});
|
| 124 |
+
|
| 125 |
+
// Ensure collections exist with indexes
|
| 126 |
+
await createCollectionsIfNotExist({
|
| 127 |
+
models: [KnowledgeGraphNode, KnowledgeGraphEdge],
|
| 128 |
+
log: true,
|
| 129 |
+
});
|
| 130 |
+
|
| 131 |
+
console.log("");
|
| 132 |
+
|
| 133 |
+
// Verify dependencies (capabilities, personas, ODs)
|
| 134 |
+
await verifyDependencies();
|
| 135 |
+
|
| 136 |
+
// Clear existing graph if requested
|
| 137 |
+
if (options.clearFirst && !options.dryRun) {
|
| 138 |
+
await clearGraph();
|
| 139 |
+
} else if (options.clearFirst && options.dryRun) {
|
| 140 |
+
console.log("[DRY-RUN] Would clear existing graph\n");
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
// Build knowledge graph from annotations
|
| 144 |
+
console.log("[migrate-knowledge-graph] Building knowledge graph from annotations...\n");
|
| 145 |
+
|
| 146 |
+
try {
|
| 147 |
+
if (options.dryRun) {
|
| 148 |
+
// In dry-run, build graph but don't save
|
| 149 |
+
console.log("[DRY-RUN] Building graph (will not save to database)...");
|
| 150 |
+
knowledgeGraph.buildGraphFromAnnotations();
|
| 151 |
+
|
| 152 |
+
const nodeCount = (knowledgeGraph as any).graph.nodeCount();
|
| 153 |
+
const edgeCount = (knowledgeGraph as any).graph.edgeCount();
|
| 154 |
+
|
| 155 |
+
console.log(`[DRY-RUN] Would save: ${nodeCount} nodes, ${edgeCount} edges\n`);
|
| 156 |
+
|
| 157 |
+
return {
|
| 158 |
+
nodeCount,
|
| 159 |
+
edgeCount,
|
| 160 |
+
source: 'annotations',
|
| 161 |
+
status: 'success',
|
| 162 |
+
};
|
| 163 |
+
} else {
|
| 164 |
+
// Build graph from annotations
|
| 165 |
+
knowledgeGraph.buildGraphFromAnnotations();
|
| 166 |
+
|
| 167 |
+
const nodeCount = (knowledgeGraph as any).graph.nodeCount();
|
| 168 |
+
const edgeCount = (knowledgeGraph as any).graph.edgeCount();
|
| 169 |
+
|
| 170 |
+
console.log(`[KnowledgeGraphService] Built graph: ${nodeCount} nodes, ${edgeCount} edges\n`);
|
| 171 |
+
|
| 172 |
+
// Save to MongoDB
|
| 173 |
+
console.log("[migrate-knowledge-graph] Saving to MongoDB...");
|
| 174 |
+
await knowledgeGraph.saveToDB();
|
| 175 |
+
console.log("[migrate-knowledge-graph] Successfully saved graph to database\n");
|
| 176 |
+
|
| 177 |
+
return {
|
| 178 |
+
nodeCount,
|
| 179 |
+
edgeCount,
|
| 180 |
+
source: 'annotations',
|
| 181 |
+
status: 'success',
|
| 182 |
+
};
|
| 183 |
+
}
|
| 184 |
+
} catch (error) {
|
| 185 |
+
console.error("β Error building or saving knowledge graph:");
|
| 186 |
+
console.error(` ${getErrorMessage(error)}\n`);
|
| 187 |
+
return {
|
| 188 |
+
nodeCount: 0,
|
| 189 |
+
edgeCount: 0,
|
| 190 |
+
source: 'annotations',
|
| 191 |
+
status: 'error',
|
| 192 |
+
};
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
/**
|
| 197 |
+
* Main execution
|
| 198 |
+
*/
|
| 199 |
+
async function main() {
|
| 200 |
+
// Parse command line arguments
|
| 201 |
+
const args = process.argv.slice(2);
|
| 202 |
+
const options: MigrateOptions = {
|
| 203 |
+
dryRun: args.includes('--dry-run'),
|
| 204 |
+
clearFirst: args.includes('--clear-first'),
|
| 205 |
+
};
|
| 206 |
+
|
| 207 |
+
// Run migration
|
| 208 |
+
const result = await migrate(options);
|
| 209 |
+
|
| 210 |
+
// Print summary
|
| 211 |
+
console.log(`${"=".repeat(60)}`);
|
| 212 |
+
console.log("[migrate-knowledge-graph] Migration complete");
|
| 213 |
+
console.log(`${"=".repeat(60)}`);
|
| 214 |
+
console.log(` Nodes: ${result.nodeCount}`);
|
| 215 |
+
console.log(` Edges: ${result.edgeCount}`);
|
| 216 |
+
console.log(` Source: ${result.source}`);
|
| 217 |
+
console.log(` Status: ${result.status}`);
|
| 218 |
+
console.log(`${"=".repeat(60)}\n`);
|
| 219 |
+
|
| 220 |
+
if (options.dryRun) {
|
| 221 |
+
console.log("π‘ This was a dry-run. No changes were made to the database.");
|
| 222 |
+
console.log(" Run without --dry-run to apply changes.\n");
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
if (result.status === 'error') {
|
| 226 |
+
console.error("[migrate-knowledge-graph] Migration failed");
|
| 227 |
+
process.exit(1);
|
| 228 |
+
} else {
|
| 229 |
+
console.log("[migrate-knowledge-graph] Migration successful");
|
| 230 |
+
|
| 231 |
+
if (!options.dryRun) {
|
| 232 |
+
console.log("\nπ‘ Next steps:");
|
| 233 |
+
console.log(" - Restart your application to load the knowledge graph from MongoDB");
|
| 234 |
+
console.log(" - The graph will be loaded via knowledgeGraph.initialize()\n");
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
process.exit(0);
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
// Execute main function
|
| 242 |
+
main().catch((err) => {
|
| 243 |
+
console.error("[migrate-knowledge-graph] Fatal error:", getErrorMessage(err));
|
| 244 |
+
process.exit(1);
|
| 245 |
+
});
|
packages/controlmart/scripts/migrate-personas-to-db.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Persona Migration Script
|
| 3 |
+
*
|
| 4 |
+
* Migrates personas from src/personas/catalog.ts to MongoDB.
|
| 5 |
+
* Idempotent - safe to run multiple times.
|
| 6 |
+
*
|
| 7 |
+
* Usage:
|
| 8 |
+
* bun run scripts/migrate-personas-to-db.ts [--dry-run] [--force] [--clear-first]
|
| 9 |
+
*
|
| 10 |
+
* Options:
|
| 11 |
+
* --dry-run Preview changes without writing to database
|
| 12 |
+
* --force Update existing personas instead of skipping
|
| 13 |
+
* --clear-first Delete all existing personas before migration
|
| 14 |
+
*/
|
| 15 |
+
|
| 16 |
+
import { connectMongo, createCollectionsIfNotExist } from "../src/services/mongo.service";
|
| 17 |
+
import { Persona } from "../src/models/persona.model";
|
| 18 |
+
import { PersonaRepository } from "../src/repository/persona.repository";
|
| 19 |
+
import { personaCatalog } from "../src/personas/catalog";
|
| 20 |
+
import { getErrorMessage } from "../src/utils/error.util";
|
| 21 |
+
import { loadEnv } from "../src/utils/env.util";
|
| 22 |
+
|
| 23 |
+
interface MigrateOptions {
|
| 24 |
+
dryRun?: boolean;
|
| 25 |
+
force?: boolean;
|
| 26 |
+
clearFirst?: boolean;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
interface MigrationStats {
|
| 30 |
+
created: number;
|
| 31 |
+
updated: number;
|
| 32 |
+
skipped: number;
|
| 33 |
+
errors: number;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
async function migrate(options: MigrateOptions = {}): Promise<void> {
|
| 37 |
+
console.log("[migrate-personas] Starting migration...");
|
| 38 |
+
console.log(`[migrate-personas] Options:`, {
|
| 39 |
+
dryRun: options.dryRun || false,
|
| 40 |
+
force: options.force || false,
|
| 41 |
+
clearFirst: options.clearFirst || false,
|
| 42 |
+
});
|
| 43 |
+
|
| 44 |
+
// Load environment variables
|
| 45 |
+
const env = loadEnv();
|
| 46 |
+
|
| 47 |
+
// Connect to MongoDB
|
| 48 |
+
await connectMongo({
|
| 49 |
+
uri: env.MONGO_URI,
|
| 50 |
+
dbName: env.DB_NAME,
|
| 51 |
+
log: true,
|
| 52 |
+
});
|
| 53 |
+
|
| 54 |
+
// Ensure collection exists with indexes
|
| 55 |
+
await createCollectionsIfNotExist({
|
| 56 |
+
models: [Persona],
|
| 57 |
+
log: true,
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
// Clear existing personas if requested
|
| 61 |
+
if (options.clearFirst) {
|
| 62 |
+
if (options.dryRun) {
|
| 63 |
+
console.log("[DRY-RUN] Would clear all existing personas");
|
| 64 |
+
} else {
|
| 65 |
+
console.log("[migrate-personas] Clearing existing personas...");
|
| 66 |
+
await (Persona as any).deleteMany({}).exec();
|
| 67 |
+
console.log("[migrate-personas] Cleared all personas");
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
// Migrate personas
|
| 72 |
+
console.log(`\n[migrate-personas] Migrating ${personaCatalog.length} personas...\n`);
|
| 73 |
+
|
| 74 |
+
const stats: MigrationStats = {
|
| 75 |
+
created: 0,
|
| 76 |
+
updated: 0,
|
| 77 |
+
skipped: 0,
|
| 78 |
+
errors: 0,
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
for (const persona of personaCatalog) {
|
| 82 |
+
try {
|
| 83 |
+
if (options.dryRun) {
|
| 84 |
+
console.log(`[DRY-RUN] Would create/update: ${persona.id} (${persona.name}) - ${persona.capabilityIds.length} capabilities`);
|
| 85 |
+
stats.created++;
|
| 86 |
+
} else {
|
| 87 |
+
// Check if persona already exists
|
| 88 |
+
const existing = await PersonaRepository.findById(persona.id);
|
| 89 |
+
|
| 90 |
+
if (existing && !options.force) {
|
| 91 |
+
console.log(`βοΈ Skipping existing: ${persona.id} (${persona.name})`);
|
| 92 |
+
stats.skipped++;
|
| 93 |
+
} else if (existing && options.force) {
|
| 94 |
+
// Update existing persona
|
| 95 |
+
await PersonaRepository.update(persona.id, persona);
|
| 96 |
+
console.log(`βοΈ Updated: ${persona.id} (${persona.name}) - ${persona.capabilityIds.length} capabilities`);
|
| 97 |
+
stats.updated++;
|
| 98 |
+
} else {
|
| 99 |
+
// Create new persona
|
| 100 |
+
await PersonaRepository.create(persona);
|
| 101 |
+
console.log(`β
Created: ${persona.id} (${persona.name}) - ${persona.capabilityIds.length} capabilities`);
|
| 102 |
+
stats.created++;
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
} catch (error) {
|
| 106 |
+
console.error(`β Error migrating ${persona.id}:`, getErrorMessage(error));
|
| 107 |
+
stats.errors++;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// Print summary
|
| 112 |
+
console.log(`\n${"=".repeat(60)}`);
|
| 113 |
+
console.log("[migrate-personas] Migration complete");
|
| 114 |
+
console.log(`${"=".repeat(60)}`);
|
| 115 |
+
console.log(` Created: ${stats.created}`);
|
| 116 |
+
console.log(` Updated: ${stats.updated}`);
|
| 117 |
+
console.log(` Skipped: ${stats.skipped}`);
|
| 118 |
+
console.log(` Errors: ${stats.errors}`);
|
| 119 |
+
console.log(` Total: ${personaCatalog.length}`);
|
| 120 |
+
console.log(`${"=".repeat(60)}\n`);
|
| 121 |
+
|
| 122 |
+
if (options.dryRun) {
|
| 123 |
+
console.log("π‘ This was a dry-run. No changes were made to the database.");
|
| 124 |
+
console.log(" Run without --dry-run to apply changes.\n");
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
// Exit with appropriate code
|
| 128 |
+
if (stats.errors > 0) {
|
| 129 |
+
console.error("[migrate-personas] Migration completed with errors");
|
| 130 |
+
process.exit(1);
|
| 131 |
+
} else {
|
| 132 |
+
console.log("[migrate-personas] Migration successful");
|
| 133 |
+
process.exit(0);
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
// Main execution
|
| 138 |
+
async function main() {
|
| 139 |
+
// Parse command line arguments
|
| 140 |
+
const args = process.argv.slice(2);
|
| 141 |
+
const options: MigrateOptions = {
|
| 142 |
+
dryRun: args.includes('--dry-run'),
|
| 143 |
+
force: args.includes('--force'),
|
| 144 |
+
clearFirst: args.includes('--clear-first'),
|
| 145 |
+
};
|
| 146 |
+
|
| 147 |
+
// Validate conflicting options
|
| 148 |
+
if (options.clearFirst && options.force) {
|
| 149 |
+
console.warn("[migrate-personas] Warning: --clear-first and --force both specified.");
|
| 150 |
+
console.warn(" --clear-first will delete all personas before migration.");
|
| 151 |
+
console.warn(" Continuing in 3 seconds... (Ctrl+C to cancel)");
|
| 152 |
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
// Run migration
|
| 156 |
+
await migrate(options);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
// Execute main function
|
| 160 |
+
main().catch((err) => {
|
| 161 |
+
console.error("[migrate-personas] Fatal error:", getErrorMessage(err));
|
| 162 |
+
process.exit(1);
|
| 163 |
+
});
|
packages/controlmart/scripts/seed-dev-data.ts
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Seed Development Data Script
|
| 3 |
+
*
|
| 4 |
+
* One-command solution to seed MongoDB with all development data:
|
| 5 |
+
* - Capabilities (4)
|
| 6 |
+
* - Personas (5)
|
| 7 |
+
* - Knowledge Graph (63 nodes, 80 edges)
|
| 8 |
+
* - Sample Worlds (5 with diverse sampling strategies)
|
| 9 |
+
*
|
| 10 |
+
* Usage:
|
| 11 |
+
* bun run seed-dev # Interactive with confirmation
|
| 12 |
+
* bun run seed-dev --no-confirm # Skip confirmation
|
| 13 |
+
* bun run seed-dev --skip-worlds # Skip world creation
|
| 14 |
+
*
|
| 15 |
+
* Note: This script orchestrates other migration scripts
|
| 16 |
+
*/
|
| 17 |
+
|
| 18 |
+
import { spawn } from 'child_process';
|
| 19 |
+
import * as readline from 'readline';
|
| 20 |
+
import * as crypto from 'crypto';
|
| 21 |
+
import { connectMongo, createCollectionsIfNotExist } from "../src/services/mongo.service";
|
| 22 |
+
import { World } from "../src/models/world.model";
|
| 23 |
+
import { Capability } from "../src/models/capability.model";
|
| 24 |
+
import { Persona } from "../src/models/persona.model";
|
| 25 |
+
import { KnowledgeGraphNode } from "../src/models/knowledge-graph-node.model";
|
| 26 |
+
import { KnowledgeGraphEdge } from "../src/models/knowledge-graph-edge.model";
|
| 27 |
+
import { WorldRepository } from "../src/repository/world.repository";
|
| 28 |
+
import { capabilitySamplingService } from "../src/services/capability-sampling.service";
|
| 29 |
+
import { capabilityCatalog } from "../src/services/capability-catalog.service";
|
| 30 |
+
import { getErrorMessage } from "../src/utils/error.util";
|
| 31 |
+
import { loadEnv } from "../src/utils/env.util";
|
| 32 |
+
import type { TWorldInput, SamplingStrategy, PersonaConfig } from "../src/models/world.model.type";
|
| 33 |
+
|
| 34 |
+
interface SeedOptions {
|
| 35 |
+
noConfirm?: boolean;
|
| 36 |
+
skipWorlds?: boolean;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
interface SeedResult {
|
| 40 |
+
capabilities: number;
|
| 41 |
+
personas: number;
|
| 42 |
+
knowledgeGraphNodes: number;
|
| 43 |
+
knowledgeGraphEdges: number;
|
| 44 |
+
worlds: number;
|
| 45 |
+
worldDetails: Array<{ name: string; capabilityCount: number }>;
|
| 46 |
+
duration: number;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
interface WorldSpec {
|
| 50 |
+
name: string;
|
| 51 |
+
url: string;
|
| 52 |
+
description: string;
|
| 53 |
+
samplingStrategy: SamplingStrategy;
|
| 54 |
+
personas?: PersonaConfig;
|
| 55 |
+
mpcCompany?: string;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
/**
|
| 59 |
+
* Sample world specifications demonstrating different sampling strategies
|
| 60 |
+
*/
|
| 61 |
+
const SAMPLE_WORLD_SPECS: WorldSpec[] = [
|
| 62 |
+
{
|
| 63 |
+
name: 'development-local',
|
| 64 |
+
url: 'http://localhost:3000',
|
| 65 |
+
description: 'Full capability access for local development',
|
| 66 |
+
samplingStrategy: { type: 'all' },
|
| 67 |
+
personas: {
|
| 68 |
+
allowedPersonas: ['warehouse-manager', 'system-administrator']
|
| 69 |
+
},
|
| 70 |
+
mpcCompany: 'Morpheus Labs'
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
name: 'staging-integration',
|
| 74 |
+
url: 'https://staging.example.com',
|
| 75 |
+
description: 'Inventory-focused staging environment',
|
| 76 |
+
samplingStrategy: {
|
| 77 |
+
type: 'filter',
|
| 78 |
+
filter: { domain: ['inventory', 'warehousing'] }
|
| 79 |
+
},
|
| 80 |
+
personas: {
|
| 81 |
+
allowedPersonas: ['warehouse-manager', 'warehouse-worker', 'store-manager']
|
| 82 |
+
},
|
| 83 |
+
mpcCompany: 'Morpheus Staging'
|
| 84 |
+
},
|
| 85 |
+
{
|
| 86 |
+
name: 'demo-showcase',
|
| 87 |
+
url: 'https://demo.example.com',
|
| 88 |
+
description: 'Reproducible demo with seeded capabilities',
|
| 89 |
+
samplingStrategy: {
|
| 90 |
+
type: 'seeded',
|
| 91 |
+
count: 3,
|
| 92 |
+
seed: 12345
|
| 93 |
+
},
|
| 94 |
+
personas: {
|
| 95 |
+
allowedPersonas: ['store-manager', 'customer-service-rep']
|
| 96 |
+
},
|
| 97 |
+
mpcCompany: 'Morpheus Demo'
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
name: 'test-automation',
|
| 101 |
+
url: 'http://test.example.com',
|
| 102 |
+
description: 'Random capability subset for testing',
|
| 103 |
+
samplingStrategy: {
|
| 104 |
+
type: 'random',
|
| 105 |
+
count: 2
|
| 106 |
+
},
|
| 107 |
+
personas: {
|
| 108 |
+
allowedPersonas: ['warehouse-worker', 'store-manager'],
|
| 109 |
+
personaOverrides: {
|
| 110 |
+
'warehouse-worker': {
|
| 111 |
+
capabilityIds: ['inventory-check']
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
mpcCompany: 'Morpheus Test'
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
name: 'performance-load',
|
| 119 |
+
url: 'http://perf.example.com',
|
| 120 |
+
description: 'Simple capabilities for load testing',
|
| 121 |
+
samplingStrategy: {
|
| 122 |
+
type: 'filter',
|
| 123 |
+
filter: { complexity: 'simple' }
|
| 124 |
+
},
|
| 125 |
+
mpcCompany: 'Morpheus Performance'
|
| 126 |
+
}
|
| 127 |
+
];
|
| 128 |
+
|
| 129 |
+
/**
|
| 130 |
+
* Prompt user for confirmation
|
| 131 |
+
*/
|
| 132 |
+
async function promptConfirmation(env: ReturnType<typeof loadEnv>): Promise<boolean> {
|
| 133 |
+
console.log('\nβ οΈ This will clear ALL existing data and reseed the database.');
|
| 134 |
+
console.log(` Database: ${env.DB_NAME} (${env.MONGO_URI})\n`);
|
| 135 |
+
console.log(' This will:');
|
| 136 |
+
console.log(' - Delete all capabilities, personas, knowledge graph, and worlds');
|
| 137 |
+
console.log(' - Migrate 4 capabilities');
|
| 138 |
+
console.log(' - Migrate 5 personas');
|
| 139 |
+
console.log(' - Build and save knowledge graph (63 nodes, 80 edges)');
|
| 140 |
+
console.log(' - Create 5 sample worlds with sampling strategies\n');
|
| 141 |
+
|
| 142 |
+
const rl = readline.createInterface({
|
| 143 |
+
input: process.stdin,
|
| 144 |
+
output: process.stdout
|
| 145 |
+
});
|
| 146 |
+
|
| 147 |
+
return new Promise((resolve) => {
|
| 148 |
+
rl.question('Continue? (y/N): ', (answer) => {
|
| 149 |
+
rl.close();
|
| 150 |
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
| 151 |
+
});
|
| 152 |
+
});
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
/**
|
| 156 |
+
* Run a migration script
|
| 157 |
+
*/
|
| 158 |
+
async function runScript(scriptPath: string, args: string[] = []): Promise<void> {
|
| 159 |
+
return new Promise((resolve, reject) => {
|
| 160 |
+
const proc = spawn('bun', ['run', scriptPath, ...args], {
|
| 161 |
+
stdio: 'inherit',
|
| 162 |
+
cwd: process.cwd()
|
| 163 |
+
});
|
| 164 |
+
|
| 165 |
+
proc.on('close', (code) => {
|
| 166 |
+
if (code === 0) {
|
| 167 |
+
resolve();
|
| 168 |
+
} else {
|
| 169 |
+
reject(new Error(`Script ${scriptPath} exited with code ${code}`));
|
| 170 |
+
}
|
| 171 |
+
});
|
| 172 |
+
|
| 173 |
+
proc.on('error', (error) => {
|
| 174 |
+
reject(error);
|
| 175 |
+
});
|
| 176 |
+
});
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
/**
|
| 180 |
+
* Clear all collections
|
| 181 |
+
*/
|
| 182 |
+
async function clearAllData(): Promise<void> {
|
| 183 |
+
console.log('\n[seed-dev] Clearing existing data...');
|
| 184 |
+
|
| 185 |
+
await (KnowledgeGraphNode as any).deleteMany({}).exec();
|
| 186 |
+
await (KnowledgeGraphEdge as any).deleteMany({}).exec();
|
| 187 |
+
console.log(' β Cleared knowledge graph');
|
| 188 |
+
|
| 189 |
+
await (Persona as any).deleteMany({}).exec();
|
| 190 |
+
console.log(' β Cleared personas');
|
| 191 |
+
|
| 192 |
+
await (Capability as any).deleteMany({}).exec();
|
| 193 |
+
console.log(' β Cleared capabilities');
|
| 194 |
+
|
| 195 |
+
await (World as any).deleteMany({}).exec();
|
| 196 |
+
console.log(' β Cleared worlds');
|
| 197 |
+
|
| 198 |
+
console.log('[seed-dev] All data cleared\n');
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
/**
|
| 202 |
+
* Generate API credentials
|
| 203 |
+
*/
|
| 204 |
+
function generateApiKey(): string {
|
| 205 |
+
return `api_${crypto.randomBytes(16).toString('hex')}`;
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
function generateApiSecret(): string {
|
| 209 |
+
return crypto.randomBytes(32).toString('hex');
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
/**
|
| 213 |
+
* Create sample worlds with sampling strategies
|
| 214 |
+
*/
|
| 215 |
+
async function createSampleWorlds(): Promise<Array<{ name: string; capabilityCount: number }>> {
|
| 216 |
+
console.log('\n[seed-dev] Creating sample worlds with sampling strategies...\n');
|
| 217 |
+
|
| 218 |
+
// Initialize capability catalog (needed for sampling)
|
| 219 |
+
await capabilityCatalog.initialize();
|
| 220 |
+
|
| 221 |
+
const worldDetails: Array<{ name: string; capabilityCount: number }> = [];
|
| 222 |
+
|
| 223 |
+
for (const spec of SAMPLE_WORLD_SPECS) {
|
| 224 |
+
try {
|
| 225 |
+
// Apply sampling strategy to get capability IDs
|
| 226 |
+
const capabilityIds = capabilitySamplingService.applySamplingStrategy(
|
| 227 |
+
spec.samplingStrategy,
|
| 228 |
+
spec.personas
|
| 229 |
+
);
|
| 230 |
+
|
| 231 |
+
// Create world with sampled capabilities
|
| 232 |
+
const worldInput: TWorldInput = {
|
| 233 |
+
name: spec.name,
|
| 234 |
+
url: spec.url,
|
| 235 |
+
apiKey: generateApiKey(),
|
| 236 |
+
apiSecret: generateApiSecret(),
|
| 237 |
+
description: spec.description,
|
| 238 |
+
mpcCompany: spec.mpcCompany,
|
| 239 |
+
samplingStrategy: spec.samplingStrategy,
|
| 240 |
+
capabilityIds,
|
| 241 |
+
personas: spec.personas
|
| 242 |
+
};
|
| 243 |
+
|
| 244 |
+
const world = await WorldRepository.createWorld(worldInput);
|
| 245 |
+
|
| 246 |
+
const strategyDesc =
|
| 247 |
+
spec.samplingStrategy.type === 'all' ? 'ALL' :
|
| 248 |
+
spec.samplingStrategy.type === 'filter' ? 'FILTERED' :
|
| 249 |
+
spec.samplingStrategy.type === 'seeded' ? 'SEEDED' :
|
| 250 |
+
'RANDOM';
|
| 251 |
+
|
| 252 |
+
console.log(` β Created: ${world.name}`);
|
| 253 |
+
console.log(` Strategy: ${strategyDesc} (${capabilityIds.length} capabilities)`);
|
| 254 |
+
|
| 255 |
+
worldDetails.push({
|
| 256 |
+
name: world.name,
|
| 257 |
+
capabilityCount: capabilityIds.length
|
| 258 |
+
});
|
| 259 |
+
} catch (error) {
|
| 260 |
+
console.error(` β Failed to create world: ${spec.name}`);
|
| 261 |
+
console.error(` Error: ${getErrorMessage(error)}`);
|
| 262 |
+
throw error;
|
| 263 |
+
}
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
console.log('');
|
| 267 |
+
return worldDetails;
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
/**
|
| 271 |
+
* Validate seeded data
|
| 272 |
+
*/
|
| 273 |
+
async function validateData(skipWorlds: boolean): Promise<{
|
| 274 |
+
capabilities: number;
|
| 275 |
+
personas: number;
|
| 276 |
+
nodes: number;
|
| 277 |
+
edges: number;
|
| 278 |
+
worlds: number;
|
| 279 |
+
}> {
|
| 280 |
+
console.log('[seed-dev] Validating seeded data...\n');
|
| 281 |
+
|
| 282 |
+
const capCount = await (Capability as any).countDocuments().exec();
|
| 283 |
+
const personaCount = await (Persona as any).countDocuments().exec();
|
| 284 |
+
const nodeCount = await (KnowledgeGraphNode as any).countDocuments().exec();
|
| 285 |
+
const edgeCount = await (KnowledgeGraphEdge as any).countDocuments().exec();
|
| 286 |
+
const worldCount = await (World as any).countDocuments().exec();
|
| 287 |
+
|
| 288 |
+
console.log(` Capabilities: ${capCount} ${capCount === 4 ? 'β' : 'β'}`);
|
| 289 |
+
console.log(` Personas: ${personaCount} ${personaCount === 5 ? 'β' : 'β'}`);
|
| 290 |
+
console.log(` KG Nodes: ${nodeCount} ${nodeCount > 0 ? 'β' : 'β'}`);
|
| 291 |
+
console.log(` KG Edges: ${edgeCount} ${edgeCount > 0 ? 'β' : 'β'}`);
|
| 292 |
+
console.log(` Worlds: ${worldCount} ${skipWorlds || worldCount === 5 ? 'β' : 'β'}`);
|
| 293 |
+
console.log('');
|
| 294 |
+
|
| 295 |
+
if (capCount !== 4 || personaCount !== 5 || nodeCount === 0 || edgeCount === 0) {
|
| 296 |
+
throw new Error('Validation failed: Data counts do not match expected values');
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
if (!skipWorlds && worldCount !== 5) {
|
| 300 |
+
throw new Error('Validation failed: Expected 5 worlds but found ' + worldCount);
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
return {
|
| 304 |
+
capabilities: capCount,
|
| 305 |
+
personas: personaCount,
|
| 306 |
+
nodes: nodeCount,
|
| 307 |
+
edges: edgeCount,
|
| 308 |
+
worlds: worldCount
|
| 309 |
+
};
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
/**
|
| 313 |
+
* Main seeding function
|
| 314 |
+
*/
|
| 315 |
+
async function seedDevData(options: SeedOptions): Promise<SeedResult> {
|
| 316 |
+
const startTime = Date.now();
|
| 317 |
+
|
| 318 |
+
console.log('[seed-dev] Starting development data seeding...\n');
|
| 319 |
+
|
| 320 |
+
// Load environment
|
| 321 |
+
const env = loadEnv();
|
| 322 |
+
|
| 323 |
+
// Confirmation prompt (unless --no-confirm)
|
| 324 |
+
if (!options.noConfirm) {
|
| 325 |
+
const confirmed = await promptConfirmation(env);
|
| 326 |
+
if (!confirmed) {
|
| 327 |
+
console.log('\n[seed-dev] Seeding cancelled by user\n');
|
| 328 |
+
process.exit(0);
|
| 329 |
+
}
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
// Connect to MongoDB
|
| 333 |
+
await connectMongo({
|
| 334 |
+
uri: env.MONGO_URI,
|
| 335 |
+
dbName: env.DB_NAME,
|
| 336 |
+
log: false
|
| 337 |
+
});
|
| 338 |
+
|
| 339 |
+
// Ensure collections exist
|
| 340 |
+
await createCollectionsIfNotExist({
|
| 341 |
+
models: [World, Capability, Persona, KnowledgeGraphNode, KnowledgeGraphEdge],
|
| 342 |
+
log: false
|
| 343 |
+
});
|
| 344 |
+
|
| 345 |
+
// Clear existing data
|
| 346 |
+
await clearAllData();
|
| 347 |
+
|
| 348 |
+
// Run capability migration
|
| 349 |
+
console.log('[seed-dev] Running capability migration...');
|
| 350 |
+
await runScript('scripts/migrate-capabilities-to-db.ts', ['--clear-first']);
|
| 351 |
+
|
| 352 |
+
// Run persona migration
|
| 353 |
+
console.log('\n[seed-dev] Running persona migration...');
|
| 354 |
+
await runScript('scripts/migrate-personas-to-db.ts', ['--clear-first']);
|
| 355 |
+
|
| 356 |
+
// Create sample worlds (unless --skip-worlds)
|
| 357 |
+
let worldDetails: Array<{ name: string; capabilityCount: number }> = [];
|
| 358 |
+
if (!options.skipWorlds) {
|
| 359 |
+
worldDetails = await createSampleWorlds();
|
| 360 |
+
} else {
|
| 361 |
+
console.log('\n[seed-dev] Skipping world creation (--skip-worlds)\n');
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
// Run knowledge graph migration
|
| 365 |
+
console.log('[seed-dev] Running knowledge graph migration...');
|
| 366 |
+
await runScript('scripts/migrate-knowledge-graph-to-db.ts', ['--clear-first']);
|
| 367 |
+
|
| 368 |
+
// Validate data
|
| 369 |
+
const counts = await validateData(options.skipWorlds || false);
|
| 370 |
+
|
| 371 |
+
const duration = (Date.now() - startTime) / 1000;
|
| 372 |
+
|
| 373 |
+
return {
|
| 374 |
+
capabilities: counts.capabilities,
|
| 375 |
+
personas: counts.personas,
|
| 376 |
+
knowledgeGraphNodes: counts.nodes,
|
| 377 |
+
knowledgeGraphEdges: counts.edges,
|
| 378 |
+
worlds: counts.worlds,
|
| 379 |
+
worldDetails,
|
| 380 |
+
duration
|
| 381 |
+
};
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
/**
|
| 385 |
+
* Main execution
|
| 386 |
+
*/
|
| 387 |
+
async function main() {
|
| 388 |
+
// Parse command line arguments
|
| 389 |
+
const args = process.argv.slice(2);
|
| 390 |
+
const options: SeedOptions = {
|
| 391 |
+
noConfirm: args.includes('--no-confirm'),
|
| 392 |
+
skipWorlds: args.includes('--skip-worlds')
|
| 393 |
+
};
|
| 394 |
+
|
| 395 |
+
try {
|
| 396 |
+
const result = await seedDevData(options);
|
| 397 |
+
|
| 398 |
+
// Print summary
|
| 399 |
+
console.log(`${"=".repeat(60)}`);
|
| 400 |
+
console.log('Development Data Seeding Complete');
|
| 401 |
+
console.log(`${"=".repeat(60)}`);
|
| 402 |
+
console.log(` Capabilities: ${result.capabilities} migrated`);
|
| 403 |
+
console.log(` Personas: ${result.personas} migrated`);
|
| 404 |
+
console.log(` Knowledge Graph: ${result.knowledgeGraphNodes} nodes, ${result.knowledgeGraphEdges} edges`);
|
| 405 |
+
console.log(` Worlds: ${result.worlds} created`);
|
| 406 |
+
|
| 407 |
+
if (result.worldDetails.length > 0) {
|
| 408 |
+
result.worldDetails.forEach(w => {
|
| 409 |
+
const strategyType = SAMPLE_WORLD_SPECS.find(s => s.name === w.name)?.samplingStrategy.type || 'unknown';
|
| 410 |
+
const label = strategyType.toUpperCase();
|
| 411 |
+
console.log(` - ${w.name.padEnd(22)} ${label.padEnd(10)} (${w.capabilityCount} caps)`);
|
| 412 |
+
});
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
console.log(` Duration: ${result.duration.toFixed(1)}s`);
|
| 416 |
+
console.log(` Status: β
SUCCESS`);
|
| 417 |
+
console.log(`${"=".repeat(60)}\n`);
|
| 418 |
+
|
| 419 |
+
if (result.worldDetails.length > 0) {
|
| 420 |
+
console.log('π‘ Sample worlds demonstrate different sampling strategies:');
|
| 421 |
+
console.log(' - Use \'development-local\' for full access testing');
|
| 422 |
+
console.log(' - Use \'demo-showcase\' for reproducible demos (seeded)');
|
| 423 |
+
console.log(' - Use \'test-automation\' for integration tests\n');
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
console.log('[seed-dev] β
Development environment ready!\n');
|
| 427 |
+
process.exit(0);
|
| 428 |
+
} catch (error) {
|
| 429 |
+
console.error('\n[seed-dev] β Seeding failed:');
|
| 430 |
+
console.error(` ${getErrorMessage(error)}\n`);
|
| 431 |
+
process.exit(1);
|
| 432 |
+
}
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
// Execute main function
|
| 436 |
+
main();
|
packages/controlmart/scripts/validate-seed-data.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Quick validation script to check seeded data
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
import { connectMongo } from "../src/services/mongo.service";
|
| 6 |
+
import { Capability } from "../src/models/capability.model";
|
| 7 |
+
import { Persona } from "../src/models/persona.model";
|
| 8 |
+
import { KnowledgeGraphNode } from "../src/models/knowledge-graph-node.model";
|
| 9 |
+
import { KnowledgeGraphEdge } from "../src/models/knowledge-graph-edge.model";
|
| 10 |
+
import { World } from "../src/models/world.model";
|
| 11 |
+
import { loadEnv } from "../src/utils/env.util";
|
| 12 |
+
|
| 13 |
+
async function validate() {
|
| 14 |
+
const env = loadEnv();
|
| 15 |
+
|
| 16 |
+
await connectMongo({
|
| 17 |
+
uri: env.MONGO_URI,
|
| 18 |
+
dbName: env.DB_NAME,
|
| 19 |
+
log: false
|
| 20 |
+
});
|
| 21 |
+
|
| 22 |
+
console.log("=== Test 1 Validation ===\n");
|
| 23 |
+
|
| 24 |
+
const capCount = await (Capability as any).countDocuments().exec();
|
| 25 |
+
const personaCount = await (Persona as any).countDocuments().exec();
|
| 26 |
+
const nodeCount = await (KnowledgeGraphNode as any).countDocuments().exec();
|
| 27 |
+
const edgeCount = await (KnowledgeGraphEdge as any).countDocuments().exec();
|
| 28 |
+
const worldCount = await (World as any).countDocuments().exec();
|
| 29 |
+
|
| 30 |
+
console.log(`Capabilities: ${capCount} ${capCount === 4 ? 'β' : 'β'}`);
|
| 31 |
+
console.log(`Personas: ${personaCount} ${personaCount === 5 ? 'β' : 'β'}`);
|
| 32 |
+
console.log(`KG Nodes: ${nodeCount} ${nodeCount === 63 ? 'β' : 'β'}`);
|
| 33 |
+
console.log(`KG Edges: ${edgeCount} ${edgeCount === 80 ? 'β' : 'β'}`);
|
| 34 |
+
console.log(`Worlds: ${worldCount} ${worldCount === 0 ? 'β' : 'β'}`);
|
| 35 |
+
|
| 36 |
+
console.log("\n=== Sample Capability ===");
|
| 37 |
+
const sampleCap = await (Capability as any).findOne({}).select('id name domain').lean().exec();
|
| 38 |
+
console.log(JSON.stringify(sampleCap, null, 2));
|
| 39 |
+
|
| 40 |
+
console.log("\n=== Sample Persona ===");
|
| 41 |
+
const samplePersona = await (Persona as any).findOne({}).select('id name capabilityIds').lean().exec();
|
| 42 |
+
console.log(JSON.stringify(samplePersona, null, 2));
|
| 43 |
+
|
| 44 |
+
console.log("\n=== KG Node Types ===");
|
| 45 |
+
const nodeTypes = await (KnowledgeGraphNode as any).aggregate([
|
| 46 |
+
{ $group: { _id: '$type', count: { $sum: 1 } } },
|
| 47 |
+
{ $sort: { _id: 1 } }
|
| 48 |
+
]).exec();
|
| 49 |
+
console.log(JSON.stringify(nodeTypes, null, 2));
|
| 50 |
+
|
| 51 |
+
// Validate worlds if they exist
|
| 52 |
+
if (worldCount > 0) {
|
| 53 |
+
console.log("\n=== World Details ===");
|
| 54 |
+
const worlds = await (World as any)
|
| 55 |
+
.find({})
|
| 56 |
+
.select('name capabilityIds samplingStrategy personas.allowedPersonas apiKey mpcCompany')
|
| 57 |
+
.lean()
|
| 58 |
+
.exec();
|
| 59 |
+
|
| 60 |
+
for (const world of worlds) {
|
| 61 |
+
console.log(`\n${world.name}:`);
|
| 62 |
+
console.log(` Company: ${world.mpcCompany || 'N/A'}`);
|
| 63 |
+
console.log(` Strategy: ${world.samplingStrategy?.type?.toUpperCase() || 'N/A'}`);
|
| 64 |
+
console.log(` Capabilities: ${world.capabilityIds?.length || 0} - [${(world.capabilityIds || []).join(', ')}]`);
|
| 65 |
+
console.log(` Personas: ${world.personas?.allowedPersonas?.length || 0} - [${(world.personas?.allowedPersonas || []).join(', ')}]`);
|
| 66 |
+
console.log(` API Key: ${world.apiKey ? 'β Set' : 'β Missing'}`);
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
process.exit(0);
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
validate().catch(err => {
|
| 74 |
+
console.error("Validation error:", err);
|
| 75 |
+
process.exit(1);
|
| 76 |
+
});
|