Skip to content

Commit 9608ace

Browse files
jboldclaude
andcommitted
docs: add spec-kit specification artifacts for core runtime
Complete specification-driven design for the 001-core-runtime feature: - spec.md: 5 user stories (P1-P5), 23 functional requirements, 8 success criteria - plan.md: architecture, project structure, implementation phases - research.md: 12 technology decisions with rationale - data-model.md: 9 entity schemas with validation rules and relationships - contracts/jsonrpc-spec.md: WebSocket JSON-RPC protocol specification - quickstart.md: getting started guide - tasks.md: 55 implementation tasks ordered by user story priority - checklists/requirements.md: spec quality checklist (all passing) - .specify/: spec-kit framework (templates, scripts, constitution v1.0.0) - CLAUDE.md: rewritten with module relationships and spec artifact references Constitution establishes 5 core principles: Secure by Default, Cost-Aware by Architecture, Simple Configuration, WASM-First Plugin Model, Performance Without Compromise. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1af0702 commit 9608ace

20 files changed

Lines changed: 3886 additions & 77 deletions

.specify/memory/constitution.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<!-- Sync Impact Report
2+
Version change: 0.0.0 → 1.0.0
3+
Modified principles: N/A (initial ratification)
4+
Added sections: Core Principles (5), Security Model, Performance Standards, Development Workflow, Governance
5+
Removed sections: All template placeholders
6+
Templates requiring updates:
7+
- .specify/templates/plan-template.md ✅ (no changes needed, Constitution Check section is generic)
8+
- .specify/templates/spec-template.md ✅ (no changes needed, structure accommodates our principles)
9+
- .specify/templates/tasks-template.md ✅ (no changes needed, phase structure works)
10+
Follow-up TODOs: None
11+
-->
12+
13+
# Exoclaw Constitution
14+
15+
## Core Principles
16+
17+
### I. Secure by Default
18+
19+
Every external interaction — tools, channels, memory access, LLM calls — flows through a deny-by-default WASM capability boundary. Plugins cannot access the filesystem, network, host memory, or environment variables unless the host explicitly grants specific capabilities.
20+
21+
- Untrusted code (skills, tools, channel adapters) MUST run in WASM sandbox
22+
- Capabilities MUST be granted per-plugin via config-driven allowlists (e.g., `http:api.telegram.org`)
23+
- The host manages all persistent connections (WebSocket, SSE, long-polling); plugins handle discrete events only
24+
- Token authentication MUST use constant-time comparison
25+
- No plugin can bypass host-level metering, budgets, or security enforcement
26+
27+
### II. Cost-Aware by Architecture
28+
29+
Token spend is controlled through architectural design, not bolted-on limits. The memory engine retrieves relevant context (graph traversal + vector similarity) instead of dumping entire conversation history. Token metering lives in the trusted host layer where plugins cannot circumvent it.
30+
31+
- Context assembly MUST use selective retrieval (target 3-5K tokens per request, not 120K)
32+
- Token metering MUST be host-side, counting actual wire data to/from LLM APIs
33+
- Budgets MUST be configurable per-agent, per-session, per-day, per-month
34+
- No cron/heartbeat pattern that sends full context on a timer; scheduled tasks use specific, scoped prompts
35+
- LLM provider calls MUST be auditable (input tokens, output tokens, cost, timestamp logged)
36+
37+
### III. Simple Configuration
38+
39+
Configuration MUST be a single TOML file that a human can write from scratch in under 5 minutes for a basic setup. No config sprawl across multiple files, no wizard-only setup, no hidden state.
40+
41+
- Single config file: `~/.exoclaw/config.toml` (or `EXOCLAW_CONFIG` env var)
42+
- Sane defaults: loopback bind, no auth required for local, default agent model
43+
- Zero-config local mode: `exoclaw gateway` MUST work with no config file for development
44+
- Every config option MUST have a sensible default; only API keys and channel tokens are mandatory
45+
- Config schema MUST be documented in `examples/config.toml` with comments
46+
47+
### IV. WASM-First Plugin Model
48+
49+
All extensibility — channel adapters, tools, skills — ships as WASM modules (.wasm files). Plugins are language-agnostic (Rust, Go, JS, Python via Component Model), sandboxed by specification, and distributed as single files.
50+
51+
- Plugins MUST target `wasm32-unknown-unknown` or `wasm32-wasip2`
52+
- Plugin host is Extism (on Wasmtime); migration to raw Wasmtime Component Model when Extism adds support
53+
- Per-invocation plugin isolation: fresh WASM instance per call, no shared state between invocations
54+
- Host functions expose controlled APIs to plugins (session storage, HTTP proxy, etc.)
55+
- Plugin interfaces defined in the host; plugins implement `handle_message`, `handle_tool_call`, `describe`
56+
57+
### V. Performance Without Compromise
58+
59+
Exoclaw MUST be fast enough that users never wait on the runtime — only on LLM response time. Single static binary, sub-millisecond plugin instantiation, microsecond routing decisions, zero-copy where possible.
60+
61+
- Gateway MUST handle 10K+ concurrent WebSocket connections on commodity hardware
62+
- Plugin instantiation MUST complete in under 1ms (WASM cold start)
63+
- Session routing MUST complete in under 100 microseconds
64+
- Release binary MUST be a single static binary under 25MB (LTO + strip)
65+
- Memory usage MUST stay under 100MB for 1000 active sessions (excluding WASM instance memory)
66+
- Startup to first request MUST complete in under 500ms
67+
68+
## Security Model
69+
70+
**Trust boundary**: The WASM membrane separates trusted host code (Rust) from untrusted plugin code (WASM).
71+
72+
| Layer | Trust | Examples |
73+
|-------|-------|----------|
74+
| Host runtime | Trusted | Gateway, router, agent loop, memory engine, capability system |
75+
| WASM plugins | Untrusted | Channel adapters, tools, skills, community extensions |
76+
| LLM providers | External | Anthropic, OpenAI — host manages connections, plugins never see API keys |
77+
| User data | Protected | Conversation history, memory graph, config — host-only access |
78+
79+
Plugins interact with protected resources ONLY through host functions registered at instantiation. A plugin requesting a host function that wasn't granted fails at instantiation, not at runtime.
80+
81+
## Performance Standards
82+
83+
| Metric | Target | Measurement |
84+
|--------|--------|-------------|
85+
| Concurrent connections | 10,000+ | `wrk` or `k6` benchmark |
86+
| Plugin cold start | < 1ms | `tracing` span timing |
87+
| Route resolution | < 100us | `criterion` benchmark |
88+
| Memory per 1K sessions | < 100MB | `heaptrack` or RSS measurement |
89+
| Binary size (release) | < 25MB | `ls -la target/release/exoclaw` |
90+
| Startup to ready | < 500ms | Time from exec to first accepted connection |
91+
| Context tokens per request | 3-5K typical | Token counter in agent loop |
92+
93+
## Development Workflow
94+
95+
- `cargo check` for fast feedback during development
96+
- `cargo clippy` MUST pass with zero warnings (dead-code warnings excepted during scaffold phase)
97+
- `cargo fmt --check` MUST pass — canonical rustfmt style, zero config
98+
- `cargo test` MUST pass before any commit to main
99+
- All new public APIs MUST have at least one unit test
100+
- Integration tests for the WebSocket protocol use `tokio-test`
101+
- WASM plugins are tested by building to `wasm32-unknown-unknown` and calling via `PluginHost` in tests
102+
- Rust edition 2024 for all crates (main + plugins)
103+
104+
## Governance
105+
106+
This constitution governs all development decisions for exoclaw. Amendments require:
107+
108+
1. A written rationale explaining what changed and why
109+
2. Version bump following semver (MAJOR: principle removal/redefinition, MINOR: new principle/expansion, PATCH: clarification)
110+
3. Update to this file with the Sync Impact Report comment at top
111+
4. Propagation check across `.specify/templates/` for consistency
112+
113+
The constitution supersedes informal practices. If a development decision contradicts a principle, either change the code or amend the constitution — never leave them in conflict.
114+
115+
**Version**: 1.0.0 | **Ratified**: 2026-02-08 | **Last Amended**: 2026-02-08
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/usr/bin/env bash
2+
3+
# Consolidated prerequisite checking script
4+
#
5+
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
6+
# It replaces the functionality previously spread across multiple scripts.
7+
#
8+
# Usage: ./check-prerequisites.sh [OPTIONS]
9+
#
10+
# OPTIONS:
11+
# --json Output in JSON format
12+
# --require-tasks Require tasks.md to exist (for implementation phase)
13+
# --include-tasks Include tasks.md in AVAILABLE_DOCS list
14+
# --paths-only Only output path variables (no validation)
15+
# --help, -h Show help message
16+
#
17+
# OUTPUTS:
18+
# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
19+
# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
20+
# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.
21+
22+
set -e
23+
24+
# Parse command line arguments
25+
JSON_MODE=false
26+
REQUIRE_TASKS=false
27+
INCLUDE_TASKS=false
28+
PATHS_ONLY=false
29+
30+
for arg in "$@"; do
31+
case "$arg" in
32+
--json)
33+
JSON_MODE=true
34+
;;
35+
--require-tasks)
36+
REQUIRE_TASKS=true
37+
;;
38+
--include-tasks)
39+
INCLUDE_TASKS=true
40+
;;
41+
--paths-only)
42+
PATHS_ONLY=true
43+
;;
44+
--help|-h)
45+
cat << 'EOF'
46+
Usage: check-prerequisites.sh [OPTIONS]
47+
48+
Consolidated prerequisite checking for Spec-Driven Development workflow.
49+
50+
OPTIONS:
51+
--json Output in JSON format
52+
--require-tasks Require tasks.md to exist (for implementation phase)
53+
--include-tasks Include tasks.md in AVAILABLE_DOCS list
54+
--paths-only Only output path variables (no prerequisite validation)
55+
--help, -h Show this help message
56+
57+
EXAMPLES:
58+
# Check task prerequisites (plan.md required)
59+
./check-prerequisites.sh --json
60+
61+
# Check implementation prerequisites (plan.md + tasks.md required)
62+
./check-prerequisites.sh --json --require-tasks --include-tasks
63+
64+
# Get feature paths only (no validation)
65+
./check-prerequisites.sh --paths-only
66+
67+
EOF
68+
exit 0
69+
;;
70+
*)
71+
echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
72+
exit 1
73+
;;
74+
esac
75+
done
76+
77+
# Source common functions
78+
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
79+
source "$SCRIPT_DIR/common.sh"
80+
81+
# Get feature paths and validate branch
82+
eval $(get_feature_paths)
83+
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
84+
85+
# If paths-only mode, output paths and exit (support JSON + paths-only combined)
86+
if $PATHS_ONLY; then
87+
if $JSON_MODE; then
88+
# Minimal JSON paths payload (no validation performed)
89+
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
90+
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
91+
else
92+
echo "REPO_ROOT: $REPO_ROOT"
93+
echo "BRANCH: $CURRENT_BRANCH"
94+
echo "FEATURE_DIR: $FEATURE_DIR"
95+
echo "FEATURE_SPEC: $FEATURE_SPEC"
96+
echo "IMPL_PLAN: $IMPL_PLAN"
97+
echo "TASKS: $TASKS"
98+
fi
99+
exit 0
100+
fi
101+
102+
# Validate required directories and files
103+
if [[ ! -d "$FEATURE_DIR" ]]; then
104+
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
105+
echo "Run /speckit.specify first to create the feature structure." >&2
106+
exit 1
107+
fi
108+
109+
if [[ ! -f "$IMPL_PLAN" ]]; then
110+
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
111+
echo "Run /speckit.plan first to create the implementation plan." >&2
112+
exit 1
113+
fi
114+
115+
# Check for tasks.md if required
116+
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
117+
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
118+
echo "Run /speckit.tasks first to create the task list." >&2
119+
exit 1
120+
fi
121+
122+
# Build list of available documents
123+
docs=()
124+
125+
# Always check these optional docs
126+
[[ -f "$RESEARCH" ]] && docs+=("research.md")
127+
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")
128+
129+
# Check contracts directory (only if it exists and has files)
130+
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
131+
docs+=("contracts/")
132+
fi
133+
134+
[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
135+
136+
# Include tasks.md if requested and it exists
137+
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
138+
docs+=("tasks.md")
139+
fi
140+
141+
# Output results
142+
if $JSON_MODE; then
143+
# Build JSON array of documents
144+
if [[ ${#docs[@]} -eq 0 ]]; then
145+
json_docs="[]"
146+
else
147+
json_docs=$(printf '"%s",' "${docs[@]}")
148+
json_docs="[${json_docs%,}]"
149+
fi
150+
151+
printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
152+
else
153+
# Text output
154+
echo "FEATURE_DIR:$FEATURE_DIR"
155+
echo "AVAILABLE_DOCS:"
156+
157+
# Show status of each potential document
158+
check_file "$RESEARCH" "research.md"
159+
check_file "$DATA_MODEL" "data-model.md"
160+
check_dir "$CONTRACTS_DIR" "contracts/"
161+
check_file "$QUICKSTART" "quickstart.md"
162+
163+
if $INCLUDE_TASKS; then
164+
check_file "$TASKS" "tasks.md"
165+
fi
166+
fi

0 commit comments

Comments
 (0)