Skip to content

feat(scaffold): Tier 1 Items 1-3#1

Merged
ryaker merged 3 commits into
developfrom
feature/t1-scaffold
Feb 12, 2026
Merged

feat(scaffold): Tier 1 Items 1-3#1
ryaker merged 3 commits into
developfrom
feature/t1-scaffold

Conversation

@ryaker

@ryaker ryaker commented Feb 12, 2026

Copy link
Copy Markdown
Owner

Foundation scaffold: type system, config engine, and test infrastructure

Tier 1, Items 1–3 of the WSJF Implementation Plan
35 files changed · 3,630 insertions · 62 tests passing · clean tsc --noEmit


Context

Zora is a long-running autonomous AI agent for macOS — multi-provider, capability-routed, memory-enriched. The v0.5 spec defines an N-provider architecture where users stack-rank LLM providers (Claude, Gemini, OpenAI, local models) and the router matches tasks to the best available provider based on capabilities and cost tiers, with automatic failover down the ranked list.

This PR establishes the foundation that everything else builds on: the TypeScript type system, the TOML-based config engine, and the test infrastructure. Nothing in this PR runs an LLM or executes tasks — it's the skeleton and nervous system that Items 4–11 will wire up.


What's in this PR

1. Project scaffolding

Toolchain: Node 20+, ESM ("type": "module"), TypeScript 5.7 in strict mode with noUncheckedIndexedAccess and noUnusedLocals/noUnusedParameters, bundler module resolution, vitest for testing, tsx for dev execution.

Directory structure matches spec §4.3 — every module has its home:

src/
  cli/  config/  dashboard/  memory/  orchestrator/
  providers/  routines/  security/  steering/  teams/
  tools/  wasm/
  types.ts        ← single source of truth for all shared interfaces
  index.ts        ← entry point + re-exports
tests/
  unit/{config, providers, tools, orchestrator, security}/
  integration/
  fixtures/       ← reusable mocks + test configs

Empty directories tracked with .gitkeep files so the full structure is visible to anyone cloning the repo.

Single runtime dependency: smol-toml for TOML parsing (zero transitive deps, 15KB). DevDeps are typescript, vitest, tsx, and @types/node — nothing else.

2. Core type system (src/types.ts — 319 lines)

Every interface, type alias, and enum that the codebase shares lives in one file. This is the contract that providers, the router, the orchestrator, the policy engine, and the CLI all agree on.

Key types and the spec sections they implement:

Type Purpose Spec ref
LLMProvider Provider contract — execute() returns AsyncGenerator<AgentEvent> for streaming §4.2
AuthStatus / QuotaStatus Provider health signals that drive failover decisions §4.2
AgentEvent Unified event stream (thinking, tool_call, tool_result, text, error, done) §4.2
TaskContext Everything the router and provider need to execute a task — capabilities, complexity, resource type, history, memory §5.1
HandoffBundle Structured context package for provider failover — task, progress, artifacts, tool history §5.3
ZoraConfig Full config shape matching config.toml — agent, providers[], routing, failover, memory, security, steering, notifications §7
ZoraPolicy Security policy shape — filesystem paths, shell allowlist/denylist, action classifications, network rules §6
WorkerCapabilityToken Scoped permission subset for per-job sandboxing §6.3
ProviderCapability Extensible capability tags (reasoning, coding, creative, search, etc.) + custom strings §5.1
CostTier / RoutingMode / TaskComplexity Routing decision axes §5.1

Design choices:

  • ProviderCapability is a union with (string & {}) — you get autocomplete for the built-in tags but users can add arbitrary capability strings for custom providers without touching the type definition.
  • LLMProvider.execute() returns AsyncGenerator<AgentEvent> rather than a callback or observable — this gives the orchestrator natural for await...of consumption with backpressure, and makes testing trivial (just yield events in sequence).
  • All config sub-types are separate interfaces (AgentConfig, RoutingConfig, FailoverConfig, etc.) — this keeps validation functions focused and lets future code import just the slice it needs.

3. Config engine (src/config/)

Three files, clear responsibilities:

defaults.ts — Every default value from spec §7, exported as typed constants (DEFAULT_AGENT, DEFAULT_ROUTING, DEFAULT_FAILOVER, etc.) plus DEFAULT_CONFIG as the assembled whole. Also exports two validation functions:

  • validateProviderConfig(p, index) — checks required fields (name, type, rank ≥ 1, non-empty capabilities, valid cost tier) with indexed error messages
  • validateConfig(config) — validates agent settings (parallel jobs, CPU/memory limits), routing mode enum + provider_only constraint, provider name/rank uniqueness among enabled providers, failover bounds, steering port range

Both return string[] of error messages — empty array means valid. Errors are descriptive and reference the config path (e.g., "providers[2].rank is required and must be a positive integer").

loader.ts — TOML parsing and merge logic:

  • deepMerge(target, source) — recursive object merge where arrays are replaced (not concatenated) and source wins on conflicts
  • parseConfig(raw) — merges parsed TOML with defaults, handles TOML's [[providers]] array-of-tables syntax with per-provider defaults
  • loadConfig(path) — async file read → parse → validate → return or throw
  • loadConfigFromString(toml) — same pipeline but from a string (used in tests)
  • ConfigError — error class with .errors: string[] for aggregated validation failures

index.ts — barrel re-exports.

4. Test infrastructure

Mock provider (tests/fixtures/mock-provider.ts) — A full LLMProvider implementation with:

  • Configurable initial states (auth valid/invalid, quota healthy/exhausted, available/unavailable)
  • Assertion tracking (.executeCalls, .abortCalls, .authCheckCount, .quotaCheckCount)
  • failAfterEvents option for testing mid-execution failures
  • reset() to clear state between tests
  • Custom capability and cost tier injection

This mock will be reused by every test that touches the router, orchestrator, failover controller, or execution loop. It's designed so tests never need to spawn real subprocesses.

Test config fixturessample-config.toml (2-provider setup with Claude rank 1 + Gemini rank 2) and sample-policy.toml (filesystem + shell + actions + network rules).

62 tests across 3 suites:

Suite Tests What it covers
defaults.test.ts 27 Every default value matches spec, validateProviderConfig for all required fields and edge cases, validateConfig for routing modes, duplicate names/ranks, resource limits, failover bounds
loader.test.ts 12 File loading, string loading, deep merge preserving nested defaults, ConfigError aggregation, malformed TOML, missing file, providers array parsing
mock-provider.test.ts 23 Interface compliance (readonly props, all methods present), execution flow (thinking→text→done event sequence), auth/quota state changes, abort tracking, failure injection, reset

5. Documentation (from GPT 5.2 session)

  • specs/v5/docs/POLICY_PRESETS.md — Safe/Balanced/Power preset definitions for onboarding
  • specs/v5/docs/WEB_ONBOARDING_SPEC.md — Local web wizard spec (localhost config UI)
  • Updated specs/v5/docs/ONBOARDING_INSTALL.md — Presets, scope, dry-run sections

What's explicitly NOT in this PR

This is a foundation PR. These are all in scope for subsequent branches:

  • No LLM providersClaudeProvider, GeminiProvider come in feature/t1-claude-provider (Item 4)
  • No tool implementationsread_file, shell_exec, etc. come in feature/t1-core-tools (Items 5–6)
  • No execution loop — The agentic think-act-observe cycle comes in feature/t1-execution-loop (Items 7–8)
  • No CLI commandszora start, zora ask, etc. come in feature/t1-cli (Item 9)
  • No security enforcement — Policy engine, critical file protection, atomic writes come in feature/t1-protections (Items 10–11)

Design decisions worth noting

  1. Single types.ts file — Not split per module. At 319 lines it's manageable, and having one import path (../types.js) prevents circular dependency headaches as the codebase grows. Can be split later if it exceeds ~500 lines.

  2. smol-toml over @iarna/toml — Zero dependencies, smaller bundle, actively maintained, full TOML 1.0 spec compliance. The config file is the only user-facing file format in the system so the parser choice matters.

  3. Validation returns error arrays, not throwsvalidateConfig() and validateProviderConfig() collect all errors in a single pass. ConfigError wraps them with a human-readable count message. This means users see all their config problems at once instead of fixing one, re-running, hitting the next one.

  4. Deep merge replaces arrays — When your TOML overrides capabilities = ["coding"], you get exactly ["coding"], not ["reasoning", "coding", "creative", "coding"]. Array merge semantics cause subtle bugs in config systems.

  5. Provider defaults applied per-provider — Each [[providers]] entry gets enabled: true, cost_tier: "metered", rank: 0 as defaults before user values are applied. This means a minimal provider block only needs name, type, rank, and capabilities.

  6. AsyncGenerator for execution — The LLMProvider.execute() signature uses AsyncGenerator<AgentEvent> rather than callbacks or event emitters. This makes the orchestrator loop a simple for await (const event of provider.execute(task)) and testing is just yield statements in the mock.


How to verify

npm install        # install deps (smol-toml + devDeps)
npm test           # 62 tests, all passing
npm run lint       # tsc --noEmit — clean compile, zero warnings

What's next

Item 4: Claude Provider (feature/t1-claude-provider) — Implement ClaudeProvider against the LLMProvider interface using the @anthropic-ai/claude-agent-sdk. Mac session token auth, execute() as AsyncGenerator, dependency-injected queryFn for testability.

Full remaining Tier 1 roadmap: Items 4–11, estimated ~12 hours to a working single-provider agent that can zora ask "write me a blog post" and produce output.

ryaker-LG and others added 2 commits February 12, 2026 00:20
…, core interfaces

Implements WSJF items 1-3 from the implementation plan:
- Project scaffolding: package.json, tsconfig.json (strict), vitest, directory structure matching spec §4.3
- Config system: TOML parser (smol-toml), deep-merge defaults, validation with error aggregation
- Core TypeScript interfaces: LLMProvider, AuthStatus, QuotaStatus, AgentEvent, ProviderCapability, CostTier, TaskContext, HandoffBundle, AuditEvent, ZoraConfig, ZoraPolicy, WorkerCapabilityToken

Also includes:
- MockProvider test fixture with configurable auth/quota/failure behavior
- Sample config.toml and policy.toml test fixtures
- 62 passing tests across 3 test suites (defaults, loader, mock-provider)

TDD: tests written first, all green before commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…onboarding docs

- Add .gitkeep to all empty src/ and tests/ subdirectories so directory
  structure is tracked in git per spec §4.3
- Add HANDOFF.md with build status, relay notes for next agent
- Add policy presets doc (Safe/Balanced/Power) and web onboarding wizard spec
- Update ONBOARDING_INSTALL.md with preset selection, scope, dry-run sections
- Update README.md with links to new docs

Tests: 62 passing | TypeScript: clean compile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@codeant-ai

codeant-ai Bot commented Feb 12, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Feb 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t1-scaffold

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ryaker, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request lays the essential groundwork for the Zora autonomous AI agent by establishing its core architectural components. It introduces a robust TypeScript type system for defining shared interfaces, a flexible TOML-based configuration engine for managing agent settings, and a comprehensive test infrastructure to ensure reliability. These changes provide the fundamental skeleton and nervous system upon which all future agent functionalities, such as LLM providers and execution loops, will be built.

Highlights

  • Project Scaffolding: Established the foundational project structure, including package.json, tsconfig.json, vitest.config.ts, and a comprehensive directory layout with .gitkeep files.
  • Core Type System: Introduced src/types.ts as the single source of truth for all shared TypeScript interfaces, covering LLM providers, agent events, task contexts, and configuration.
  • Config Engine: Implemented a robust TOML-based configuration system in src/config/, featuring default values, deep merging logic, and comprehensive validation with detailed error reporting.
  • Test Infrastructure: Set up a dedicated testing environment using Vitest, including a flexible MockProvider fixture and sample configuration/policy files for thorough unit testing.
  • Documentation: Added and updated several documentation files (POLICY_PRESETS.md, WEB_ONBOARDING_SPEC.md, ONBOARDING_INSTALL.md, README.md) to reflect new features and onboarding guidance.
Changelog
  • HANDOFF.md
    • Added a new document detailing the contents of this PR and outlining next steps for development.
  • README.md
    • Updated the documentation links to include new onboarding and policy preset guides.
  • package-lock.json
    • Added the lock file to manage project dependencies.
  • package.json
    • Added the project manifest, defining dependencies, scripts, and metadata.
  • specs/v5/docs/ONBOARDING_INSTALL.md
    • Updated the installation guide with new steps for choosing safety presets, defining scope, shell permissions, and dry-run simulations.
  • specs/v5/docs/POLICY_PRESETS.md
    • Added a new document outlining predefined policy presets (Safe, Balanced, Power) for agent security.
  • specs/v5/docs/WEB_ONBOARDING_SPEC.md
    • Added a new specification document for a local web-based onboarding wizard.
  • src/config/defaults.ts
    • Added default configuration values and validation logic for various Zora components.
  • src/config/index.ts
    • Added an index file for exporting config-related modules.
  • src/config/loader.ts
    • Added the configuration loader, responsible for parsing TOML, merging defaults, and validating the final configuration.
  • src/index.ts
    • Added the main entry point for the Zora application, exporting core types.
  • src/types.ts
    • Added a comprehensive set of TypeScript interfaces and types for the Zora agent.
  • tests/fixtures/mock-provider.ts
    • Added a mock implementation of the LLMProvider interface for testing.
  • tests/fixtures/sample-config.toml
    • Added a sample TOML configuration file for use in tests.
  • tests/fixtures/sample-policy.toml
    • Added a sample TOML policy file for use in tests.
  • tests/unit/config/defaults.test.ts
    • Added unit tests to verify default configuration values and validation rules.
  • tests/unit/config/loader.test.ts
    • Added unit tests for the configuration loading and parsing logic.
  • tests/unit/providers/mock-provider.test.ts
    • Added unit tests for the mock LLM provider's functionality and interface compliance.
  • tsconfig.json
    • Added the TypeScript compiler configuration file.
  • vitest.config.ts
    • Added the Vitest test runner configuration file.
Activity
  • No specific activity (comments, reviews, progress updates) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Feb 12, 2026
@codeant-ai

codeant-ai Bot commented Feb 12, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request establishes a comprehensive foundation for the Zora project, including the project scaffolding, a robust TOML-based configuration system with validation, a detailed TypeScript type system, and a thorough test infrastructure with a well-designed mock provider. The code quality is excellent, with clear structure, modern TypeScript practices, and extensive test coverage. My review found only one minor issue related to a type definition not fully aligning with the documentation, which is a testament to the high quality of this foundational work.

Comment thread src/types.ts Outdated
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@ryaker

ryaker commented Feb 12, 2026

Copy link
Copy Markdown
Owner Author

@claude

@ryaker
ryaker merged commit edb2019 into develop Feb 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants