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

+
    +
  1. Ingest visual/sign input or text request
  2. +
  3. Run Deaf-first analysis and context retrieval
  4. +
  5. Route through selected org visual panel profile
  6. +
  7. Generate response with collaboration/operator alignment
  8. +
  9. Loop per selected schedule when enabled
  10. +
+
+
+ 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"] +}