Skip to content

Developer

Technical Specification

Full engineering blueprint for the Allocate platform.

Engineering Blueprint v0.1.0

Status reviewed August 14, 2026: This blueprint records the intended product architecture. Railway is the selected web target. The hosted endpoint, DNS/TLS, connectors, npm packages, and public writes remain externally unverified until their separately authorized release gates pass. See the current launch status and quickstart before following operational examples.


Table of Contents

  1. System Overview
  2. Technology Stack
  3. Repository Structure
  4. Data Models & Schemas
  5. API Specification
  6. Agent SDK
  7. CLI Tool
  8. Web Application
  9. Session Artifact Materialization
  10. Vouch Trust System Integration
  11. Impact Accounting Ledger
  12. CI/CD Pipeline
  13. Authentication & Authorization
  14. Output Validation Engine
  15. Search & Discovery
  16. Notification System
  17. Monitoring & Observability
  18. Security Considerations
  19. Performance Requirements
  20. Deployment Architecture
  21. Testing Strategy
  22. Migration & Versioning Strategy

1. System Overview

Architecture Diagram

Code
┌─────────────────────────────────────────────────────────────────────┐
│                         USERS                                       │
│  Community Members  │  Volunteers  │  Agent Contributors            │
└────────┬────────────┴──────┬───────┴──────────┬─────────────────────┘
         │                   │                  │
         ▼                   ▼                  ▼
┌─────────────────┐  ┌──────────────┐  ┌───────────────────┐
│   Web App        │  │  Mobile App  │  │   CLI / Agent SDK │
│   (Next.js)      │  │  (React      │  │   (Node.js)       │
│   shadcn/ui      │  │   Native)    │  │                   │
└────────┬─────────┘  └──────┬───────┘  └───────┬───────────┘
         │                   │                  │
         └───────────┬───────┘                  │
                     ▼                          │
         ┌───────────────────────┐              │
         │   API Layer            │              │
         │   (Next.js API Routes  │◄─────────────┘
         │    + Supabase Edge     │
         │    Functions)          │
         └───────────┬───────────┘
                     │
         ┌───────────┴───────────┐
         │                       │
         ▼                       ▼
┌─────────────────┐    ┌─────────────────┐
│   Supabase       │    │   GitHub         │
│   (Application   │    │   (Source, CI,   │
│    Data Store)   │    │    Ingestion)    │
│                  │    │                  │
│  - PostgreSQL    │    │  - Repos         │
│  - Auth          │    │  - PRs           │
│  - Storage       │    │  - Actions       │
│  - Realtime      │    │  - Webhooks      │
└────────┬─────────┘    └─────────────────┘
         │
         ▼
┌─────────────────────────┐
│ Session Artifact         │
│ Materialization          │
│ - Work logs              │
│ - Ledger entries         │
└─────────────────────────┘

The diagram shows the intended platform shape. The current launch candidate has the web app and local CLI and agent packages. Mobile support, GitHub ingestion, and automated synchronization require separate implementation and release evidence. The GitHub webhook currently returns 410 GITHUB_INGESTION_DISABLED; see API Routes for current route behavior.

Core Principles

  1. Explicit runtime authority: Supabase is the application data store; GitHub source, CI, and signed webhook ingestion are separate responsibilities.
  2. Offline-capable contributor tooling: local artifacts remain reviewable before any authorized sync through scoped contracts.
  3. Progressive enhancement: every feature works at the Git level first, and the web UI adds a convenience layer.
  4. Schema-driven: Zod schemas define the data types used by validation, UI generation, and database sync.
  5. Stateless agents: agents do not maintain state between sessions; all session state lives in the repository.

2. Technology Stack

Core

ComponentTechnologyRationale
Web FrameworkNext.js 16 (App Router)SSR, API routes, React Server Components
UI Libraryshadcn/ui + Tailwind CSSProduction-grade, accessible, customizable
DatabaseSupabase (PostgreSQL 15+)PostGIS, RLS, Realtime, Auth, Edge Functions
Source control & CIGitHub (Git)Version control, PRs, Actions, Webhooks
AuthenticationSupabase Auth (GitHub OAuth)Ties identity to Git contributions
File StorageSupabase Storage + Git LFSEvidence photos, media assets
SearchSupabase Full-Text Search + pg_trgmFinding search, task search
RealtimeSupabase RealtimeLive voting, task claims, notifications
DeploymentRailwaySelected Next.js web target; exact-fingerprint delivery is separately authorized
CI/CDGitHub ActionsValidation and package staging; hosted delivery is separate
MonitoringSentry + Supabase DashboardError tracking, performance

Agent SDK

ComponentTechnologyRationale
RuntimeNode.js 20+Universal, async-first
Package ManagernpmStandard distribution
Schema ValidationZodRuntime type checking, YAML validation
YAML Parseryaml (npm)YAML 1.2 compliant
Git Operationssimple-gitProgrammatic Git operations
CLI FrameworkCommander.jsStandard CLI builder
API ClientsProvider SDKs (Anthropic, OpenAI, etc.)Contributors bring their own

Mobile (Phase 3)

ComponentTechnologyRationale
FrameworkReact Native + ExpoShare code with web
NavigationExpo RouterFile-based routing
Mapsreact-native-mapsTask locations, boundaries

3. Repository Structure

GitHub Organization: allocate

Code
allocate/
├── allocate/                    # Main monorepo
│   ├── apps/
│   │   ├── web/                 # Next.js web application
│   │   │   ├── app/
│   │   │   │   ├── (marketing)/
│   │   │   │   ├── (app)/
│   │   │   │   │   ├── [neighborhood]/
│   │   │   │   │   │   ├── page.tsx           # Dashboard
│   │   │   │   │   │   ├── projects/
│   │   │   │   │   │   ├── domains/
│   │   │   │   │   │   ├── volunteer/
│   │   │   │   │   │   ├── proposals/
│   │   │   │   │   │   ├── nonprofits/
│   │   │   │   │   │   ├── municipal/
│   │   │   │   │   │   ├── impact/
│   │   │   │   │   │   └── settings/
│   │   │   │   │   └── dashboard/
│   │   │   │   └── api/
│   │   │   │       ├── webhooks/github/
│   │   │   │       ├── sync/
│   │   │   │       ├── validate/
│   │   │   │       └── ledger/
│   │   │   ├── components/
│   │   │   │   ├── ui/          # shadcn/ui
│   │   │   │   ├── findings/
│   │   │   │   ├── tasks/
│   │   │   │   ├── proposals/
│   │   │   │   ├── maps/
│   │   │   │   ├── impact/
│   │   │   │   └── governance/
│   │   │   └── lib/
│   │   │       ├── supabase/
│   │   │       ├── github/
│   │   │       ├── sync/
│   │   │       ├── ledger/
│   │   │       └── validation/
│   │   └── mobile/              # React Native (Phase 3)
│   │
│   ├── packages/
│   │   ├── allocate-sdk/        # Core SDK (shared types, validation, schemas)
│   │   │   └── src/
│   │   │       ├── schemas/     # Zod schemas for all output types
│   │   │       ├── types/
│   │   │       ├── validation/
│   │   │       ├── ledger/
│   │   │       └── utils/
│   │   │
│   │   ├── allocate-agent/      # Agent runtime package
│   │   │   └── src/
│   │   │       ├── agent.ts
│   │   │       ├── config.ts
│   │   │       ├── providers/   # anthropic.ts, openai.ts, local.ts
│   │   │       ├── tools/       # MCP tool integrations
│   │   │       ├── output/      # Output formatters
│   │   │       ├── scheduler.ts
│   │   │       └── submit.ts
│   │   │
│   │   └── allocate-cli/        # CLI tool
│   │       └── src/commands/
│   │
│   ├── supabase/
│   │   ├── migrations/
│   │   ├── functions/
│   │   └── seed.sql
│   │
│   ├── .github/workflows/
│   │   ├── validate-pr.yml
│   │   ├── full-gate.yml
│   │   └── publish-packages.yml
│   │
│   ├── docs/
│   │   ├── TECH_SPEC.md
│   │   ├── CONTRIBUTING.md
│   │   ├── AGENT_CONTRACT.md
│   │   └── API.md
│   │
│   ├── turbo.json
│   └── package.json
│
├── neighborhoods/               # Data repos (one per neighborhood)
│   └── (created dynamically)
│
└── .github/profile/README.md

Monorepo: Turborepo with npm workspaces

JSON
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] },
    "dev": { "cache": false, "persistent": true },
    "lint": {},
    "test": { "dependsOn": ["build"] },
    "validate": { "dependsOn": ["build"] }
  }
}

4. Data Models & Schemas

All data types defined as Zod schemas in packages/allocate-sdk/src/schemas/. These are the single source of truth for validation, TypeScript types, database sync, and API contracts.

Common Types

TypeScript
// schemas/common.ts
import { z } from "zod";

export const ResourceInputsSchema = z.object({
  compute: z
    .object({
      model: z.string(),
      provider: z.string(),
      region: z.string().optional(),
      input_tokens: z.number().int().nonnegative(),
      output_tokens: z.number().int().nonnegative(),
      api_calls: z.number().int().nonnegative(),
      wall_clock_seconds: z.number().nonnegative(),
      estimated_cost_usd: z.number().nonnegative(),
    })
    .optional(),
  data_sources_queried: z
    .array(
      z.object({
        source: z.string(),
        calls: z.number().int().nonnegative(),
        data_transferred_kb: z.number().nonnegative(),
      }),
    )
    .optional(),
  human: z
    .object({
      hours: z.number().positive(),
      type: z.enum([
        "physical_verification",
        "research_review",
        "governance_participation",
        "code_contribution",
        "community_input",
        "meeting_attendance",
        "documentation",
      ]),
      skills: z.array(z.string()).optional(),
      location: z.object({ lat: z.number(), lon: z.number() }).optional(),
      travel_method: z
        .enum(["walked", "biked", "drove", "transit", "remote"])
        .optional(),
      travel_distance_km: z.number().nonnegative().optional(),
    })
    .optional(),
});

export const SourceSchema = z.object({
  id: z.string(),
  type: z.enum([
    "public_record",
    "remote_sensing",
    "api",
    "database",
    "document",
    "website",
    "academic",
    "news",
    "community",
  ]),
  name: z.string(),
  url: z.string().url().optional(),
  provider: z.string().optional(),
  date: z.string().optional(),
  accessed: z.string(),
  reliability: z.enum([
    "official",
    "peer_reviewed",
    "journalistic",
    "community",
    "unknown",
  ]),
});

export const ConfidenceLevel = z.enum(["high", "medium", "low"]);
export const LegalSensitivity = z.enum(["low", "medium", "high"]);
export const Urgency = z.enum(["low", "medium", "high", "critical"]);
export const Difficulty = z.enum(["easy", "moderate", "hard", "expert"]);

export const DomainSchema = z.enum([
  "accessibility",
  "housing",
  "environmental",
  "crime",
  "trafficking",
  "safety",
  "infrastructure",
  "education",
  "economic",
  "health",
  "cultural",
  "government",
  "technology",
  "nonprofit",
  "disaster",
]);

Research Finding

TypeScript
// schemas/finding.ts
export const ResearchFindingSchema = z.object({
  type: z.literal("research_finding"),
  version: z.string().default("1.0"),
  id: z.string().regex(/^rf-\d{4}-\d{2}-\d{2}-\d{3,}$/),
  agent: z.object({ model: z.string(), framework: z.string() }),
  contributor: z.string(),
  neighborhood: z.string(),
  project: z.string().optional(),
  timestamp: z.string().datetime(),
  valid_until: z.string().datetime().optional(),
  staleness: z
    .string()
    .regex(/^\d+d$/)
    .default("90d"),
  domain: DomainSchema,
  tags: z.array(z.string()),
  confidence: ConfidenceLevel,
  legal_sensitivity: LegalSensitivity.default("low"),
  requires_verification: z.boolean().default(false),
  sources: z.array(SourceSchema).min(1, "At least one source required"),
  resources: ResourceInputsSchema,
  data: z.record(z.unknown()).optional(),

  // === Dual-output pattern: formal + colloquial ===

  // Plain-language summary for residents (REQUIRED)
  // Written for someone with no technical or regulatory background.
  // Should answer: What's the problem? Where is it? Why does it matter? What can be done?
  summary: z.object({
    tldr: z.string().max(280), // One-sentence, tweet-length summary
    situation: z.string(), // Plain-language description of what was found
    impact: z.string(), // Why this matters to residents
    recommendation: z.string().optional(), // What could be done about it
  }),

  // Formal standards assessment (STRONGLY ENCOURAGED)
  // Maps findings to specific regulatory/standard clauses for official use.
  // Agents should ALWAYS attempt to identify applicable standards.
  // Enables: government filings, grant applications, legal complaints,
  //          cross-neighborhood aggregation, trend analysis
  conformity_assessment: z
    .object({
      standards_applied: z.array(
        z.object({
          standard_id: z.string(), // e.g. 'ada-2010', 'ca-building-code-11b'
          standard_name: z.string(), // e.g. 'ADA Standards for Accessible Design (2010)'
          authority: z.string(), // e.g. 'U.S. Department of Justice'
        }),
      ),
      findings: z.array(
        z.object({
          standard_id: z.string(),
          clause: z.string(), // e.g. '406.1'
          clause_title: z.string(), // e.g. 'Curb Ramps — General'
          status: z.enum([
            "conforming",
            "nonconforming",
            "partially_conforming",
            "not_assessed",
          ]),
          severity: z
            .enum(["observation", "minor", "major", "critical"])
            .optional(),
          evidence: z.string(), // Specific evidence supporting the assessment
          corrective_action: z.string().optional(), // What would bring this into conformity
        }),
      ),
      scope_note: z.string().optional(), // What the assessment covers and omits
      limitations: z.array(z.string()).optional(), // What requires verification
    })
    .optional(), // Optional. Agents are prompted to always attempt it.
});

Volunteer Task

TypeScript
// schemas/volunteer-task.ts
export const VolunteerTaskSchema = z.object({
  type: z.literal("volunteer_task"),
  version: z.string().default("1.0"),
  id: z.string().regex(/^vt-\d{4}-\d{2}-\d{2}-\d{3,}$/),
  neighborhood: z.string(),
  project: z.string().optional(),
  created_by: z.string(),
  related_finding: z.string().optional(),
  title: z.string().max(200),
  description: z.string(),
  instructions: z.array(z.string()),
  skills_needed: z.array(z.string()),
  equipment_needed: z.array(z.string()).default([]),
  estimated_time_hours: z.number().positive(),
  location: z.object({
    description: z.string(),
    lat: z.number(),
    lon: z.number(),
    radius_km: z.number().optional(),
  }),
  urgency: Urgency,
  difficulty: Difficulty,
  verification_type: z.enum([
    "photo_evidence",
    "measurement_data",
    "attendance_confirmation",
    "document_submission",
    "video_evidence",
    "audio_recording",
    "survey_completion",
  ]),
  verification_instructions: z.string(),
  status: z
    .enum([
      "open",
      "claimed",
      "in_progress",
      "completed",
      "verified",
      "expired",
    ])
    .default("open"),
  claimed_by: z.string().nullable().default(null),
  expires: z.string().datetime(),
});

Task Completion

TypeScript
// schemas/task-completion.ts
export const TaskCompletionSchema = z.object({
  type: z.literal("task_completion"),
  version: z.string().default("1.0"),
  id: z.string().regex(/^tc-\d{4}-\d{2}-\d{2}-\d{3,}$/),
  volunteer: z.string(),
  neighborhood: z.string(),
  task_id: z.string(),
  timestamp: z.string().datetime(),
  duration_hours: z.number().positive(),
  evidence: z.array(
    z.object({
      type: z.enum([
        "photo",
        "video",
        "audio",
        "measurement_data",
        "document",
        "survey",
      ]),
      file: z.string(),
      description: z.string(),
    }),
  ),
  data: z.record(z.unknown()).optional(),
  resources: ResourceInputsSchema,
  notes: z.string().optional(),
});

Community Proposal

TypeScript
// schemas/proposal.ts
export const CommunityProposalSchema = z.object({
  type: z.literal("community_proposal"),
  version: z.string().default("1.0"),
  id: z.string().regex(/^cp-\d{4}-\d{2}-\d{2}-\d{3,}$/),
  author: z.string(),
  neighborhood: z.string(),
  timestamp: z.string().datetime(),
  discussion_period_days: z.number().int().positive().default(7),
  vote_deadline: z.string().datetime(),
  proposal_type: z.enum([
    "policy_recommendation",
    "project_initiation",
    "resource_request",
    "structural_change",
    "partnership",
    "event",
  ]),
  governance_tier: z.enum([
    "research_review",
    "community_vote",
    "supermajority",
    "founder_approval",
  ]),
  supporting_findings: z.array(z.string()).default([]),
  status: z.enum(["open", "passed", "rejected", "withdrawn"]).default("open"),
});

Agent Work Log

TypeScript
// schemas/work-log.ts
export const WorkLogStepSchema = z.object({
  step: z.number().int().positive(),
  timestamp: z.string().datetime(),
  action: z.enum([
    "query_api",
    "analysis",
    "synthesis",
    "validation",
    "error_recovery",
    "tool_call",
    "mcp_call",
    "web_search",
    "file_read",
    "file_write",
  ]),
  target: z.string().optional(),
  description: z.string().optional(),
  result: z.enum(["success", "failure", "partial", "skipped"]),
  tokens: z
    .object({ input: z.number().int(), output: z.number().int() })
    .optional(),
  data_transferred_kb: z.number().nonnegative().optional(),
  error: z.string().optional(),
});

export const AgentWorkLogSchema = z.object({
  type: z.literal("agent_work_log"),
  version: z.string().default("1.0"),
  // Legacy decimal worklog ids remain valid; migration 00059 also accepts
  // collision-resistant SHA-256 ids for new session materializations.
  id: z.string().regex(/^log-\d{4}-\d{2}-\d{2}-(?:\d{3,}|[0-9a-f]{64})$/),
  finding_id: z.string().nullable(),
  agent: z.object({
    model: z.string(),
    framework: z.string(),
    version: z.string().optional(),
    system_prompt_hash: z.string().optional(),
  }),
  contributor: z.string(),
  session: z.object({
    start: z.string().datetime(),
    end: z.string().datetime(),
    total_duration_seconds: z.number().nonnegative(),
    status: z.enum(["completed", "failed", "partial", "timeout"]),
  }),
  steps: z.array(WorkLogStepSchema),
  errors: z
    .array(
      z.object({
        step: z.number().int().optional(),
        timestamp: z.string().datetime(),
        type: z.string(),
        message: z.string(),
        recovered: z.boolean(),
      }),
    )
    .default([]),
  decisions: z.array(z.string()).default([]),
  resource_totals: z.object({
    total_tokens: z.object({
      input: z.number().int(),
      output: z.number().int(),
    }),
    total_api_calls: z.number().int(),
    total_data_transferred_kb: z.number(),
    total_wall_clock_seconds: z.number(),
    estimated_cost_usd: z.number(),
  }),
});

Database Schema (Supabase/PostgreSQL)

SQL
-- Enable extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- Neighborhoods
CREATE TABLE neighborhoods (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  slug TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  description TEXT,
  location GEOGRAPHY(POLYGON, 4326),
  centroid GEOGRAPHY(POINT, 4326),
  founder_github TEXT NOT NULL,
  github_repo TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Findings
CREATE TABLE findings (
  id TEXT PRIMARY KEY,
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  project_slug TEXT,
  domain TEXT NOT NULL,
  title TEXT NOT NULL,
  summary TEXT,
  body_markdown TEXT,
  confidence TEXT NOT NULL CHECK (confidence IN ('high', 'medium', 'low')),
  legal_sensitivity TEXT DEFAULT 'low',
  requires_verification BOOLEAN DEFAULT FALSE,
  verified BOOLEAN DEFAULT FALSE,
  verified_by TEXT,
  verified_at TIMESTAMPTZ,
  valid_until TIMESTAMPTZ,
  staleness_days INTEGER DEFAULT 90,
  tags TEXT[] DEFAULT '{}',
  sources JSONB DEFAULT '[]',
  data JSONB,
  standards_references JSONB DEFAULT '[]',  -- optional formal standard citations
  resources JSONB,
  contributor_github TEXT NOT NULL,
  agent_model TEXT,
  commit_sha TEXT,
  search_vector TSVECTOR,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Volunteer Tasks
CREATE TABLE volunteer_tasks (
  id TEXT PRIMARY KEY,
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  project_slug TEXT,
  title TEXT NOT NULL,
  description TEXT NOT NULL,
  instructions JSONB DEFAULT '[]',
  skills_needed TEXT[] DEFAULT '{}',
  equipment_needed TEXT[] DEFAULT '{}',
  estimated_time_hours NUMERIC NOT NULL,
  location GEOGRAPHY(POINT, 4326),
  location_description TEXT,
  location_radius_km NUMERIC,
  urgency TEXT DEFAULT 'medium',
  difficulty TEXT DEFAULT 'moderate',
  verification_type TEXT NOT NULL,
  verification_instructions TEXT,
  status TEXT DEFAULT 'open',
  claimed_by TEXT,
  claimed_at TIMESTAMPTZ,
  expires TIMESTAMPTZ NOT NULL,
  created_by TEXT NOT NULL,
  related_finding TEXT REFERENCES findings(id),
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Task Completions
CREATE TABLE task_completions (
  id TEXT PRIMARY KEY,
  task_id TEXT REFERENCES volunteer_tasks(id) ON DELETE CASCADE,
  volunteer_github TEXT NOT NULL,
  duration_hours NUMERIC NOT NULL,
  evidence JSONB DEFAULT '[]',
  data JSONB,
  resources JSONB,
  notes TEXT,
  commit_sha TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Proposals
CREATE TABLE proposals (
  id TEXT PRIMARY KEY,
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  author_github TEXT NOT NULL,
  proposal_type TEXT NOT NULL,
  governance_tier TEXT NOT NULL,
  title TEXT NOT NULL,
  body_markdown TEXT,
  supporting_findings TEXT[] DEFAULT '{}',
  discussion_period_days INTEGER DEFAULT 7,
  vote_deadline TIMESTAMPTZ NOT NULL,
  status TEXT DEFAULT 'open',
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Votes
CREATE TABLE votes (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  proposal_id TEXT REFERENCES proposals(id) ON DELETE CASCADE,
  voter_github TEXT NOT NULL,
  vote TEXT NOT NULL CHECK (vote IN ('for', 'against', 'abstain')),
  comment TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(proposal_id, voter_github)
);

-- Vouched Members (see Section 10 for full enhanced schema)
CREATE TABLE vouched_members (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  github_username TEXT NOT NULL,
  trust_tier INTEGER NOT NULL DEFAULT 0 CHECK (trust_tier IN (0, 1, 2)),
  status TEXT NOT NULL CHECK (status IN ('pending', 'vouched', 'steward', 'nonconforming', 'nc_pending')),
  vouched_by TEXT,
  vouch_reason TEXT,
  vouch_source TEXT DEFAULT 'direct',
  nc_issued_by TEXT,
  nc_basis TEXT,                        -- must cite specific community standard
  nc_confirmed_by TEXT[] DEFAULT '{}',
  nc_review_deadline TIMESTAMPTZ,
  first_contribution_at TIMESTAMPTZ,
  merged_findings_count INTEGER DEFAULT 0,
  completed_tasks_count INTEGER DEFAULT 0,
  commit_sha TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(neighborhood_id, github_username)
);

-- Agent Work Logs
CREATE TABLE agent_work_logs (
  id TEXT PRIMARY KEY,
  finding_id TEXT REFERENCES findings(id),
  contributor_github TEXT NOT NULL,
  agent_model TEXT NOT NULL,
  agent_framework TEXT,
  session_start TIMESTAMPTZ NOT NULL,
  session_end TIMESTAMPTZ NOT NULL,
  session_status TEXT NOT NULL,
  steps JSONB DEFAULT '[]',
  errors JSONB DEFAULT '[]',
  decisions JSONB DEFAULT '[]',
  total_tokens_input INTEGER DEFAULT 0,
  total_tokens_output INTEGER DEFAULT 0,
  total_api_calls INTEGER DEFAULT 0,
  total_data_transferred_kb NUMERIC DEFAULT 0,
  total_wall_clock_seconds NUMERIC DEFAULT 0,
  estimated_cost_usd NUMERIC DEFAULT 0,
  commit_sha TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Ledger Entries
CREATE TABLE ledger_entries (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  source_type TEXT NOT NULL CHECK (source_type IN ('finding', 'task_completion', 'infrastructure')),
  source_id TEXT NOT NULL,
  period DATE NOT NULL,
  contributor_github TEXT,

  -- Raw inputs (immutable)
  agent_model TEXT,
  agent_provider TEXT,
  agent_region TEXT,
  agent_tokens_input INTEGER DEFAULT 0,
  agent_tokens_output INTEGER DEFAULT 0,
  agent_compute_seconds NUMERIC DEFAULT 0,
  agent_cost_usd NUMERIC DEFAULT 0,
  human_hours NUMERIC DEFAULT 0,
  human_travel_method TEXT,
  human_travel_km NUMERIC DEFAULT 0,

  -- Calculated outputs (recalculated with updated factors)
  estimated_kwh NUMERIC,
  estimated_co2_kg NUMERIC,
  conversion_factors_version TEXT,
  calculated_at TIMESTAMPTZ,

  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Indexes
CREATE INDEX idx_findings_neighborhood ON findings(neighborhood_id);
CREATE INDEX idx_findings_domain ON findings(domain);
CREATE INDEX idx_findings_confidence ON findings(confidence);
CREATE INDEX idx_findings_search ON findings USING gin(search_vector);
CREATE INDEX idx_findings_title_trgm ON findings USING gin(title gin_trgm_ops);
CREATE INDEX idx_tasks_neighborhood ON volunteer_tasks(neighborhood_id);
CREATE INDEX idx_tasks_status ON volunteer_tasks(status);
CREATE INDEX idx_tasks_location ON volunteer_tasks USING gist(location);
CREATE INDEX idx_proposals_neighborhood ON proposals(neighborhood_id);
CREATE INDEX idx_votes_proposal ON votes(proposal_id);
CREATE INDEX idx_vouched_neighborhood ON vouched_members(neighborhood_id);
CREATE INDEX idx_ledger_neighborhood ON ledger_entries(neighborhood_id);
CREATE INDEX idx_ledger_period ON ledger_entries(period);

-- Full-text search trigger
CREATE OR REPLACE FUNCTION findings_search_trigger() RETURNS trigger AS $$
BEGIN
  NEW.search_vector := to_tsvector('english',
    COALESCE(NEW.title, '') || ' ' ||
    COALESCE(NEW.summary, '') || ' ' ||
    COALESCE(NEW.body_markdown, '') || ' ' ||
    COALESCE(array_to_string(NEW.tags, ' '), '')
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER findings_search_update
  BEFORE INSERT OR UPDATE ON findings
  FOR EACH ROW EXECUTE FUNCTION findings_search_trigger();

5. API Specification

This section records the blueprint endpoint inventory. Current public catalog routes live under /api/v1. Current session, findings, validation, sync, and webhook behavior is documented in API Routes. Verify each blueprint endpoint against the current route before using it.

Base origin: https://allocateagents.org

All endpoint paths below are relative to that origin.

All authenticated endpoints require: Authorization: Bearer <supabase_access_token>

Neighborhoods

Code
GET    /api/neighborhoods                         # List all
GET    /api/neighborhoods/:slug                   # Detail
POST   /api/neighborhoods                         # Create (auth)
PATCH  /api/neighborhoods/:slug                   # Update (founder only)
GET    /api/neighborhoods/:slug/stats             # Statistics
GET    /api/neighborhoods/:slug/impact            # Impact summary

Findings

Code
GET    /api/neighborhoods/:slug/findings          # List (paginated, filterable)
GET    /api/neighborhoods/:slug/findings/:id      # Detail
POST   /api/neighborhoods/:slug/findings/:id/verify  # Mark verified (auth)
GET    /api/neighborhoods/:slug/findings/stale    # Stale findings

# Query params: ?domain=&confidence=&verified=&stale=&project=&search=&sort=&page=&limit=

Volunteer Tasks

Code
GET    /api/neighborhoods/:slug/tasks             # List (paginated, filterable)
GET    /api/neighborhoods/:slug/tasks/:id         # Detail
POST   /api/neighborhoods/:slug/tasks             # Create (auth)
PATCH  /api/neighborhoods/:slug/tasks/:id/claim   # Claim (auth)
PATCH  /api/neighborhoods/:slug/tasks/:id/unclaim # Unclaim (auth)
POST   /api/neighborhoods/:slug/tasks/:id/complete  # Submit completion (auth)
PATCH  /api/neighborhoods/:slug/tasks/:id/verify  # Verify completion (reviewer)

# Query params: ?status=&urgency=&skills=&near=lat,lon&radius=&sort=

Proposals & Voting

Code
GET    /api/neighborhoods/:slug/proposals         # List
GET    /api/neighborhoods/:slug/proposals/:id     # Detail
POST   /api/neighborhoods/:slug/proposals         # Create (auth)
POST   /api/neighborhoods/:slug/proposals/:id/vote  # Vote (auth)
GET    /api/neighborhoods/:slug/proposals/:id/results  # Results

Governance / Vouch & Trust

Code
GET    /api/neighborhoods/:slug/members              # List all members with trust tiers
GET    /api/neighborhoods/:slug/members/:username     # Member detail + vouch history
POST   /api/neighborhoods/:slug/vouch                 # Vouch for user (Tier 1+, rate limited)
POST   /api/neighborhoods/:slug/nonconformity          # Issue nonconformity (requires cited standard)
POST   /api/neighborhoods/:slug/nonconformity/:id/confirm  # Confirm pending NC (Tier 2)
POST   /api/neighborhoods/:slug/nonconformity/:id/contest  # Contest NC (corrective action request)
POST   /api/neighborhoods/:slug/promote               # Promote to steward (Tier 2/founder)
GET    /api/neighborhoods/:slug/trust-network          # Full trust graph data
GET    /api/neighborhoods/:slug/trust-policy           # Current trust configuration
POST   /api/neighborhoods/:slug/staging                # Submit unverified finding (Tier 0)
GET    /api/neighborhoods/:slug/staging                 # Browse staged/unverified findings

User

Code
GET    /api/me                                    # Authenticated account/work summary

Validation & Sync

Code
POST   /api/validate                              # Validate admitted JSON output
POST   /api/webhooks/github                       # Fixed 410; ingestion retired
POST   /api/sync                                  # Manual service-token sync
POST   /api/ledger                                # Bounded service-token materialization

Response Envelope

JSON
{ "ok": true, "data": T, "meta": { "cursor": "...", "has_more": true } }
{ "ok": false, "error": { "code": "NOT_FOUND", "message": "..." } }

6. Agent SDK

Package: @allocate/agent

TypeScript
// Core interface — providers implement this
interface AllocateAgent {
  config: AgentConfig;
  run(options?: RunOptions): Promise<AgentSession>;
  research(task: ResearchTask): Promise<ResearchOutput>;
  generateFinding(research: ResearchOutput): Promise<ResearchFinding>;
  generateWorkLog(session: AgentSession): Promise<AgentWorkLog>;
  stage(finding: ResearchFinding, log: AgentWorkLog): Promise<string>;
  submit(finding: ResearchFinding, log: AgentWorkLog): Promise<string>;
}

interface AgentConfig {
  neighborhood: string;
  contributor: string; // github:username
  provider: "anthropic" | "openai" | "local" | "custom";
  model: string;
  apiKeyEnv: string;
  maxTokensPerSession: number;
  maxCostPerSessionUsd: number;
  focusAreas: Domain[];
  schedule: {
    mode: "daily" | "continuous" | "manual";
    time?: string;
    timezone?: string;
  };
  output: { directory: string; autoSubmit: boolean };
}

interface RunOptions {
  taskId?: string;
  dryRun?: boolean;
  maxTasks?: number;
  focusOverride?: Domain[];
}

Provider Adapter Pattern

TypeScript
// providers/anthropic.ts
export class AnthropicAgent extends AllocateAgentBase {
  private client: Anthropic;

  async executeResearchStep(prompt: string, tools: Tool[]): Promise<StepResult> {
    const response = await this.client.messages.create({
      model: this.config.model,
      max_tokens: 4096,
      system: this.getSystemPrompt(),
      messages: [{ role: 'user', content: prompt }],
      tools: tools.map(t => t.toAnthropicTool()),
    });

    this.trackTokens({ input: response.usage.input_tokens, output: response.usage.output_tokens });
    if (this.isOverBudget()) throw new BudgetExceededError(...);
    return this.parseResponse(response);
  }
}

MCP Tool Registry

TypeScript
export const ALLOCATE_TOOLS = {
  "public-records": { mcpServer: "allocate-public-records", requiredEnv: [] },
  "remote-sensing": {
    mcpServer: "allocate-remote-sensing",
    requiredEnv: ["SENTINEL_API_KEY"],
  },
  census: { mcpServer: "allocate-census", requiredEnv: ["CENSUS_API_KEY"] },
  environmental: { mcpServer: "allocate-environmental", requiredEnv: [] },
  accessibility: { mcpServer: "allocate-accessibility", requiredEnv: [] },
  nonprofit: {
    mcpServer: "allocate-nonprofit",
    requiredEnv: ["PROPUBLICA_API_KEY"],
  },
  municipal: { mcpServer: "allocate-municipal", requiredEnv: [] },
  crime: { mcpServer: "allocate-crime", requiredEnv: [] },
};

7. CLI Tool

Package: @allocate/cli

The public launch exposes the read-only catalog commands below by default. It does not expose contributor writes or agent orchestration.

Code
allocate <command> [options]

  projects list / show <slug>          Browse public projects
  evidence search [query]              Search public evidence
  releases show / export <id>          Inspect public releases
  resources list / show <slug>         Browse public resources
  mcp stdio                            Serve the public catalog over stdio

Legacy contributor commands are intentionally absent from the public CLI. The public documentation provides no activation walkthrough for that compatibility surface; authenticated contribution uses the reviewed web and scoped MCP contracts and still requires separate public-write authorization.

Configuration: ~/.allocate/config.yaml

YAML
user:
  github_username: johnny_allocate
  auth_token_env: ALLOCATE_AUTH_TOKEN

neighborhoods:
  - slug: venice-la
    role: founder

agent:
  provider: anthropic
  model: claude-3.5-sonnet
  api_key_env: ANTHROPIC_API_KEY
  max_tokens_per_session: 50000
  max_cost_per_session_usd: 5.00
  schedule: { mode: daily, time: "02:00", timezone: America/Los_Angeles }
  focus_areas: [accessibility, environmental]
  output: { directory: ~/.allocate/output/, auto_submit: false }

defaults:
  neighborhood: venice-la

8. Web Application

Page Structure (Next.js App Router)

Code
(marketing)/           Landing, mission, docs, projects
(app)/
  dashboard/           User's cross-neighborhood view
  [neighborhood]/
    page.tsx           Neighborhood dashboard
    projects/          Project list → detail → findings
    findings/          Searchable finding list → detail
    domains/[domain]/  Domain-specific view
    volunteer/         Task board (Kanban) → detail + completion
    proposals/         Proposal list → detail + voting
    nonprofits/        Ecosystem map → detail
    municipal/         Government dashboard, council, budget, officials
    impact/            Impact dashboard with charts
    members/           Member list + trust network graph → profiles
    settings/          Neighborhood config (founder/admin)
  contribute/          Contribution hub + web-based agent runner
  settings/            User settings

Key Components

  • FindingCard — domain badge, title, confidence indicator, verification status, staleness, source count
  • TaskBoard — Kanban: Open → Claimed → In Progress → Completed → Verified
  • VoteWidget — For/against/abstain, live tally via Supabase Realtime, discussion thread
  • ImpactDashboard — Charts: tokens, hours, CO₂, findings merged, tasks completed, proposals passed
  • NeighborhoodMap — Interactive Mapbox map with toggleable layers (findings, tasks, nonprofits)
  • TrustNetwork — Force-directed graph showing vouch relationships

Realtime Features (Supabase Realtime)

  • Live vote updates on proposals
  • Live task claim/unclaim on task board
  • New finding toast notifications
  • Active agent session status

9. Session Artifact Materialization

The current POST /api/sync service route materializes terminal research sessions into work-log and ledger artifacts. A service token is required. The request may filter by neighborhood and terminal status, cap the batch size, or run in dry-run mode; each session reports its own success or failure.

This release has no /api/sync/repo-to-db endpoint, bidirectional Git/Supabase synchronization worker, or scheduled consistency workflow. Repository recovery and hosted data operations are operator-controlled runbook procedures. Public API behavior covers the current routes documented in API Routes.


10. Vouch Trust System Integration

Enhanced VOUCHED.td Format

Code
# VOUCHED.td — Venice, LA
# Trust policy: see allocate.yaml

# Founding members
github:johnny_allocate  founder                                    2026-02-08
github:maria_garcia     vouched by johnny_allocate "neighbor, community garden organizer"  2026-02-10

# Community members
github:david_chen       vouched by maria_garcia "completed 3 volunteer tasks, active in discussions"  2026-02-15
github:sarah_williams   vouched by johnny_allocate "local journalist, covers Venice council"  2026-02-12

# Stewards (Tier 2)
+github:maria_garcia    promoted by johnny_allocate "3 months active, 14 merged findings"  2026-05-10

# Nonconformities (confirmed; requires a cited standard and confirmation count)
-github:spam_account    NC by david_chen "Agent Contract §2: fabricated sources in rf-2026-03-01-004" confirmed:3  2026-03-15

# Pending nonconformity (under review; effective status awaits confirmation)
~github:questionable    NC by sarah_williams "Contribution Guidelines §4: possible plagiarism in rf-2026-04-02-001" confirmed:0  2026-04-02

# Trusted neighborhood lists (web of trust)
# @trust https://github.com/allocate/echo-park-la/blob/main/VOUCHED.td
# @trust https://github.com/allocate/mar-vista-la/blob/main/VOUCHED.td

Parsing Rules (Updated)

  • Lines starting with + = steward promotion (Tier 2)
  • Lines starting with - = confirmed nonconformity (effective, contributor blocked)
  • Lines starting with ~ = pending nonconformity (under review; effective status awaits confirmation)
  • Lines starting with # @trust <url> = inherit trust from another neighborhood
  • Dates at end of line = timestamp of action
  • Quoted strings = reason
  • confirmed:N = number of confirmations on nonconformities
  • Comments (lines starting with # without @trust) are ignored

Updated Database Schema

SQL
-- Replace the simple vouched_members table with a richer model

CREATE TABLE vouched_members (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  github_username TEXT NOT NULL,

  -- Trust tier: 0 = unvouched, 1 = vouched, 2 = steward
  trust_tier INTEGER NOT NULL DEFAULT 0 CHECK (trust_tier IN (0, 1, 2)),

  -- Status tracks the current state
  status TEXT NOT NULL CHECK (status IN ('pending', 'vouched', 'steward', 'nonconforming', 'nc_pending')),

  -- Vouch provenance
  vouched_by TEXT,                    -- github username of voucher
  vouch_reason TEXT,
  vouch_source TEXT DEFAULT 'direct', -- 'direct' or 'inherited:<neighborhood_slug>'

  -- Steward promotion
  promoted_by TEXT,
  promoted_at TIMESTAMPTZ,
  promotion_reason TEXT,

  -- Nonconformity tracking
  nc_issued_by TEXT,
  nc_basis TEXT,                        -- must cite specific community standard
  nc_confirmed_by TEXT[] DEFAULT '{}',          -- list of confirming usernames
  nc_confirmations_needed INTEGER DEFAULT 2,
  nc_review_deadline TIMESTAMPTZ,
  nc_contested BOOLEAN DEFAULT FALSE,

  -- Activity tracking (for steward promotion eligibility)
  first_contribution_at TIMESTAMPTZ,
  merged_findings_count INTEGER DEFAULT 0,
  completed_tasks_count INTEGER DEFAULT 0,
  months_active INTEGER DEFAULT 0,

  -- Metadata
  commit_sha TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),

  UNIQUE(neighborhood_id, github_username)
);

-- Vouch history (immutable audit log)
CREATE TABLE vouch_events (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  event_type TEXT NOT NULL CHECK (event_type IN (
    'vouch', 'nc_initiated', 'nc_confirmed', 'nc_effective',
    'nc_contested', 'nc_reversed', 'promote_steward', 'demote_steward'
  )),
  target_github TEXT NOT NULL,        -- who is being acted upon
  actor_github TEXT NOT NULL,         -- who is taking the action
  reason TEXT,
  commit_sha TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Monthly vouch rate limiting
CREATE TABLE vouch_rate_limits (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  voucher_github TEXT NOT NULL,
  month DATE NOT NULL,                -- first of month
  vouch_count INTEGER DEFAULT 0,
  UNIQUE(neighborhood_id, voucher_github, month)
);

-- Indexes
CREATE INDEX idx_vouched_neighborhood ON vouched_members(neighborhood_id);
CREATE INDEX idx_vouched_status ON vouched_members(status);
CREATE INDEX idx_vouched_tier ON vouched_members(trust_tier);
CREATE INDEX idx_vouch_events_target ON vouch_events(target_github);
CREATE INDEX idx_vouch_events_actor ON vouch_events(actor_github);
CREATE INDEX idx_vouch_events_neighborhood ON vouch_events(neighborhood_id);
CREATE INDEX idx_vouch_rate_neighborhood ON vouch_rate_limits(neighborhood_id);

Updated API Endpoints

Code
# Vouch & Trust
GET    /api/neighborhoods/:slug/members              # List all members with trust tiers
GET    /api/neighborhoods/:slug/members/:username     # Member detail + vouch history
POST   /api/neighborhoods/:slug/vouch                 # Vouch for user (rate limited)
POST   /api/neighborhoods/:slug/nonconformity          # Issue NC (requires standard citation)
POST   /api/neighborhoods/:slug/nonconformity/:id/confirm  # Confirm pending NC
POST   /api/neighborhoods/:slug/nonconformity/:id/contest  # Contest NC (corrective action request)
POST   /api/neighborhoods/:slug/promote               # Promote to steward (steward/founder only)
GET    /api/neighborhoods/:slug/trust-network          # Full trust graph data
GET    /api/neighborhoods/:slug/trust-policy           # Current trust configuration

# Tier 0 (unvouched) endpoints
POST   /api/neighborhoods/:slug/staging                # Submit unverified finding to staging
GET    /api/neighborhoods/:slug/staging                 # Browse staged/unverified findings
POST   /api/neighborhoods/:slug/tasks/:id/complete     # Complete task (no vouch needed)

Updated Web of Trust Resolution

Code
resolveUserTrust(username, neighborhood, maxDepth=2):
  1. Check local VOUCHED.td:
     - If 'nonconforming' → return { status: 'nonconforming', tier: 0, source: 'direct' }
     - If 'nc_pending' → return { status: 'active', tier: 1, source: 'direct', flag: 'nc_pending' }
     - If 'steward' → return { status: 'active', tier: 2, source: 'direct' }
     - If 'vouched' → return { status: 'active', tier: 1, source: 'direct' }

  2. For each @trust directive (up to maxDepth):
     a. Fetch trusted neighborhood's VOUCHED.td (with cycle detection via visited set)
     b. If user found as 'vouched' or 'steward' in trusted list:
        → return { status: 'active', tier: 1, source: 'inherited:<slug>', maxTier: 1 }
        (inherited trust has tier 1; steward status requires a direct record)
     c. If user found as 'nonconforming':
        → check neighborhood's trust policy for nc_propagation
        → if 'none': skip (don't import nonconformities)
        → if 'opt_in': return { status: 'nc_inherited', tier: 0, source: 'inherited:<slug>' }

  3. Not found → return { status: 'unknown', tier: 0 }

Updated Authorization Middleware

Code
requireTrust(request, neighborhoodSlug, minimumTier=1):
  trust = resolveUserTrust(request.user.github, neighborhoodSlug)

  if trust.tier < minimumTier:
    if minimumTier == 0:
      pass  // Tier 0 always allowed
    elif trust.status == 'nonconforming':
      return 403 { error: 'NONCONFORMING', basis: trust.nc_basis, contest_url: '...' }
    elif trust.status == 'unknown':
      return 403 { error: 'NOT_VOUCHED', onramp: 'Complete volunteer tasks or open a discussion to get involved' }
    elif trust.tier == 1 and minimumTier == 2:
      return 403 { error: 'STEWARD_REQUIRED' }

  request.trust = trust
  next()

Updated Permission Matrix

ActionMin TierNotes
Browse findings, tasks, proposals0Public
Open issues and discussions0GitHub account required
Comment on proposals0During discussion period
Complete volunteer tasks0Photo/evidence required
Submit to staging (unverified)0Clearly marked unverified
Submit finding PR1Requires review to merge
Run agent with auto-submit1Rate limited
Vote on proposals1One vote per user
Vouch for new users1Rate limited (3/month default)
Issue nonconformity1Requires cited standard, starts review
Claim tasks1
Approve/merge research PRs2Cannot merge own PRs
Confirm nonconformities2Independent review required
Modify neighborhood config2
Add @trust directives2
Promote to stewardFounder or steward consensus

Cross-Neighborhood Nonconformity Registry

The runtime authority is the Supabase public.nc_registry table. Reviewed /api/vouch/nc operations and their audit events are the supported mutation path. A neighborhood may retain a VOUCHED.td file as a provenance artifact. The Supabase table is the live authority for reviewed operations. This release ships no separate registry repository or automatic file-to-database sync.

Registry Schema

SQL
-- Cross-neighborhood nonconformity registry
CREATE TABLE nc_registry (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  github_username TEXT NOT NULL,
  neighborhood_id UUID REFERENCES neighborhoods(id) ON DELETE CASCADE,
  neighborhood_slug TEXT NOT NULL,
  reason TEXT NOT NULL,
  nc_issued_by TEXT NOT NULL,
  confirmed_by TEXT[] NOT NULL,
  confirmed_at TIMESTAMPTZ NOT NULL,
  contested BOOLEAN DEFAULT FALSE,
  reversed BOOLEAN DEFAULT FALSE,
  reversed_at TIMESTAMPTZ,
  reversal_reason TEXT,
  source_commit_sha TEXT,             -- commit in neighborhood repo
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_registry_username ON nc_registry(github_username);
CREATE INDEX idx_registry_neighborhood ON nc_registry(neighborhood_slug);
CREATE INDEX idx_registry_active ON nc_registry(github_username) WHERE reversed = FALSE;

Vouch and Nonconformity API

Code
GET    /api/vouch                                 # List vouch records
POST   /api/vouch                                 # Create a vouch record
GET    /api/vouch/:username                       # Read a contributor's vouch status
DELETE /api/vouch/:username                       # Remove a contributor's vouch record
POST   /api/vouch/nc                              # Record a nonconformity
POST   /api/vouch/nc/:id/confirm                  # Confirm a nonconformity
POST   /api/vouch/nc/:id/contest                  # Contest a nonconformity
POST   /api/vouch/nc/:id/reverse                  # Reverse a nonconformity

No /api/registry/* endpoint ships in this release.

Registry Sync Pipeline

The original blueprint proposed an automatic sync-on-merge workflow for VOUCHED.td. The current repository has no such workflow. Registry changes must use the reviewed application/database contracts and retain their provenance. Automatic Git-to-database synchronization requires separate implementation and release evidence.

Integration with Vouch Workflow

TypeScript
// Called before a vouch is committed
async function checkNonconformities(username: string): Promise<NCWarning[]> {
  const records = await registry.getActive(username);
  return records.map((r) => ({
    neighborhood: r.neighborhood_slug,
    reason: r.reason,
    confirmed_at: r.confirmed_at,
    nc_issued_by: r.nc_issued_by,
    confirmed_by: r.confirmed_by,
  }));
}

// In the vouch API handler
async function handleVouch(req: Request) {
  const warnings = await checkNonconformities(req.body.target_username);
  const policy = neighborhood.trust.cross_neighborhood_ncs.policy;

  if (warnings.length > 0) {
    if (policy === "hard_block") {
      return 403({ error: "PRIOR_NONCONFORMITY", warnings });
    }
    if (policy === "soft_block" && req.user.trust_tier < 2) {
      return 403({ error: "STEWARD_OVERRIDE_REQUIRED", warnings });
    }
    // advisory: log the override and proceed
    await logVouchWithWarnings(req, warnings);
  }

  // Proceed with vouch...
}

11. Impact Accounting Ledger

Design Philosophy

Raw resource inputs are immutable (recorded at time of action). Calculated impacts are recalculated whenever conversion factors improve. This means historical impact estimates get more accurate over time without changing the source data.

Conversion Factors (v1.0)

TypeScript
const CONVERSION_FACTORS_V1 = {
  version: "1.0",
  updated: "2026-02-08",

  // Energy per token (kWh) — varies by model
  energy_per_token: {
    "claude-3.5-sonnet": 0.000000035, // ~35 nJ/token
    "claude-3-opus": 0.00000009,
    "gpt-4o": 0.00000004,
    "gpt-4o-mini": 0.000000012,
    "llama-3-70b": 0.00000006,
    default: 0.00000004,
  },

  // Grid carbon intensity by region (kg CO₂/kWh)
  grid_intensity: {
    "us-west-2": 0.085, // Oregon (hydro)
    "us-east-1": 0.379, // Virginia (mixed)
    "us-west-1": 0.195, // California
    default: 0.4,
  },

  // PUE by provider
  pue: { anthropic: 1.1, openai: 1.1, google: 1.1, default: 1.2 },

  // Human travel (kg CO₂/km)
  travel_emissions: {
    walked: 0,
    biked: 0,
    transit: 0.089,
    drove: 0.217,
    remote: 0,
  },

  // Network (kWh/GB)
  network_energy_per_gb: 0.011,
};

Calculation

Code
For each ledger entry:
  compute_kwh = total_tokens × energy_per_token[model] × pue[provider]
  compute_co2 = compute_kwh × grid_intensity[region]
  travel_co2  = travel_km × travel_emissions[method]
  network_kwh = (total_tokens × 4 bytes / 1e9 GB) × network_energy_per_gb
  total_co2   = compute_co2 + travel_co2 + (network_kwh × grid_intensity[region])

Recalculation

POST /api/ledger is a service-token-only materialization/recalculation route that can target one session or a bounded status/neighborhood set. No weekly ledger workflow ships; invocation and any future scheduling require an explicitly reviewed operator path.

Impact Aggregation SQL

SQL
CREATE FUNCTION get_neighborhood_impact(p_neighborhood_id UUID, p_start DATE, p_end DATE)
RETURNS JSON -- totals: tokens, seconds, cost, hours, travel_km, kwh, co2, finding_count, etc.

12. CI/CD Pipeline

PR Validation (validate-pr.yml)

Triggered on pull-request changes. It classifies changed paths, checks supported changed-file formatting, requires evidence for protected public-contract changes, runs affected package type/tests, exercises repository scripts, and validates the launch-schema contract. It has read-only repository permissions and is not a deployment workflow.

Full Main Gate (full-gate.yml)

Triggered on pushes to main and manual dispatch. Independent jobs run the full application lint/test/build gate, replay the isolated local database and pgTAP suite, execute local production-build browser/accessibility/load checks, and run pinned secret/static-analysis scanners. Passing this workflow supplies CI evidence for one commit. Hosted-release evidence requires separate hosted verification.

Web Delivery

There is no automatic web-deployment workflow. Railway delivery is a separate, explicitly authorized operation pinned to an approved release fingerprint, with hosted migration, DNS/TLS, connector, and write enablement retained as separate gates.

Publish Packages (publish-packages.yml)

Manual dispatch only. It requires a public repository and pre-reserved npm names, builds/tests exact SDK, agent, MCP, and CLI tarballs, smoke-tests the tarballs, generates a pinned SBOM/checksum manifest and attestations, then stages the packages. Staging never publishes them; final npm promotion remains a separate human-approved action.


13. Authentication & Authorization

Auth Flow

Code
User clicks "Sign In"
  → Redirect to GitHub OAuth (Supabase Auth)
  → GitHub authenticates → callback to Supabase
  → Supabase issues JWT
  → Client sends JWT with all API requests
  → API validates JWT + checks vouch status per neighborhood

Permission Matrix (Three-Tier Model)

ActionMin TierAuthNotes
Browse findings, tasks, proposals0Public
Open issues and discussions0GitHub account required
Comment on proposals0During discussion period
Complete volunteer tasks0Photo/evidence required
Submit to staging (unverified)0Clearly marked unverified
Submit finding PR1Requires review to merge
Run agent with auto-submit1Rate limited
Vote on proposals1One vote per user
Vouch for new users1Rate limited (3/month default)
Issue nonconformity1Requires cited standard, starts review
Create proposal1
Create neighborhoodBecomes founder + first steward
Approve/merge research PRs2Cannot merge own PRs
Confirm nonconformities2Independent review required
Modify neighborhood config2
Add @trust directives2
Promote to stewardFounderOr steward consensus

Row Level Security

  • Public read on: findings, tasks, proposals, neighborhoods, staging
  • Tier 0 write on: staging findings, task completions, issues, discussion comments
  • Tier 1 write on: findings (as PRs), tasks, proposals, votes, vouches
  • Tier 2 write on: merge approvals, nonconformity confirmations, neighborhood config
  • One-vote-per-user enforced at DB level via UNIQUE constraint
  • Vouch rate limiting enforced at application level with DB tracking
  • Nonconformity confirmation requires different user than issuer

14. Output Validation Engine

Pipeline

Code
1. Parse YAML → error if malformed
2. Detect type field → error if unknown
3. Validate against Zod schema → field-level errors
4. Type-specific validation:
   - Findings: source quality, resource inputs present, staleness defaults
   - Tasks: location validity, expiration in future
   - Work logs: step sequence integrity, total reconciliation
5. Privacy scan (PII detection via regex patterns)
6. Legal sensitivity auto-detection (named entity check)
7. Return { valid, errors[], warnings[] }

PII Patterns Checked

  • Email addresses
  • Phone numbers (US format)
  • Social Security Numbers
  • Street addresses with house numbers

Validation Surface

Candidate artifacts use the shared SDK schema and authenticated validation contract. The legacy contributor CLI sits outside the public package surface. Local schema proof covers local behavior. Hosted write or publication readiness requires separate evidence.


15. Search & Discovery

Full-Text Search (PostgreSQL)

  • tsvector column on findings (title + summary + body + tags)
  • plainto_tsquery for user queries
  • ts_rank for relevance scoring
  • pg_trgm index on title for fuzzy matching

Spatial Search (PostGIS)

SQL
-- Find tasks near a location
SELECT id, title, urgency,
  ST_Distance(location::geography, ST_MakePoint(lon, lat)::geography) / 1000 AS distance_km
FROM volunteer_tasks
WHERE status = 'open'
  AND ST_DWithin(location::geography, ST_MakePoint(lon, lat)::geography, radius_m)
ORDER BY distance_km;

Faceted Filtering

Findings: domain, confidence, verification status, staleness, project, contributor Tasks: status, urgency, difficulty, skills, location, timeframe


16. Notification System

Types

CategoryEvents
Researchnew_finding, finding_stale, pr_merged, pr_rejected
Volunteertask_available (skill match), task_claimed, task_completed
Governanceproposal_open, proposal_closing_soon, proposal_result, vouched, nonconformity_issued
Agentagent_session_complete, agent_error, agent_budget_warning

Channels

  • In-app (always) — stored in notifications table
  • Email (configurable per type) — via Supabase Edge Function + Resend
  • Push (Phase 3) — via Expo notifications

17. Monitoring & Observability

Metrics

  • Liveness: exact release identity and bounded database probe
  • Protected-write readiness: OAuth/rate/control stores, reviewer, migration, capacity, and effective operating mode
  • Application telemetry: privacy-allowlisted server/edge events with the exact release identifier
  • External service metrics: Railway, Supabase, Redis, and Sentry evidence is environment-specific and must be verified after an authorized deployment

Health Check: GET /api/health

Returns only release-identity and database-liveness checks. GitHub, sync, ledger, capacity, OAuth, rate-store, and protected-write readiness belong to GET /api/ready.

Alerting

  • Sentry for allowlisted application events
  • Railway, Supabase, and Redis provider metrics after hosted verification
  • GitHub Actions failure notifications for repository gates
  • Required alert definitions are checked read-only; paging delivery still requires an accountable, separately configured recipient

18. Security Considerations

Threat Model

ThreatMitigation
Fabricated researchValidation + source verification + community review
Malicious vouchVouch rate limits + voucher accountability trail + nonconformity with confirmation
Bad actor neighborhood hoppingCross-neighborhood nonconformity registry (advisory/soft_block/hard_block)
PII in outputsAutomated PII scanner + privacy review tier
API key exposureEnv vars only, CLI uses OS keychain
Webhook spoofingGitHub signature verification
Vote manipulationOne vote per user (DB-enforced), vouch-gated
Data tampering in DBRLS, service-token boundaries, stable identifiers, audit events, and operator-controlled backups
DDoSRailway ingress controls plus bounded Upstash Redis rate policy; production load evidence is still required
Prompt injectionValidation sanitizes before web rendering
Agent runaway costToken budget + cost ceiling per session

Rate Limiting

  • Read endpoints: 100 requests/minute per IP
  • Write endpoints: 20 requests/minute per authenticated user
  • Webhook endpoint: bounded and signature-verified
  • Contribution writes: shared mode/rate boundaries apply; public-write release is separately authorized

19. Performance Requirements

MetricTarget
Page load (TTFB)< 200ms
API response (read)< 100ms
API response (write)< 500ms
Full-text search< 300ms
Spatial queries< 200ms
Session artifact materialization (per session)< 2s
Terminal-session materialization batch< 5 min
Validation (per file)< 1s
Concurrent users per neighborhood1000+
Findings per neighborhood100k+

20. Deployment Architecture

Production Stack

Code
Railway (Web App)
├── Next.js server and API routes
├── Static assets
└── Exact-fingerprint deployments after explicit authorization

Supabase (Database + Auth)
├── PostgreSQL 15 + PostGIS
├── Auth (GitHub OAuth)
├── Storage (evidence photos)
├── Edge Functions (async processing)
├── Realtime (live updates)
└── Pgbouncer (connection pooling)

GitHub (Source Control + CI)
├── allocate org
├── Neighborhood repos
├── Actions (CI/CD)
└── Webhooks → Railway-hosted web API

Upstash Redis (Rate Limiting)
Sentry (Error Tracking)
Railway service metrics (hosting)

Environment Variables

The committed .env.example is the authoritative variable catalog. The following matrix records the production boundary; values belong in the deployment platform or an approved secret store, never in this document.

Required for production validation

Shell
# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=

# Release identity
ALLOCATE_RELEASE_SHA=

# Shared rate limiting
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=

# Monitoring
SENTRY_DSN=

# Internal service credentials
SYNC_TOKEN=
CLI_JWT_SECRET=
ALLOCATE_AUTH_STATE_SECRET=

# Trusted production topology and operator control
ALLOCATE_TRUSTED_PROXY=railway
ALLOCATE_OPERATOR_TOKEN=
ALLOCATE_PLATFORM_REVIEWER_PROFILE_ID=

# Capacity policy (each metric is warning < scale-up < critical < write-disable)
ALLOCATE_CAPACITY_DATABASE_BYTES_WARNING=
ALLOCATE_CAPACITY_DATABASE_BYTES_SCALE_UP=
ALLOCATE_CAPACITY_DATABASE_BYTES_CRITICAL=
ALLOCATE_CAPACITY_DATABASE_BYTES_WRITE_DISABLE=
ALLOCATE_CAPACITY_MONTHLY_SPEND_CENTS_WARNING=
ALLOCATE_CAPACITY_MONTHLY_SPEND_CENTS_SCALE_UP=
ALLOCATE_CAPACITY_MONTHLY_SPEND_CENTS_CRITICAL=
ALLOCATE_CAPACITY_MONTHLY_SPEND_CENTS_WRITE_DISABLE=

Optional or separately gated controls

Shell
# MCP transport and OAuth discovery
MCP_ISSUER=
MCP_RESOURCE_URL=
ALLOCATE_MCP_AUTH_REQUIRED=0
ALLOCATE_MCP_ALLOWED_HOSTS=
ALLOCATE_MCP_ALLOWED_ORIGINS=
ALLOCATE_MCP_ALLOW_LOCALHOST=0
ALLOCATE_OAUTH_CHATGPT_REDIRECT_URIS=
ALLOCATE_OAUTH_CLAUDE_REDIRECT_URIS=
ALLOCATE_OAUTH_EXTRA_REDIRECT_URIS=
MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER=0
MCP_ACCESS_TOKEN_TTL_SECONDS=
MCP_REFRESH_TOKEN_TTL_SECONDS=
MCP_AUTHORIZATION_CODE_TTL_SECONDS=
ALLOCATE_OAUTH_ALLOW_DCR=0

# Web safety and operations
ALLOCATE_OPERATING_MODE_OVERRIDE=
ALLOCATE_WRITE_RETRY_AFTER_SECONDS=300
ALLOCATE_API_BODY_BYTES_MAX=1048576
ALLOCATE_CAPACITY_STATE_MAX_AGE_SECONDS=3600
SITE_UNDER_CONSTRUCTION=
ALLOCATE_ENABLE_WRITABLE_BETA=

# Optional Supabase GitHub OAuth and rotation values
SUPABASE_AUTH_GITHUB_CLIENT_ID=
SUPABASE_AUTH_GITHUB_SECRET=
NEXT_PUBLIC_SUPABASE_BROWSER_URL=
CLI_JWT_SECRET_PREVIOUS=

The MCP write flag opens only its separately gated OAuth route lane. Arbitrary API writes remain outside that authority. DCR remains default-off, and the legacy writable-beta flag is rejected by production validation. Local-only E2E, package, load, and provider credentials are documented in .env.example for local and CI use. Production configuration uses separately managed settings.

Agent and CLI process variables

Shell
# Provider credentials belong only in the agent process or approved secret store.
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
ALLOCATE_API_BASE_URL=
ALLOCATE_PROVIDER=
ALLOCATE_MODEL=
ALLOCATE_CONTRIBUTOR=
ALLOCATE_NEIGHBORHOOD=
ALLOCATE_API_KEY_ENV=
ALLOCATE_MAX_TOKENS=
ALLOCATE_MAX_COST_USD=
ALLOCATE_STATE_DIR=
ALLOCATE_MCP_TOKEN=

Local and CI-only variables

Shell
ALLOCATE_E2E_HOST=
ALLOCATE_E2E_PORT=
ALLOCATE_E2E_LOCAL_RATE_LIMIT=
ALLOCATE_LOAD_BASE_URL=
ALLOCATE_LOAD_PORT=
ALLOCATE_LOAD_REQUESTS=1000
ALLOCATE_LOAD_SURFACE=all
ALLOCATE_PACKAGE_TARBALL_DIR=
ALLOCATE_TUI_PYTHON=
NEXT_RUNTIME=
NO_COLOR=

These values select local test hosts, load-gate inputs, package artifacts, or runtime output behavior. They must not be used as hosted readiness or production-configuration evidence.


21. Testing Strategy

Test Pyramid

Code
           ┌──────────┐
           │   E2E    │  Playwright: critical user flows
           ├──────────┤
       ┌───┤Integration├───┐  Supabase + transport mocks
       │   ├──────────┤   │
       │   │   Unit   │   │  Zod schemas, validators, ledger calc
       └───┴──────────┴───┘

Unit Tests

  • Schema validation: every Zod schema tested with valid/invalid fixtures
  • PII scanner: known PII patterns detected, false positives checked
  • Ledger calculator: known inputs → expected CO₂ outputs
  • VOUCHED.td parser: edge cases (comments, nonconformities, trust directives)
  • Web of trust resolver: cycle detection, max depth, multi-hop resolution

Integration Tests

  • Disabled GitHub ingestion: fixed 410 without reading body/config or invoking fetch/database code
  • API routes: authenticated/unauthenticated/vouched/nonconforming scenarios
  • Vote counting: concurrent votes, duplicate prevention
  • Task lifecycle: open → claim → complete → verify

E2E Tests (Playwright)

  • Contributor flow: login → browse findings → view detail → verify
  • Volunteer flow: login → browse tasks → claim → complete → upload evidence
  • Governance flow: login → create proposal → vote → see results
  • Public CLI flow: allocate projects listallocate evidence searchallocate releases show

Test Data

  • Seed script (supabase/seed.sql) with realistic test neighborhood
  • Fixtures directory with sample YAML outputs (valid and intentionally invalid)
  • Mock GitHub API responses for webhook testing

22. Migration & Versioning Strategy

Database Migrations

Sequential SQL files in supabase/migrations/ are applied in numeric order. The current launch-compatibility tail is:

Code
00055_public_operations_limits_and_compatibility.sql
00056_atomic_finding_creation.sql
00057_sdk_metadata_limits_and_compatibility.sql
00058_finding_relationship_privacy.sql
00059_atomic_session_materialization.sql

The first fifty-four migrations remain part of the ordered history. A local or hosted target that stops before 00059 lacks the migration required by this candidate's protected-write readiness contract.

New migrations via: npx supabase migration new <name>

Schema Versioning

All output types include a version field. Schema evolution rules:

  • Additive changes (new optional fields): bump minor version, backward compatible
  • Breaking changes (field removal, type change): bump major version, migration required
  • Old versions validated with previous schema version during transition period
  • Version routers and SDK validators handle accepted versions; migrations and operator procedures handle stored-data transitions

API Versioning

  • /api/v1 is the current public read contract and preserves additive compatibility for existing fields and query aliases.
  • Breaking changes introduce an /api/v2/ prefix.
  • V1 maintained for 6 months after v2 launch

Package Versioning

  • Semantic versioning for all npm packages
  • @allocate/sdk version drives compatible agent/CLI versions
  • Lockstep releases for breaking changes

Appendix A: Neighborhood Data Repository Structure

Each neighborhood gets its own Git repo under allocate/:

Code
venice-la/
├── README.md                         # Neighborhood overview
├── VOUCHED.td                        # Trust list
├── allocate.yaml                     # Neighborhood config
│
├── projects/
│   └── sunset-blvd-bike-lane/
│       ├── README.md                 # Project description
│       ├── research/
│       │   ├── rf-2026-02-08-001.yaml
│       │   └── rf-2026-02-08-002.yaml
│       ├── verification/
│       │   └── tc-2026-02-09-001.yaml
│       └── proposals/
│           └── cp-2026-02-10-001.yaml
│
├── monitoring/
│   ├── municipal/
│   │   ├── council-agendas/
│   │   └── budgets/
│   └── nonprofits/
│       ├── registry/
│       └── 990-filings/
│
├── tasks/
│   ├── open/
│   │   └── vt-2026-02-08-001.yaml
│   └── completed/
│       └── vt-2026-02-07-001.yaml
│
├── logs/
│   └── log-2026-02-08-001.yaml
│
└── .github/
    └── workflows/
        └── validate.yml             # Inherits from main repo

Appendix B: Example Agent System Prompt

Code
You are an Allocate research agent working for the {neighborhood} community.

Your job is to research {domain} issues using public data sources and produce
structured findings that help residents understand their neighborhood.

## Rules (Agent Contract)
1. Flag uncertainty. Include confidence with justification.
2. Every claim must link to a verifiable primary source.
3. Record all resource inputs (tokens, API calls, cost, model, provider).
4. Never identify individuals. Aggregate vulnerable populations.
5. Stay in scope: only {neighborhood} / {project}.
6. Document every step, including what failed.
7. Separate factual findings from recommendations.
8. Fail gracefully. Log errors, produce partial findings, never fabricate.

## Dual-Output Requirement

Every finding MUST include BOTH:

### 1. Plain-Language Summary (REQUIRED)
Write for a resident with no technical or regulatory background.
- `tldr`: One sentence, max 280 characters. What's the problem in plain English?
- `situation`: What did you find? Be specific about locations and conditions.
- `impact`: Why should residents care? Who is affected?
- `recommendation`: What could be done about it?

Example:
  tldr: "The curb ramp at Venice Blvd and Pacific Ave is missing tactile warning strips, making it dangerous for visually impaired pedestrians."
  situation: "The curb ramp at the northwest corner of Venice Blvd and Pacific Ave was repaved. The detectable warning surface (truncated domes) was not reinstalled. The ramp surface is smooth concrete with no tactile or color contrast differentiation from the roadway."
  impact: "Visually impaired pedestrians cannot detect the transition from sidewalk to street, creating a serious safety hazard at a high-traffic intersection near the Venice library and senior center."
  recommendation: "File a complaint with LA Bureau of Street Services requesting installation of ADA-compliant detectable warning surfaces. Reference ADA Standard 406.13."

### 2. Conformity Assessment (STRONGLY ENCOURAGED)
Map your findings to formal standards whenever possible. This makes findings
usable in government filings, grant applications, public comment submissions,
and legal complaints. Always attempt to identify applicable standards. Research
the applicable standard when its scope is unclear.

For each applicable standard clause, assess:
- `status`: conforming / nonconforming / partially_conforming / not_assessed
- `severity`: observation (informational) / minor / major / critical
- `evidence`: Specific evidence supporting your assessment
- `corrective_action`: What would bring this into conformity

Common standards by domain:
- Accessibility: ADA 2010, CA Building Code 11B, MUTCD Ch 4E
- Environmental: CEQA, Clean Water Act, Clean Air Act, local ordinances
- Housing: Fair Housing Act, local rent stabilization, habitability standards
- Infrastructure: MUTCD, AASHTO, local complete streets policies
- Safety: OSHA, fire code, building code

If no formal standard applies, record that in `scope_note` and provide the
plain-language summary. A finding may use a community-defined standard from a
passed proposal when no formal regulation applies.

## Output Format
Produce a YAML file matching the ResearchFinding schema (v1.0).
Produce a separate YAML work log matching the AgentWorkLog schema (v1.0).

## Current Task
{task_description}

## Available Standards
{available_standards}

## Available Tools
{tool_descriptions}

Appendix C: Quick Start (Developer)

Shell
# Clone (private maintainer/invited-collaborator access)
git clone <maintainer-provided-private-origin>
cd allocate

# Install
corepack enable
pnpm install --frozen-lockfile

# Environment
cp .env.example apps/web/.env.local
# Keep real secrets out of Git; fill only the required local values.

# Named local database + deterministic local account/bootstrap
pnpm db:start
pnpm env:check

# Dev
pnpm dev

# CLI (separate terminal, only after separately authorized npm publication)
npm install --global @allocate/cli
# Default launch surface is public/read-only and needs no provider key:
allocate projects list --json
allocate resources list --json
# `allocate mcp stdio` exposes the same anonymous public catalog over stdio.

Allocate Technical Specification v0.1.0 — status reviewed August 14, 2026 MIT License; current source status: docs/PROJECT_STATUS.md