diff --git a/.github/workflows/spec-registry-validation.yml b/.github/workflows/spec-registry-validation.yml
new file mode 100644
index 0000000..8731e81
--- /dev/null
+++ b/.github/workflows/spec-registry-validation.yml
@@ -0,0 +1,43 @@
+name: Spec Registry Validation
+
+on:
+ pull_request:
+ paths:
+ - 'specs/**'
+ - 'docs/ARCHITECTURE_REGISTRY.md'
+ - '.github/workflows/spec-registry-validation.yml'
+ - 'package.json'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ validate-registry:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: npm
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Validate specs
+ run: npm run specs:validate
+
+ - name: Build registry index
+ run: npm run specs:index
+
+ - name: Generate architecture docs
+ run: npm run specs:docs
+
+ - name: Check generated artifacts are committed
+ run: |
+ git diff --exit-code -- specs/registries/index.json docs/ARCHITECTURE_REGISTRY.md
diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts
index 0b6cffe..602cc44 100644
--- a/app/api/chat/route.ts
+++ b/app/api/chat/route.ts
@@ -1,12 +1,39 @@
import { groq } from "@ai-sdk/groq"
import { streamText, convertToCoreMessages } from "ai"
import { awardTokens, saveConversation } from "@/lib/db"
+import { z } from "zod"
+
+const ChatRequestSchema = z.object({
+ messages: z.array(z.object({
+ role: z.enum(["user", "assistant"]),
+ content: z.string().min(1),
+ })).min(1),
+ userId: z.string().optional(),
+ sessionId: z.string().optional(),
+ orchestration: z.object({
+ mode: z.enum(["visual-chat", "realtime-collaboration", "agent-loop"]).default("visual-chat"),
+ interfaceProfile: z.enum(["vr4deaf", "vuri-ai"]).default("vr4deaf"),
+ collaboration: z.boolean().default(false),
+ loopSchedule: z.enum(["single", "5m", "15m"]).default("single"),
+ ragResearchFocus: z.boolean().default(true),
+ }).optional(),
+})
export const maxDuration = 30
export async function POST(req: Request) {
try {
- const { messages, userId, sessionId } = await req.json()
+ const payload = ChatRequestSchema.parse(await req.json())
+ const { messages, userId, sessionId, orchestration } = payload
+
+ const orchestrationPrompt = orchestration
+ ? `\n\n๐งญ Active session mode:
+- Mode: ${orchestration.mode}
+- Interface profile: ${orchestration.interfaceProfile}
+- Collaboration layer: ${orchestration.collaboration ? "enabled" : "disabled"}
+- Loop schedule: ${orchestration.loopSchedule}
+- Deaf-first RAG research focus: ${orchestration.ragResearchFocus ? "enabled" : "disabled"}`
+ : ""
// Save conversation to Neon
if (userId && sessionId) {
@@ -15,7 +42,7 @@ export async function POST(req: Request) {
const result = await streamText({
model: groq("llama-3.1-70b-versatile"),
- messages: convertToCoreMessages(messages),
+ messages: convertToCoreMessages(messages as any),
system: `You are PINKY AI, a specialized assistant for sign language interpretation and accessibility.
๐ฏ Your expertise includes:
@@ -42,7 +69,9 @@ export async function POST(req: Request) {
- Encourage participation in the Sign-to-Earn ecosystem
- Mention token rewards when appropriate
-Always be inclusive, respectful, and focused on advancing accessibility through AI.`,
+Always be inclusive, respectful, and focused on advancing accessibility through AI.
+
+Prioritize Deaf-first initiatives, practical implementation guidance, and concise, operationally useful answers.${orchestrationPrompt}`,
onFinish: async (result) => {
// Award tokens for interaction
if (userId) {
@@ -51,7 +80,7 @@ Always be inclusive, respectful, and focused on advancing accessibility through
},
})
- return result.toDataStreamResponse()
+ return (result as any).toDataStreamResponse()
} catch (error) {
console.error("Chat API error:", error)
return new Response("Internal Server Error", { status: 500 })
diff --git a/app/api/health/route.ts b/app/api/health/route.ts
index 95fa9f0..cbe3a59 100644
--- a/app/api/health/route.ts
+++ b/app/api/health/route.ts
@@ -1,8 +1,10 @@
import { NextResponse } from 'next/server'
+import { PLATFORM_VERSION, PLATFORM_LABELS } from '@/lib/platform'
interface HealthStatus {
status: 'healthy' | 'degraded' | 'unhealthy'
version: string
+ labels: string[]
timestamp: string
uptime: number
services: {
@@ -18,7 +20,8 @@ const startTime = Date.now()
export async function GET(): Promise> {
const status: HealthStatus = {
status: 'healthy',
- version: '2.0.0',
+ version: PLATFORM_VERSION,
+ labels: [...PLATFORM_LABELS],
timestamp: new Date().toISOString(),
uptime: Math.floor((Date.now() - startTime) / 1000),
services: {
diff --git a/app/chat/page.tsx b/app/chat/page.tsx
index 9ed2bd2..c525334 100644
--- a/app/chat/page.tsx
+++ b/app/chat/page.tsx
@@ -1,7 +1,7 @@
"use client"
import type React from "react"
-import { useState, useRef } from "react"
+import { useState, useRef, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
@@ -16,6 +16,15 @@ interface Message {
content: string
}
+type ChatMode = "visual-chat" | "realtime-collaboration" | "agent-loop"
+type LoopSchedule = "single" | "5m" | "15m"
+type InterfaceProfile = "vr4deaf" | "vuri-ai"
+
+interface HealthStatus {
+ version: string
+ labels?: string[]
+}
+
// Generate unique ID with fallback
function generateId(): string {
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
@@ -37,6 +46,27 @@ export default function ChatPage() {
const [messages, setMessages] = useState([])
const [input, setInput] = useState('')
const [isLoading, setIsLoading] = useState(false)
+ const [chatMode, setChatMode] = useState("visual-chat")
+ const [enableCollaboration, setEnableCollaboration] = useState(false)
+ const [loopSchedule, setLoopSchedule] = useState("single")
+ const [ragResearchFocus, setRagResearchFocus] = useState(true)
+ const [interfaceProfile, setInterfaceProfile] = useState("vr4deaf")
+ const [health, setHealth] = useState(null)
+
+ useEffect(() => {
+ const fetchHealth = async () => {
+ try {
+ const response = await fetch("/api/health")
+ if (!response.ok) return
+ const result = await response.json() as HealthStatus
+ setHealth(result)
+ } catch {
+ // no-op
+ }
+ }
+
+ fetchHealth()
+ }, [])
const handleInputChange = (e: React.ChangeEvent) => {
setInput(e.target.value)
@@ -64,6 +94,13 @@ export default function ChatPage() {
messages: [...messages, userMessage].map(m => ({ role: m.role, content: m.content })),
userId: user?.id,
sessionId: sessionId,
+ orchestration: {
+ mode: chatMode,
+ interfaceProfile,
+ collaboration: enableCollaboration,
+ loopSchedule,
+ ragResearchFocus,
+ },
}),
})
@@ -161,6 +198,87 @@ export default function ChatPage() {
+
+
+ Visual Chat Entry Point
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Workflow Steps
+
+ - Ingest visual/sign input or text request
+ - Run Deaf-first analysis and context retrieval
+ - Route through selected org visual panel profile
+ - Generate response with collaboration/operator alignment
+ - Loop per selected schedule when enabled
+
+
+
+ Version: {health?.version ?? "unknown"} ยท Labels: {(health?.labels?.join(", ") ?? "vr4deaf, deafauth, pinksync")}
+
+
+
+
diff --git a/docs/ARCHITECTURE_REGISTRY.md b/docs/ARCHITECTURE_REGISTRY.md
new file mode 100644
index 0000000..114bc1e
--- /dev/null
+++ b/docs/ARCHITECTURE_REGISTRY.md
@@ -0,0 +1,32 @@
+# MBTQ Studio Registry Architecture
+
+Generated from `specs/` at 2026-08-03T01:18:10.596Z.
+
+## Registry Summary
+- Version: 1.0.0
+- Total specs: 7
+
+## Specs by Type
+- agent.spec: 1
+- dispatch.spec: 1
+- magician.spec: 1
+- provider.spec: 1
+- runtime.spec: 1
+- service.spec: 1
+- workflow.spec: 1
+
+## Specification Inventory
+
+| ID | Type | Version | Lifecycle | Owner | Path |
+|---|---|---|---|---|---|
+| agent.spec.auditor | agent.spec | 0.1.0 | draft | MBTQ Core Team | `specs/agents/spec-auditor.agent.spec.json` |
+| dispatch.spec.router | dispatch.spec | 0.1.0 | draft | MBTQ Core Team | `specs/dispatch/spec-dispatch.dispatch.spec.json` |
+| magician.developer | magician.spec | 0.1.0 | draft | MBTQ Core Team | `specs/magicians/developer-magician.magician.spec.json` |
+| provider.github-actions | provider.spec | 0.1.0 | draft | MBTQ Core Team | `specs/providers/github-actions.provider.spec.json` |
+| runtime.multi-framework | runtime.spec | 0.1.0 | draft | MBTQ Core Team | `specs/runtimes/multi-runtime.runtime.spec.json` |
+| svc.registry.foundation | service.spec | 0.1.0 | draft | MBTQ Core Team | `specs/services/foundation-registry.service.spec.json` |
+| workflow.spec-governance | workflow.spec | 0.1.0 | draft | MBTQ Core Team | `specs/workflows/spec-governance.workflow.spec.json` |
+
+## Runtime Compatibility
+
+Framework-agnostic support targets are encoded in every spec runtime.supported array, including FastAPI, Deno, and Python workers.
diff --git a/docs/INDEX.md b/docs/INDEX.md
new file mode 100644
index 0000000..be810cf
--- /dev/null
+++ b/docs/INDEX.md
@@ -0,0 +1,58 @@
+# Deaf First Platform Knowledge Hub
+
+## Vision
+- Mission: Build Deaf-first, accessibility-first AI products
+- User journeys: creators, organizations, developers, and end users
+- Ecosystem: web platform, AI tooling, and deployment infrastructure
+
+## Platform
+- Architecture: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md`
+- Service registry: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/services.yaml`
+- APIs registry: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/APIs.yaml`
+
+## AI
+- PinkyAI documentation strategy and governance
+- Agent/workflow inventory: `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/workflows.yaml`
+- Structured metadata for automation in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/registry/`
+
+## Applications
+- Business Magician (planned)
+- Job Magician (planned)
+- Developer Magician (planned)
+- SignLanguageAssistant (prototype bundle in `SignLanguageAssistant/`)
+
+## Operations
+- CI/CD workflows in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/`
+- Dependency automation in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/dependabot.yml`
+- Deployment references in `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/DEPLOYMENT.md`
+
+## Documentation Inventory and Audit Status
+
+| Path | Type | Status | Notes |
+|---|---|---|---|
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/README.md` | Root overview | UPDATE | Strong summary, but contains legacy sections and mixed source-of-truth signals. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/API.md` | API doc | UPDATE | Useful intent, but endpoint host/contracts appear placeholder and need alignment with current app routes. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/CONTRIBUTING.md` | Contributor guide | UPDATE | Good structure, but references old repo names/contacts and needs normalization. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/DEPLOYMENT.md` | Deployment guide | UPDATE | Valuable checklist, but includes mixed targets and environment examples needing validation. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md` | Architecture/stack policy | KEEP | Primary architecture intent and standards baseline; should remain canonical after cleanup passes. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/mbtq_architecture.html` | Legacy architecture artifact | ARCHIVE | Historical artifact; retain for reference only, not active source-of-truth. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/templates/README.md` | Template documentation | KEEP | Active template catalog and onboarding for template users. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/README.md` | Prototype overview | ARCHIVE | Rich but prototype-heavy; overlaps with architecture and implementation docs. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/ARCHITECTURE.md` | Prototype architecture | MERGE | Keep key ideas, merge reusable architecture parts into central platform architecture docs. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/IMPLEMENTATION_SUMMARY.md` | Implementation snapshot | ARCHIVE | Session/date-bound status report; historical context only. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/QUICKSTART.md` | Prototype setup guide | MERGE | Merge practical setup steps into maintained platform onboarding docs. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/NEXTJS_INTEGRATION.md` | Integration guide | MERGE | Merge stable integration patterns into `docs/API.md` + platform docs to avoid drift. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/dependabot.yml` | Automation config | UPDATE | Keep automation but update directories and ecosystem paths to match actual repo layout. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/issue-labled.yml` | Workflow | KEEP | Active issue triage helper workflow. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/jekyll-gh-pages.yml` | Workflow | ARCHIVE | Sample Pages workflow; archive unless GitHub Pages publishing is actively used. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/mbtq-wcag-check.yml` | Workflow | UPDATE | Important accessibility workflow; currently requires syntax/trigger hardening. |
+| `/home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/pinkflow.yml` | Workflow | ARCHIVE | Empty placeholder file; archive or replace with real automation definition. |
+
+## Next Documentation Governance Loop
+
+GitHub Change
+โ PinkyAI Review
+โ Update docs
+โ Consistency check
+โ Pull Request
+
diff --git a/docs/registry/APIs.yaml b/docs/registry/APIs.yaml
new file mode 100644
index 0000000..0fbef59
--- /dev/null
+++ b/docs/registry/APIs.yaml
@@ -0,0 +1,39 @@
+version: 1
+updated_at: "2026-08-02"
+apis:
+ - id: platform-api-doc
+ name: Platform API (documented)
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/API.md
+ kind: reference-doc
+ status: update
+ note: Host, auth examples, and endpoint contracts require verification against implementation.
+
+ - id: nextjs-api-auth
+ name: Next.js Auth API Routes
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app/api/auth
+ kind: implementation
+ status: keep
+
+ - id: nextjs-api-chat
+ name: Next.js Chat API Routes
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app/api/chat
+ kind: implementation
+ status: keep
+
+ - id: nextjs-api-health
+ name: Next.js Health API Routes
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app/api/health
+ kind: implementation
+ status: keep
+
+ - id: nextjs-api-rss
+ name: Next.js RSS API Routes
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app/api/rss
+ kind: implementation
+ status: keep
+
+ - id: nextjs-api-upload
+ name: Next.js Upload API Routes
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app/api/upload
+ kind: implementation
+ status: keep
diff --git a/docs/registry/apps.yaml b/docs/registry/apps.yaml
new file mode 100644
index 0000000..54cf099
--- /dev/null
+++ b/docs/registry/apps.yaml
@@ -0,0 +1,35 @@
+version: 1
+updated_at: "2026-08-02"
+apps:
+ - id: business-magician
+ name: Business Magician
+ category: application
+ lifecycle: planned
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/INDEX.md
+
+ - id: job-magician
+ name: Job Magician
+ category: application
+ lifecycle: planned
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/INDEX.md
+
+ - id: developer-magician
+ name: Developer Magician
+ category: application
+ lifecycle: planned
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/INDEX.md
+
+ - id: sign-language-assistant
+ name: SignLanguageAssistant
+ category: prototype
+ lifecycle: prototype
+ status: archive
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/README.md
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/SignLanguageAssistant/ARCHITECTURE.md
diff --git a/docs/registry/services.yaml b/docs/registry/services.yaml
new file mode 100644
index 0000000..8a2b307
--- /dev/null
+++ b/docs/registry/services.yaml
@@ -0,0 +1,52 @@
+version: 1
+updated_at: "2026-08-02"
+services:
+ - id: platform-web
+ name: ai.mbtq.dev web platform
+ type: application-service
+ implementation:
+ stack: Next.js
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/app
+ status: keep
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/README.md
+
+ - id: deafauth
+ name: DeafAUTH Identity Management
+ type: microservice
+ implementation:
+ stack: Next.js + Better Auth
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/services/deafauth
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md
+
+ - id: pinksync
+ name: PinkSync Provisioning
+ type: microservice
+ implementation:
+ stack: Node.js + Fastify
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/services/pinksync
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md
+
+ - id: accessibility-nodes
+ name: Accessibility Node Runtime
+ type: client-runtime
+ implementation:
+ stack: React + Next.js
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/services/accessibility-nodes
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md
+
+ - id: fibonrose
+ name: Fibonrose Reputation and Logging
+ type: data-service
+ implementation:
+ stack: Next.js + Cassandra + ChromaDB
+ path: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/services/fibonrose
+ status: update
+ source_of_truth:
+ - /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/docs/singlesource.md
diff --git a/docs/registry/workflows.yaml b/docs/registry/workflows.yaml
new file mode 100644
index 0000000..7f56342
--- /dev/null
+++ b/docs/registry/workflows.yaml
@@ -0,0 +1,42 @@
+version: 1
+updated_at: "2026-08-02"
+workflows:
+ - id: issue-labeled
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/issue-labled.yml
+ purpose: Auto-comment and relabel issues when specific labels are applied
+ trigger:
+ - issues:labeled
+ status: keep
+
+ - id: jekyll-gh-pages
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/jekyll-gh-pages.yml
+ purpose: Build and deploy Jekyll site to GitHub Pages
+ trigger:
+ - push:main
+ - workflow_dispatch
+ status: archive
+
+ - id: mbtq-wcag-check
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/mbtq-wcag-check.yml
+ purpose: Accessibility/WCAG compliance validation
+ trigger:
+ - push
+ - pull_request
+ - workflow_dispatch
+ status: update
+ note: Workflow currently has syntax/branch filter issues and needs hardening.
+
+ - id: pinkflow
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/workflows/pinkflow.yml
+ purpose: Reserved for PinkyAI documentation automation
+ trigger: []
+ status: archive
+
+ - id: dependabot
+ file: /home/runner/work/ai.mbtq.dev/ai.mbtq.dev/.github/dependabot.yml
+ purpose: Automated dependency update PRs
+ trigger:
+ - schedule:daily
+ - schedule:weekly
+ status: update
+ note: Config directories should be aligned to actual repository package locations.
diff --git a/lib/platform.ts b/lib/platform.ts
new file mode 100644
index 0000000..189bbca
--- /dev/null
+++ b/lib/platform.ts
@@ -0,0 +1,5 @@
+import packageJson from "@/package.json"
+
+export const PLATFORM_VERSION = packageJson.version
+
+export const PLATFORM_LABELS = ["vr4deaf", "vuri-ai", "deafauth", "pinksync"] as const
diff --git a/package.json b/package.json
index c740065..f7f3b4d 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,10 @@
"cli": "node cli/launcher.mjs",
"docker:build": "docker build -t mbtq-ai-platform .",
"docker:run": "docker-compose up -d",
- "docker:stop": "docker-compose down"
+ "docker:stop": "docker-compose down",
+ "specs:validate": "node specs/registries/scripts/validate-specs.mjs",
+ "specs:index": "node specs/registries/scripts/build-index.mjs",
+ "specs:docs": "node specs/registries/scripts/generate-architecture-docs.mjs"
},
"dependencies": {
"@ai-sdk/groq": "latest",
diff --git a/specs/agents/spec-auditor.agent.spec.json b/specs/agents/spec-auditor.agent.spec.json
new file mode 100644
index 0000000..6a9c985
--- /dev/null
+++ b/specs/agents/spec-auditor.agent.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "agent.spec",
+ "id": "agent.spec.auditor",
+ "name": "Spec Auditor Agent",
+ "version": "0.1.0",
+ "description": "Validates structural integrity of MBTQ specifications in pull requests.",
+ "inputs": [
+ {
+ "name": "specFiles",
+ "type": "array",
+ "required": true,
+ "description": "Specification files detected in repository."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "validationReport",
+ "type": "report.json",
+ "description": "Validation result summary per spec file."
+ }
+ ],
+ "dependencies": ["svc.registry.foundation"],
+ "eventsProduced": ["spec.validation.completed"],
+ "eventsConsumed": ["spec.change.requested"],
+ "runtime": {
+ "primary": "python-worker",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["read-only-execution", "audit-logging"],
+ "permissions": ["contents:read"],
+ "healthChecks": [
+ {
+ "name": "agent-ready",
+ "method": "event",
+ "target": "agent.heartbeat",
+ "intervalSeconds": 60
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["agent", "validation", "governance"]
+}
diff --git a/specs/dispatch/spec-dispatch.dispatch.spec.json b/specs/dispatch/spec-dispatch.dispatch.spec.json
new file mode 100644
index 0000000..23b8207
--- /dev/null
+++ b/specs/dispatch/spec-dispatch.dispatch.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "dispatch.spec",
+ "id": "dispatch.spec.router",
+ "name": "Spec Dispatch Router",
+ "version": "0.1.0",
+ "description": "Routes specification change events to validation and indexing workflows.",
+ "inputs": [
+ {
+ "name": "event",
+ "type": "spec.change.requested",
+ "required": true,
+ "description": "Incoming event requesting spec processing."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "dispatchDecision",
+ "type": "dispatch.route",
+ "description": "Routing decision for downstream handlers."
+ }
+ ],
+ "dependencies": ["workflow.spec-governance"],
+ "eventsProduced": ["dispatch.spec.routed"],
+ "eventsConsumed": ["spec.change.requested"],
+ "runtime": {
+ "primary": "deno",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["input-signature-verification"],
+ "permissions": ["events:read", "events:write"],
+ "healthChecks": [
+ {
+ "name": "dispatch-loop",
+ "method": "event",
+ "target": "dispatch.spec.routed",
+ "intervalSeconds": 60
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["dispatch", "routing", "events"]
+}
diff --git a/specs/events/.gitkeep b/specs/events/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/specs/magicians/developer-magician.magician.spec.json b/specs/magicians/developer-magician.magician.spec.json
new file mode 100644
index 0000000..d20fb5c
--- /dev/null
+++ b/specs/magicians/developer-magician.magician.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "magician.spec",
+ "id": "magician.developer",
+ "name": "Developer Magician",
+ "version": "0.1.0",
+ "description": "Registry-defined agent profile for developer workflow orchestration.",
+ "inputs": [
+ {
+ "name": "taskRequest",
+ "type": "task.request",
+ "required": true,
+ "description": "Developer task request payload."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "taskPlan",
+ "type": "task.plan",
+ "description": "Generated execution plan for developer workflows."
+ }
+ ],
+ "dependencies": ["agent.spec.auditor", "dispatch.spec.router"],
+ "eventsProduced": ["magician.task.planned"],
+ "eventsConsumed": ["task.requested"],
+ "runtime": {
+ "primary": "fastapi",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["role-based-access-control", "action-audit-log"],
+ "permissions": ["tasks:read", "tasks:write"],
+ "healthChecks": [
+ {
+ "name": "planner-ready",
+ "method": "http",
+ "target": "/healthz",
+ "intervalSeconds": 30
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["magician", "developer", "orchestration"]
+}
diff --git a/specs/policies/.gitkeep b/specs/policies/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/specs/providers/github-actions.provider.spec.json b/specs/providers/github-actions.provider.spec.json
new file mode 100644
index 0000000..13fc1e0
--- /dev/null
+++ b/specs/providers/github-actions.provider.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "provider.spec",
+ "id": "provider.github-actions",
+ "name": "GitHub Actions Provider",
+ "version": "0.1.0",
+ "description": "Provider contract for pull request validation and registry automation.",
+ "inputs": [
+ {
+ "name": "workflowEvent",
+ "type": "github.event",
+ "required": true,
+ "description": "GitHub workflow event context."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "workflowRun",
+ "type": "github.workflow_run",
+ "description": "Execution result and artifacts from workflow run."
+ }
+ ],
+ "dependencies": ["workflow.spec-governance"],
+ "eventsProduced": ["provider.workflow.completed"],
+ "eventsConsumed": ["spec.change.requested"],
+ "runtime": {
+ "primary": "github-actions",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["ephemeral-credentials", "oidc-token-use"],
+ "permissions": ["contents:read"],
+ "healthChecks": [
+ {
+ "name": "runner-availability",
+ "method": "provider",
+ "target": "github-actions",
+ "intervalSeconds": 0
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["provider", "ci", "github"]
+}
diff --git a/specs/registries/index.json b/specs/registries/index.json
new file mode 100644
index 0000000..0352248
--- /dev/null
+++ b/specs/registries/index.json
@@ -0,0 +1,214 @@
+{
+ "version": "1.0.0",
+ "generatedAt": "2026-08-03T01:18:10.596Z",
+ "totalSpecs": 7,
+ "byType": {
+ "agent.spec": [
+ "agent.spec.auditor"
+ ],
+ "dispatch.spec": [
+ "dispatch.spec.router"
+ ],
+ "magician.spec": [
+ "magician.developer"
+ ],
+ "provider.spec": [
+ "provider.github-actions"
+ ],
+ "runtime.spec": [
+ "runtime.multi-framework"
+ ],
+ "service.spec": [
+ "svc.registry.foundation"
+ ],
+ "workflow.spec": [
+ "workflow.spec-governance"
+ ]
+ },
+ "specs": [
+ {
+ "id": "agent.spec.auditor",
+ "specType": "agent.spec",
+ "name": "Spec Auditor Agent",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/agents/spec-auditor.agent.spec.json",
+ "dependencies": [
+ "svc.registry.foundation"
+ ],
+ "runtime": {
+ "primary": "python-worker",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "agent",
+ "validation",
+ "governance"
+ ]
+ },
+ {
+ "id": "dispatch.spec.router",
+ "specType": "dispatch.spec",
+ "name": "Spec Dispatch Router",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/dispatch/spec-dispatch.dispatch.spec.json",
+ "dependencies": [
+ "workflow.spec-governance"
+ ],
+ "runtime": {
+ "primary": "deno",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "dispatch",
+ "routing",
+ "events"
+ ]
+ },
+ {
+ "id": "magician.developer",
+ "specType": "magician.spec",
+ "name": "Developer Magician",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/magicians/developer-magician.magician.spec.json",
+ "dependencies": [
+ "agent.spec.auditor",
+ "dispatch.spec.router"
+ ],
+ "runtime": {
+ "primary": "fastapi",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "magician",
+ "developer",
+ "orchestration"
+ ]
+ },
+ {
+ "id": "provider.github-actions",
+ "specType": "provider.spec",
+ "name": "GitHub Actions Provider",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/providers/github-actions.provider.spec.json",
+ "dependencies": [
+ "workflow.spec-governance"
+ ],
+ "runtime": {
+ "primary": "github-actions",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "provider",
+ "ci",
+ "github"
+ ]
+ },
+ {
+ "id": "runtime.multi-framework",
+ "specType": "runtime.spec",
+ "name": "Multi-Runtime Compatibility Contract",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/runtimes/multi-runtime.runtime.spec.json",
+ "dependencies": [],
+ "runtime": {
+ "primary": "agnostic",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs",
+ "future-runtime"
+ ]
+ },
+ "tags": [
+ "runtime",
+ "agnostic",
+ "compatibility"
+ ]
+ },
+ {
+ "id": "svc.registry.foundation",
+ "specType": "service.spec",
+ "name": "Registry Foundation Service",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/services/foundation-registry.service.spec.json",
+ "dependencies": [
+ "provider.github-actions",
+ "workflow.spec-governance"
+ ],
+ "runtime": {
+ "primary": "nodejs",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "registry",
+ "foundation",
+ "architecture"
+ ]
+ },
+ {
+ "id": "workflow.spec-governance",
+ "specType": "workflow.spec",
+ "name": "Spec Governance Workflow",
+ "version": "0.1.0",
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "path": "specs/workflows/spec-governance.workflow.spec.json",
+ "dependencies": [
+ "agent.spec.auditor",
+ "provider.github-actions"
+ ],
+ "runtime": {
+ "primary": "github-actions",
+ "supported": [
+ "fastapi",
+ "deno",
+ "python-worker",
+ "nodejs"
+ ]
+ },
+ "tags": [
+ "workflow",
+ "registry",
+ "ci"
+ ]
+ }
+ ]
+}
diff --git a/specs/registries/schemas/agent.spec.schema.json b/specs/registries/schemas/agent.spec.schema.json
new file mode 100644
index 0000000..5cda17b
--- /dev/null
+++ b/specs/registries/schemas/agent.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/agent.spec.schema.json",
+ "title": "MBTQ Agent Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "agent.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/common-fields.schema.json b/specs/registries/schemas/common-fields.schema.json
new file mode 100644
index 0000000..2982ee3
--- /dev/null
+++ b/specs/registries/schemas/common-fields.schema.json
@@ -0,0 +1,134 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/common-fields.schema.json",
+ "title": "MBTQ Common Spec Fields",
+ "type": "object",
+ "required": [
+ "schemaVersion",
+ "id",
+ "name",
+ "version",
+ "description",
+ "inputs",
+ "outputs",
+ "dependencies",
+ "eventsProduced",
+ "eventsConsumed",
+ "runtime",
+ "securityRequirements",
+ "permissions",
+ "healthChecks",
+ "lifecycleState",
+ "owner",
+ "tags"
+ ],
+ "properties": {
+ "schemaVersion": {
+ "type": "string",
+ "const": "1.0.0"
+ },
+ "id": {
+ "type": "string",
+ "minLength": 3
+ },
+ "name": {
+ "type": "string",
+ "minLength": 2
+ },
+ "version": {
+ "type": "string",
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
+ },
+ "description": {
+ "type": "string",
+ "minLength": 5
+ },
+ "inputs": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": ["name", "type", "description"],
+ "properties": {
+ "name": { "type": "string" },
+ "type": { "type": "string" },
+ "required": { "type": "boolean" },
+ "description": { "type": "string" }
+ },
+ "additionalProperties": true
+ }
+ },
+ "outputs": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": ["name", "type", "description"],
+ "properties": {
+ "name": { "type": "string" },
+ "type": { "type": "string" },
+ "description": { "type": "string" }
+ },
+ "additionalProperties": true
+ }
+ },
+ "dependencies": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "eventsProduced": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "eventsConsumed": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "runtime": {
+ "type": "object",
+ "required": ["primary", "supported"],
+ "properties": {
+ "primary": { "type": "string" },
+ "supported": {
+ "type": "array",
+ "items": { "type": "string" },
+ "minItems": 1
+ }
+ },
+ "additionalProperties": true
+ },
+ "securityRequirements": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "permissions": {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "healthChecks": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": ["name", "method", "target"],
+ "properties": {
+ "name": { "type": "string" },
+ "method": { "type": "string" },
+ "target": { "type": "string" },
+ "intervalSeconds": { "type": "number" }
+ },
+ "additionalProperties": true
+ }
+ },
+ "lifecycleState": {
+ "type": "string",
+ "enum": ["draft", "active", "deprecated", "archived"]
+ },
+ "owner": {
+ "type": "string",
+ "minLength": 2
+ },
+ "tags": {
+ "type": "array",
+ "items": { "type": "string" }
+ }
+ },
+ "additionalProperties": true
+}
diff --git a/specs/registries/schemas/dispatch.spec.schema.json b/specs/registries/schemas/dispatch.spec.schema.json
new file mode 100644
index 0000000..860dca0
--- /dev/null
+++ b/specs/registries/schemas/dispatch.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/dispatch.spec.schema.json",
+ "title": "MBTQ Dispatch Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "dispatch.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/magician.spec.schema.json b/specs/registries/schemas/magician.spec.schema.json
new file mode 100644
index 0000000..f59e18a
--- /dev/null
+++ b/specs/registries/schemas/magician.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/magician.spec.schema.json",
+ "title": "MBTQ Magician Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "magician.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/provider.spec.schema.json b/specs/registries/schemas/provider.spec.schema.json
new file mode 100644
index 0000000..edcfaf3
--- /dev/null
+++ b/specs/registries/schemas/provider.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/provider.spec.schema.json",
+ "title": "MBTQ Provider Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "provider.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/runtime.spec.schema.json b/specs/registries/schemas/runtime.spec.schema.json
new file mode 100644
index 0000000..b959d31
--- /dev/null
+++ b/specs/registries/schemas/runtime.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/runtime.spec.schema.json",
+ "title": "MBTQ Runtime Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "runtime.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/service.spec.schema.json b/specs/registries/schemas/service.spec.schema.json
new file mode 100644
index 0000000..edb44ee
--- /dev/null
+++ b/specs/registries/schemas/service.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/service.spec.schema.json",
+ "title": "MBTQ Service Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "service.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/schemas/workflow.spec.schema.json b/specs/registries/schemas/workflow.spec.schema.json
new file mode 100644
index 0000000..193b52a
--- /dev/null
+++ b/specs/registries/schemas/workflow.spec.schema.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://mbtq.dev/specs/schemas/v1/workflow.spec.schema.json",
+ "title": "MBTQ Workflow Specification",
+ "type": "object",
+ "required": ["specType"],
+ "properties": {
+ "specType": {
+ "type": "string",
+ "const": "workflow.spec"
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "./common-fields.schema.json"
+ }
+ ]
+}
diff --git a/specs/registries/scripts/build-index.mjs b/specs/registries/scripts/build-index.mjs
new file mode 100644
index 0000000..68cbdad
--- /dev/null
+++ b/specs/registries/scripts/build-index.mjs
@@ -0,0 +1,41 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import { SPECS_DIR, walkSpecFiles, readJson, asRepoPath } from './spec-lib.mjs';
+
+const files = walkSpecFiles();
+const generatedAt = new Date().toISOString();
+
+const index = {
+ version: '1.0.0',
+ generatedAt,
+ totalSpecs: files.length,
+ byType: {},
+ specs: []
+};
+
+for (const file of files) {
+ const spec = readJson(file);
+ const specRef = {
+ id: spec.id,
+ specType: spec.specType,
+ name: spec.name,
+ version: spec.version,
+ lifecycleState: spec.lifecycleState,
+ owner: spec.owner,
+ path: asRepoPath(file),
+ dependencies: spec.dependencies,
+ runtime: spec.runtime,
+ tags: spec.tags
+ };
+
+ index.specs.push(specRef);
+ if (!index.byType[spec.specType]) {
+ index.byType[spec.specType] = [];
+ }
+ index.byType[spec.specType].push(specRef.id);
+}
+
+const outputPath = path.join(SPECS_DIR, 'registries', 'index.json');
+fs.writeFileSync(outputPath, `${JSON.stringify(index, null, 2)}\n`);
+
+console.log(`Registry index written to ${asRepoPath(outputPath)}.`);
diff --git a/specs/registries/scripts/generate-architecture-docs.mjs b/specs/registries/scripts/generate-architecture-docs.mjs
new file mode 100644
index 0000000..beec579
--- /dev/null
+++ b/specs/registries/scripts/generate-architecture-docs.mjs
@@ -0,0 +1,41 @@
+import fs from 'node:fs';
+import path from 'node:path';
+
+const root = process.cwd();
+const indexPath = path.join(root, 'specs', 'registries', 'index.json');
+const docsPath = path.join(root, 'docs', 'ARCHITECTURE_REGISTRY.md');
+
+const index = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
+
+const lines = [];
+lines.push('# MBTQ Studio Registry Architecture');
+lines.push('');
+lines.push(`Generated from \`specs/\` at ${index.generatedAt}.`);
+lines.push('');
+lines.push('## Registry Summary');
+lines.push(`- Version: ${index.version}`);
+lines.push(`- Total specs: ${index.totalSpecs}`);
+lines.push('');
+lines.push('## Specs by Type');
+
+for (const [type, ids] of Object.entries(index.byType)) {
+ lines.push(`- ${type}: ${ids.length}`);
+}
+
+lines.push('');
+lines.push('## Specification Inventory');
+lines.push('');
+lines.push('| ID | Type | Version | Lifecycle | Owner | Path |');
+lines.push('|---|---|---|---|---|---|');
+
+for (const spec of index.specs) {
+ lines.push(`| ${spec.id} | ${spec.specType} | ${spec.version} | ${spec.lifecycleState} | ${spec.owner} | \`${spec.path}\` |`);
+}
+
+lines.push('');
+lines.push('## Runtime Compatibility');
+lines.push('');
+lines.push('Framework-agnostic support targets are encoded in every spec runtime.supported array, including FastAPI, Deno, and Python workers.');
+
+fs.writeFileSync(docsPath, `${lines.join('\n')}\n`);
+console.log('Architecture registry documentation generated at docs/ARCHITECTURE_REGISTRY.md.');
diff --git a/specs/registries/scripts/spec-lib.mjs b/specs/registries/scripts/spec-lib.mjs
new file mode 100644
index 0000000..5295b8a
--- /dev/null
+++ b/specs/registries/scripts/spec-lib.mjs
@@ -0,0 +1,64 @@
+import fs from 'node:fs';
+import path from 'node:path';
+
+export const ROOT = process.cwd();
+export const SPECS_DIR = path.join(ROOT, 'specs');
+export const SCHEMAS_DIR = path.join(SPECS_DIR, 'registries', 'schemas');
+
+export const REQUIRED_FIELDS = [
+ 'id',
+ 'name',
+ 'version',
+ 'description',
+ 'inputs',
+ 'outputs',
+ 'dependencies',
+ 'eventsProduced',
+ 'eventsConsumed',
+ 'runtime',
+ 'securityRequirements',
+ 'permissions',
+ 'healthChecks',
+ 'lifecycleState',
+ 'owner',
+ 'tags',
+ 'schemaVersion',
+ 'specType'
+];
+
+export const TYPE_TO_SCHEMA = {
+ 'service.spec': 'service.spec.schema.json',
+ 'agent.spec': 'agent.spec.schema.json',
+ 'workflow.spec': 'workflow.spec.schema.json',
+ 'dispatch.spec': 'dispatch.spec.schema.json',
+ 'magician.spec': 'magician.spec.schema.json',
+ 'provider.spec': 'provider.spec.schema.json',
+ 'runtime.spec': 'runtime.spec.schema.json'
+};
+
+export function walkSpecFiles(dir = SPECS_DIR) {
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
+ const files = [];
+
+ for (const entry of entries) {
+ const fullPath = path.join(dir, entry.name);
+ if (entry.isDirectory()) {
+ files.push(...walkSpecFiles(fullPath));
+ continue;
+ }
+
+ if (entry.isFile() && entry.name.endsWith('.spec.json')) {
+ files.push(fullPath);
+ }
+ }
+
+ return files;
+}
+
+export function readJson(filePath) {
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
+}
+
+export function asRepoPath(filePath) {
+ return path.relative(ROOT, filePath).replaceAll('\\\\', '/');
+}
diff --git a/specs/registries/scripts/validate-specs.mjs b/specs/registries/scripts/validate-specs.mjs
new file mode 100644
index 0000000..1b1e662
--- /dev/null
+++ b/specs/registries/scripts/validate-specs.mjs
@@ -0,0 +1,95 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import {
+ SCHEMAS_DIR,
+ REQUIRED_FIELDS,
+ TYPE_TO_SCHEMA,
+ walkSpecFiles,
+ readJson,
+ asRepoPath
+} from './spec-lib.mjs';
+
+const errors = [];
+const files = walkSpecFiles();
+
+for (const file of files) {
+ const spec = readJson(file);
+ const repoPath = asRepoPath(file);
+
+ for (const field of REQUIRED_FIELDS) {
+ if (!(field in spec)) {
+ errors.push(`${repoPath}: missing required field '${field}'`);
+ }
+ }
+
+ if (spec.schemaVersion !== '1.0.0') {
+ errors.push(`${repoPath}: schemaVersion must be '1.0.0'`);
+ }
+
+ const schemaFileName = TYPE_TO_SCHEMA[spec.specType];
+ if (!schemaFileName) {
+ errors.push(`${repoPath}: unknown specType '${spec.specType}'`);
+ } else {
+ const schemaPath = path.join(SCHEMAS_DIR, schemaFileName);
+ if (!fs.existsSync(schemaPath)) {
+ errors.push(`${repoPath}: schema file not found '${asRepoPath(schemaPath)}'`);
+ } else {
+ const schema = readJson(schemaPath);
+ const expectedType = schema?.properties?.specType?.const;
+ if (expectedType !== spec.specType) {
+ errors.push(`${repoPath}: specType '${spec.specType}' does not match schema '${expectedType}'`);
+ }
+ }
+ }
+
+ const arrays = [
+ 'inputs',
+ 'outputs',
+ 'dependencies',
+ 'eventsProduced',
+ 'eventsConsumed',
+ 'securityRequirements',
+ 'permissions',
+ 'healthChecks',
+ 'tags'
+ ];
+
+ for (const key of arrays) {
+ if (!Array.isArray(spec[key])) {
+ errors.push(`${repoPath}: '${key}' must be an array`);
+ }
+ }
+
+ if (!spec.runtime || typeof spec.runtime !== 'object') {
+ errors.push(`${repoPath}: runtime must be an object`);
+ } else {
+ if (typeof spec.runtime.primary !== 'string' || spec.runtime.primary.length === 0) {
+ errors.push(`${repoPath}: runtime.primary must be a non-empty string`);
+ }
+ if (!Array.isArray(spec.runtime.supported) || spec.runtime.supported.length === 0) {
+ errors.push(`${repoPath}: runtime.supported must be a non-empty array`);
+ }
+ }
+
+ if (!['draft', 'active', 'deprecated', 'archived'].includes(spec.lifecycleState)) {
+ errors.push(`${repoPath}: lifecycleState must be one of draft|active|deprecated|archived`);
+ }
+
+ const runtimeSupported = spec.runtime?.supported ?? [];
+ const agnosticTargets = ['fastapi', 'deno', 'python-worker'];
+ for (const target of agnosticTargets) {
+ if (!runtimeSupported.includes(target)) {
+ errors.push(`${repoPath}: runtime.supported must include '${target}' for framework-agnostic compatibility`);
+ }
+ }
+}
+
+if (errors.length > 0) {
+ console.error('Spec validation failed:\n');
+ for (const error of errors) {
+ console.error(`- ${error}`);
+ }
+ process.exit(1);
+}
+
+console.log(`Validated ${files.length} spec files successfully.`);
diff --git a/specs/runtimes/multi-runtime.runtime.spec.json b/specs/runtimes/multi-runtime.runtime.spec.json
new file mode 100644
index 0000000..607103a
--- /dev/null
+++ b/specs/runtimes/multi-runtime.runtime.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "runtime.spec",
+ "id": "runtime.multi-framework",
+ "name": "Multi-Runtime Compatibility Contract",
+ "version": "0.1.0",
+ "description": "Framework-agnostic runtime contract for FastAPI, Deno, Python workers, and future runtimes.",
+ "inputs": [
+ {
+ "name": "executionRequest",
+ "type": "runtime.execution.request",
+ "required": true,
+ "description": "Runtime execution request payload."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "executionResult",
+ "type": "runtime.execution.result",
+ "description": "Normalized execution result format."
+ }
+ ],
+ "dependencies": [],
+ "eventsProduced": ["runtime.execution.completed"],
+ "eventsConsumed": ["runtime.execution.requested"],
+ "runtime": {
+ "primary": "agnostic",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs", "future-runtime"]
+ },
+ "securityRequirements": ["sandboxed-execution", "runtime-isolation"],
+ "permissions": ["runtime:execute"],
+ "healthChecks": [
+ {
+ "name": "runtime-heartbeat",
+ "method": "event",
+ "target": "runtime.heartbeat",
+ "intervalSeconds": 60
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["runtime", "agnostic", "compatibility"]
+}
diff --git a/specs/services/foundation-registry.service.spec.json b/specs/services/foundation-registry.service.spec.json
new file mode 100644
index 0000000..2b02f2e
--- /dev/null
+++ b/specs/services/foundation-registry.service.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "service.spec",
+ "id": "svc.registry.foundation",
+ "name": "Registry Foundation Service",
+ "version": "0.1.0",
+ "description": "Central registry-driven control plane for MBTQ architecture metadata.",
+ "inputs": [
+ {
+ "name": "specChange",
+ "type": "spec.bundle",
+ "required": true,
+ "description": "Proposed spec changes from pull requests."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "registryIndex",
+ "type": "registry.index",
+ "description": "Machine-readable registry index artifact."
+ }
+ ],
+ "dependencies": ["provider.github-actions", "workflow.spec-governance"],
+ "eventsProduced": ["registry.index.generated", "spec.validation.completed"],
+ "eventsConsumed": ["spec.change.requested"],
+ "runtime": {
+ "primary": "nodejs",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["signed-commits", "branch-protection", "artifact-integrity"],
+ "permissions": ["contents:read", "pull-requests:read"],
+ "healthChecks": [
+ {
+ "name": "spec-validator",
+ "method": "command",
+ "target": "npm run specs:validate",
+ "intervalSeconds": 0
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["registry", "foundation", "architecture"]
+}
diff --git a/specs/workflows/spec-governance.workflow.spec.json b/specs/workflows/spec-governance.workflow.spec.json
new file mode 100644
index 0000000..fe9bdd5
--- /dev/null
+++ b/specs/workflows/spec-governance.workflow.spec.json
@@ -0,0 +1,43 @@
+{
+ "schemaVersion": "1.0.0",
+ "specType": "workflow.spec",
+ "id": "workflow.spec-governance",
+ "name": "Spec Governance Workflow",
+ "version": "0.1.0",
+ "description": "Workflow that validates specs, builds registry index, and generates architecture docs.",
+ "inputs": [
+ {
+ "name": "pullRequest",
+ "type": "github.pull_request",
+ "required": true,
+ "description": "Pull request event payload."
+ }
+ ],
+ "outputs": [
+ {
+ "name": "governanceResult",
+ "type": "workflow.result",
+ "description": "Pass/fail result with generated artifacts."
+ }
+ ],
+ "dependencies": ["agent.spec.auditor", "provider.github-actions"],
+ "eventsProduced": ["workflow.spec-governance.completed"],
+ "eventsConsumed": ["spec.change.requested"],
+ "runtime": {
+ "primary": "github-actions",
+ "supported": ["fastapi", "deno", "python-worker", "nodejs"]
+ },
+ "securityRequirements": ["least-privilege-permissions", "artifact-auditability"],
+ "permissions": ["contents:read"],
+ "healthChecks": [
+ {
+ "name": "workflow-trigger",
+ "method": "github-event",
+ "target": "pull_request",
+ "intervalSeconds": 0
+ }
+ ],
+ "lifecycleState": "draft",
+ "owner": "MBTQ Core Team",
+ "tags": ["workflow", "registry", "ci"]
+}