From c2a688ef9347521dd84517fe11c14405e388d819 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 04:08:58 -0400 Subject: [PATCH 1/9] docs: design local ollama architect agent --- ...-01-local-ollama-architect-agent-design.md | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-01-local-ollama-architect-agent-design.md diff --git a/docs/superpowers/specs/2026-07-01-local-ollama-architect-agent-design.md b/docs/superpowers/specs/2026-07-01-local-ollama-architect-agent-design.md new file mode 100644 index 00000000..7d1bbd5d --- /dev/null +++ b/docs/superpowers/specs/2026-07-01-local-ollama-architect-agent-design.md @@ -0,0 +1,165 @@ +# Local Ollama Architect Agent Design + +## Objective + +Add a production-quality local coding-model path to Project Infinity and Lawful +Nova using the Ollama models already installed on the workstation: + +- `qwen2.5-coder:3b` as the default +- `qwen2.5-coder:7b` as an explicit configuration option + +The work is delivered in three sequential stages: + +1. Create the `@aaes-os/architect-agent` workspace package. +2. Replace the root `src/model/OllamaProvider.ts` stub with a compatibility + adapter. +3. Restore and update the `lawful-nova-shell` source checkout. + +## Architecture + +### Workspace Package + +`packages/architect-agent` owns the TypeScript model-provider contract, +proposal schema, Ollama HTTP client, and governed architect-agent pipeline. +The package uses the workspace's existing Node.js 20, TypeScript, and Vitest +toolchain and adds no runtime dependency for HTTP or UUID generation. + +The Ollama client calls `/api/generate` with streaming disabled. It sends +deterministic generation options, including temperature and output-token +limits, and requests JSON output. The response is parsed and validated before +it enters the governance pipeline. + +### Root Compatibility Adapter + +The root `src/model/OllamaProvider.ts` preserves the existing +`ModelProvider.generate(prompt)` contract. It delegates generation to the +workspace package and returns the validated proposal shape expected by current +root consumers. + +The root adapter contains no hard-coded proposal and no independent HTTP +implementation. + +### Lawful Nova + +The current `E:\project-infi\lawful-nova-shell` directory contains generated +runtime artifacts and Python bytecode but not editable source. Its contents +will be preserved in a sibling backup directory. The editable source will be +restored from the dedicated `warheart1984-ctrl/agentic-coding-agent` +repository, using the latest branch that contains the desktop Node and local +model surfaces. + +The restored Python and Electron implementations remain native to their +language. They use the same observable configuration contract as the +TypeScript package: + +- Ollama base URL +- model name +- timeout +- temperature +- maximum output tokens + +The default becomes `qwen2.5-coder:3b`; `qwen2.5-coder:7b` remains selectable +through environment/configuration and the desktop model selector. + +## Public Contracts + +### Architect Agent Options + +The package accepts: + +- `baseUrl`: defaults to `http://127.0.0.1:11434` +- `model`: defaults to `qwen2.5-coder:3b` +- `timeoutMs`: finite positive integer +- `temperature`: finite number from 0 through 2 +- `maxTokens`: positive integer +- injectable `fetch` implementation for deterministic tests + +### Model Proposal + +A valid proposal contains: + +- `schemaVersion` equal to `"1"` +- a supported goal +- an operations array +- each operation has a non-empty relative file path +- operation type is `insert`, `update`, or `delete` +- insert/update content is non-empty +- delete content is absent or null + +Unknown fields are ignored only when they do not weaken these invariants. +Malformed or unsupported output is rejected before governance evaluation. + +### Error Contract + +The provider emits typed errors for: + +- invalid configuration +- request timeout +- network or HTTP failure +- empty model response +- malformed JSON +- proposal-schema violation + +Error messages may contain endpoint and status information but must not expose +environment variables, prompt contents, credentials, or complete provider +responses. + +## Data Flow + +1. A caller submits a coding prompt. +2. The provider builds the structured JSON prompt. +3. Ollama returns one non-streaming response. +4. The package extracts and validates the proposal. +5. The architect agent evaluates UCR constraints. +6. ALA normalizes the allowed operations. +7. Safety evaluates the normalized plan with the proposal and contract. +8. The envelope builder creates a deterministic proposal hash and audit + timestamp. +9. Replay re-evaluates the same governed decisions and reports drift. +10. The caller receives the proposal, envelope, replay result, and receipt. + +Model generation proposes changes only. It does not write files or execute +commands. + +## Testing + +The TypeScript package uses mocked HTTP for: + +- valid 3B response +- explicit 7B selection +- malformed JSON +- invalid proposal shape +- empty response +- non-success HTTP status +- network failure +- request timeout +- invalid provider options +- valid and rejected governed pipelines +- replay drift + +The root adapter receives a focused compatibility test. + +Lawful Nova verification includes: + +- Python provider and tool tests +- desktop Node tests +- configuration/default-model tests +- one opt-in live Ollama generation with `qwen2.5-coder:3b` + +The final readiness pass runs the complete available build and test commands, +checks CI syntax and package-lock consistency, scans changed files for secrets, +and reports both repository Git states separately. + +## Git Boundaries + +Project Infinity and `agentic-coding-agent` are separate publication targets. +Changes are committed only within their owning repository. Existing unrelated +changes are preserved and excluded from scoped commits. + +No branch is pushed directly to `main`. Push readiness requires: + +- successful build and tests +- no unintended staged files +- no generated binaries or model blobs in the patch +- confirmed remote and branch +- no hard-coded secrets From 2d6dccc107299056384d2f80f845cb0c4040da07 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 04:10:45 -0400 Subject: [PATCH 2/9] docs: plan local ollama architect agent --- ...2026-07-01-local-ollama-architect-agent.md | 404 ++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-01-local-ollama-architect-agent.md diff --git a/docs/superpowers/plans/2026-07-01-local-ollama-architect-agent.md b/docs/superpowers/plans/2026-07-01-local-ollama-architect-agent.md new file mode 100644 index 00000000..f4c0a7a2 --- /dev/null +++ b/docs/superpowers/plans/2026-07-01-local-ollama-architect-agent.md @@ -0,0 +1,404 @@ +# Local Ollama Architect Agent Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Build a tested `@aaes-os/architect-agent` package, replace the root Ollama stub with a package adapter, and restore and configure Lawful Nova for the installed Qwen coding models. + +**Architecture:** The TypeScript workspace package owns proposal parsing, Ollama transport, governance evaluation, deterministic envelope construction, and replay. The root provider delegates to that package. Lawful Nova keeps its Python and Electron adapters but follows the same default-model and generation-option contract. + +**Tech Stack:** Node.js 20, TypeScript 5, native `fetch`, Vitest, Python 3.12, pytest, Electron, Ollama + +--- + +## File Map + +### Project Infinity + +- Create `packages/architect-agent/package.json`: workspace package metadata and scripts. +- Create `packages/architect-agent/tsconfig.json`: composite TypeScript package build. +- Create `packages/architect-agent/vitest.config.ts`: package-local test discovery. +- Create `packages/architect-agent/src/types.ts`: proposal, contract, decision, envelope, and provider types. +- Create `packages/architect-agent/src/errors.ts`: typed provider error codes. +- Create `packages/architect-agent/src/proposal.ts`: strict runtime proposal validation. +- Create `packages/architect-agent/src/prompt.ts`: structured JSON generation prompt. +- Create `packages/architect-agent/src/ollamaProvider.ts`: native Ollama HTTP transport. +- Create `packages/architect-agent/src/governance.ts`: UCR, ALA, safety, envelope, and replay components. +- Create `packages/architect-agent/src/architectAgent.ts`: package orchestration entry point. +- Create `packages/architect-agent/src/index.ts`: public exports. +- Create `packages/architect-agent/src/*.test.ts`: deterministic unit and integration tests. +- Modify `tsconfig.base.json`: register the package workspace alias. +- Modify `vitest.config.ts`: register the package test alias. +- Modify `package.json`: add the package as the root compatibility dependency. +- Modify `src/model/ModelProvider.types.ts`: use a strict operation type. +- Modify `src/model/OllamaProvider.ts`: delegate to the workspace provider. +- Create `tests/model/OllamaProvider.test.ts`: verify root compatibility. + +### Lawful Nova + +- Preserve `E:\project-infi\lawful-nova-shell` as an artifact backup. +- Restore `warheart1984-ctrl/agentic-coding-agent` into `E:\project-infi\lawful-nova-shell`. +- Modify `nova/node/tools/local_model.py`: non-streaming Ollama generation, deterministic options, 3B default, and bounded output. +- Modify `nova/providers/provider_ollama.py`: 3B default with 7B configuration support. +- Modify `nova/config.py`: consistent 3B default. +- Modify desktop model-selection/configuration files: expose both installed Qwen models. +- Modify configuration and startup scripts: consistent model defaults. +- Modify Python and desktop tests: verify defaults, selection, payload shape, and parsing. + +### Readiness + +- Modify `.github/workflows/ci.yml` only if fresh verification proves the current workflow cannot install and run the workspace. +- Create no model files, generated binaries, credentials, or runtime caches. + +## Task 1: Package Contract and Proposal Validation + +**Files:** +- Create: `packages/architect-agent/package.json` +- Create: `packages/architect-agent/tsconfig.json` +- Create: `packages/architect-agent/vitest.config.ts` +- Create: `packages/architect-agent/src/types.ts` +- Create: `packages/architect-agent/src/errors.ts` +- Create: `packages/architect-agent/src/proposal.ts` +- Test: `packages/architect-agent/src/proposal.test.ts` + +- [ ] **Step 1: Write failing proposal-validation tests** + +Test valid insert/update/delete operations and reject unknown schema versions, +absolute paths, parent traversal, unsupported operation types, empty +insert/update content, and non-object model output. + +```ts +expect(parseModelProposal({ + schemaVersion: '1', + goal: 'refactor', + operations: [{ file: 'src/index.ts', type: 'update', content: 'export {};' }], +})).toEqual({ + schemaVersion: '1', + goal: 'refactor', + operations: [{ file: 'src/index.ts', type: 'update', content: 'export {};' }], +}); +expect(() => parseModelProposal({ + schemaVersion: '1', + goal: 'fix', + operations: [{ file: '../secret', type: 'update', content: 'x' }], +})).toThrowError(ArchitectAgentError); +``` + +- [ ] **Step 2: Run the test and verify red** + +Run: +`corepack pnpm exec vitest run packages/architect-agent/src/proposal.test.ts` + +Expected: FAIL because the package modules do not exist. + +- [ ] **Step 3: Implement strict package types and validator** + +Define: + +```ts +export type OperationType = 'insert' | 'update' | 'delete'; +export type ProposalGoal = 'refactor' | 'rewrite' | 'fix' | 'mutation'; +export interface ModelOperation { + file: string; + type: OperationType; + content?: string | null; +} +export interface ModelProposal { + schemaVersion: '1'; + goal: ProposalGoal; + operations: ModelOperation[]; +} +``` + +Use explicit type guards. Normalize path separators to `/`, reject absolute +paths and `..` segments, require non-empty content for insert/update, and +normalize delete content to `null`. + +- [ ] **Step 4: Run validator tests and package build** + +Run: +`corepack pnpm exec vitest run packages/architect-agent/src/proposal.test.ts` + +Run: +`corepack pnpm --filter @aaes-os/architect-agent build` + +Expected: both commands exit 0. + +## Task 2: Ollama Provider + +**Files:** +- Create: `packages/architect-agent/src/prompt.ts` +- Create: `packages/architect-agent/src/ollamaProvider.ts` +- Test: `packages/architect-agent/src/ollamaProvider.test.ts` + +- [ ] **Step 1: Write failing provider tests** + +Inject a mocked `fetch` and assert: + +```ts +expect(JSON.parse(String(init.body))).toMatchObject({ + model: 'qwen2.5-coder:3b', + stream: false, + format: 'json', + options: { temperature: 0, num_predict: 2048 }, +}); +``` + +Cover explicit `qwen2.5-coder:7b`, timeout, network failure, HTTP failure, +empty response, malformed JSON, and invalid proposal output. + +- [ ] **Step 2: Run the provider test and verify red** + +Run: +`corepack pnpm exec vitest run packages/architect-agent/src/ollamaProvider.test.ts` + +Expected: FAIL because `OllamaProvider` does not exist. + +- [ ] **Step 3: Implement native-fetch transport** + +Implement: + +```ts +export interface OllamaProviderOptions { + baseUrl?: string; + model?: string; + timeoutMs?: number; + temperature?: number; + maxTokens?: number; + fetch?: typeof globalThis.fetch; +} + +export class OllamaProvider { + async generate(prompt: string): Promise; +} +``` + +Use `AbortController`, `/api/generate`, `stream: false`, `format: 'json'`, +typed errors, and `parseModelProposal`. Do not include prompt or raw model +output in thrown error messages. + +- [ ] **Step 4: Run provider tests** + +Run: +`corepack pnpm exec vitest run packages/architect-agent/src/ollamaProvider.test.ts` + +Expected: all provider tests pass. + +## Task 3: Governed Architect Agent + +**Files:** +- Create: `packages/architect-agent/src/governance.ts` +- Create: `packages/architect-agent/src/architectAgent.ts` +- Create: `packages/architect-agent/src/index.ts` +- Test: `packages/architect-agent/src/governance.test.ts` +- Test: `packages/architect-agent/src/architectAgent.test.ts` + +- [ ] **Step 1: Write failing governance and orchestration tests** + +Verify allowed proposals pass, goal/file/operation violations fail closed, +operations normalize deterministically, safety rejects empty updates, proposal +hashes are stable for equivalent objects, and replay detects tampering. + +```ts +const result = await agent.run('Refactor src/index.ts', contract); +expect(result.envelope.ucrDecision.ok).toBe(true); +expect(result.envelope.safetyDecision.ok).toBe(true); +expect(result.replay.ok).toBe(true); +``` + +- [ ] **Step 2: Run the tests and verify red** + +Run: +`corepack pnpm exec vitest run packages/architect-agent/src/governance.test.ts packages/architect-agent/src/architectAgent.test.ts` + +Expected: FAIL because governance modules do not exist. + +- [ ] **Step 3: Implement the minimal governed pipeline** + +Implement pure `evaluateUcr`, `normalizeOperations`, `evaluateSafety`, +`buildEnvelope`, and `replayEnvelope` functions. Use a stable key-sorted JSON +serializer for the SHA-256 proposal hash. `ArchitectAgent.run` generates, +evaluates, and returns data without applying filesystem mutations. + +- [ ] **Step 4: Run package tests and build** + +Run: +`corepack pnpm --filter @aaes-os/architect-agent test` + +Run: +`corepack pnpm --filter @aaes-os/architect-agent build` + +Expected: all tests and compilation pass. + +- [ ] **Step 5: Commit the package** + +Stage only `packages/architect-agent`, `tsconfig.base.json`, +`vitest.config.ts`, and lockfile changes. Commit: + +`feat(architect-agent): add governed ollama provider` + +## Task 4: Root Provider Compatibility + +**Files:** +- Modify: `package.json` +- Modify: `tsconfig.base.json` +- Modify: `vitest.config.ts` +- Modify: `src/model/ModelProvider.types.ts` +- Modify: `src/model/OllamaProvider.ts` +- Create: `tests/model/OllamaProvider.test.ts` + +- [ ] **Step 1: Write a failing compatibility test** + +Mock injected fetch and assert the root provider returns a validated +`ModelProposal` rather than `{ raw: string }`. + +```ts +const proposal = await provider.generate('Fix src/index.ts'); +expect(proposal.goal).toBe('fix'); +expect(proposal.operations[0]?.file).toBe('src/index.ts'); +``` + +- [ ] **Step 2: Run the compatibility test and verify red** + +Run: +`corepack pnpm exec vitest run tests/model/OllamaProvider.test.ts` + +Expected: FAIL because the root provider is still a hard-coded stub. + +- [ ] **Step 3: Implement the compatibility adapter** + +Delegate to: + +```ts +import { + OllamaProvider as ArchitectOllamaProvider, + type OllamaProviderOptions, +} from '@aaes-os/architect-agent'; +``` + +Preserve the root class name and `generate(prompt)` interface. Add the +workspace dependency and aliases required by TypeScript and Vitest. + +- [ ] **Step 4: Run focused and workspace verification** + +Run: +`corepack pnpm exec vitest run tests/model/OllamaProvider.test.ts` + +Run: +`corepack pnpm run build` + +Run: +`corepack pnpm test` + +Expected: all commands exit 0. + +- [ ] **Step 5: Commit the adapter** + +Stage only the root provider contract, adapter, test, package metadata, +configuration, and lockfile. Commit: + +`feat(model): connect root provider to architect agent` + +## Task 5: Restore and Configure Lawful Nova + +**Files:** +- Preserve: `E:\project-infi\lawful-nova-shell` +- Restore: dedicated `agentic-coding-agent` source checkout +- Modify: local-model, provider, config, desktop, setup, and focused test files + +- [ ] **Step 1: Inventory and preserve the artifact-only directory** + +Resolve and print the source and backup absolute paths. Confirm both remain +under `E:\project-infi`. Rename the existing directory without deleting it. + +- [ ] **Step 2: Restore the dedicated repository** + +Clone: + +```powershell +git clone --branch codex/nova-desktop-node-quickstart ` + https://github.com/warheart1984-ctrl/agentic-coding-agent.git ` + E:\project-infi\lawful-nova-shell +``` + +Verify `git -C E:\project-infi\lawful-nova-shell rev-parse --show-toplevel` +returns that directory. + +- [ ] **Step 3: Run the source baseline** + +Run the repository's Python tests and desktop tests before edits. Record any +pre-existing failures without masking them. + +- [ ] **Step 4: Write failing model-default and payload tests** + +Assert that Python local generation uses: + +```python +{ + "model": "qwen2.5-coder:3b", + "prompt": prompt, + "stream": False, + "options": {"temperature": 0.2, "num_predict": 2048}, +} +``` + +Assert the provider and desktop defaults are 3B and both 3B/7B choices are +available. + +- [ ] **Step 5: Run focused tests and verify red** + +Run the exact Python and desktop test files containing the new assertions. +Expected: failures reference stale `phi3` or 7B defaults and missing +non-streaming options. + +- [ ] **Step 6: Implement consistent configuration** + +Update Python, Electron, JSON configuration, and startup scripts to use +`qwen2.5-coder:3b` by default while accepting +`qwen2.5-coder:7b` explicitly. Keep environment-variable overrides intact. + +- [ ] **Step 7: Run Lawful Nova tests** + +Run all Python tests, desktop tests, and repository verification scripts. +Expected: all source-controlled checks pass; unavailable optional services may +produce documented warnings only. + +- [ ] **Step 8: Run a live 3B smoke test** + +Confirm `ollama list` contains `qwen2.5-coder:3b`. Generate one bounded coding +proposal through the actual Lawful Nova adapter and validate its output. + +- [ ] **Step 9: Commit Lawful Nova changes** + +Stage only source, tests, and configuration. Scan staged content for secrets +and generated files. Commit: + +`feat(models): default local coding to qwen 3b` + +## Task 6: Final Readiness Audit + +**Files:** +- Modify: `.github/workflows/ci.yml` only if needed +- Modify: lockfiles only through package-manager commands + +- [ ] **Step 1: Verify Project Infinity** + +Run `corepack pnpm install --frozen-lockfile`, full build, full tests, +`git diff --check`, and a staged-secret scan. + +- [ ] **Step 2: Verify Lawful Nova** + +Run full Python tests, desktop tests, Windows verification, `git diff --check`, +and a staged-secret scan. + +- [ ] **Step 3: Audit Git publication boundaries** + +For each repository, report top-level path, branch, remote, commits ahead of +upstream, staged files, unstaged files, and untracked files. Confirm no model +blob, virtual environment, cache, packaged binary, or unrelated user file is +included. + +- [ ] **Step 4: Report push readiness** + +State `ready`, `ready with scoped push`, or `not ready` separately for Project +Infinity and Lawful Nova, citing fresh command outcomes and any remaining +blocker. From c6665334fade63c430538ac23d5d339b8f3759e0 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 04:22:59 -0400 Subject: [PATCH 3/9] feat(architect-agent): add governed ollama provider --- packages/architect-agent/package.json | 23 +++ .../src/architectAgent.test.ts | 52 ++++++ .../architect-agent/src/architectAgent.ts | 52 ++++++ packages/architect-agent/src/errors.ts | 20 +++ .../architect-agent/src/governance.test.ts | 114 ++++++++++++ packages/architect-agent/src/governance.ts | 147 +++++++++++++++ packages/architect-agent/src/index.ts | 27 +++ .../src/ollamaProvider.test.ts | 103 +++++++++++ .../architect-agent/src/ollamaProvider.ts | 167 ++++++++++++++++++ packages/architect-agent/src/prompt.ts | 12 ++ packages/architect-agent/src/proposal.test.ts | 68 +++++++ packages/architect-agent/src/proposal.ts | 82 +++++++++ packages/architect-agent/src/types.ts | 70 ++++++++ packages/architect-agent/tsconfig.json | 10 ++ packages/architect-agent/vitest.config.ts | 8 + 15 files changed, 955 insertions(+) create mode 100644 packages/architect-agent/package.json create mode 100644 packages/architect-agent/src/architectAgent.test.ts create mode 100644 packages/architect-agent/src/architectAgent.ts create mode 100644 packages/architect-agent/src/errors.ts create mode 100644 packages/architect-agent/src/governance.test.ts create mode 100644 packages/architect-agent/src/governance.ts create mode 100644 packages/architect-agent/src/index.ts create mode 100644 packages/architect-agent/src/ollamaProvider.test.ts create mode 100644 packages/architect-agent/src/ollamaProvider.ts create mode 100644 packages/architect-agent/src/prompt.ts create mode 100644 packages/architect-agent/src/proposal.test.ts create mode 100644 packages/architect-agent/src/proposal.ts create mode 100644 packages/architect-agent/src/types.ts create mode 100644 packages/architect-agent/tsconfig.json create mode 100644 packages/architect-agent/vitest.config.ts diff --git a/packages/architect-agent/package.json b/packages/architect-agent/package.json new file mode 100644 index 00000000..eec1d036 --- /dev/null +++ b/packages/architect-agent/package.json @@ -0,0 +1,23 @@ +{ + "name": "@aaes-os/architect-agent", + "version": "0.1.0", + "description": "Governed local coding agent with Ollama model support", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc -p tsconfig.json", + "test": "vitest run --config vitest.config.ts" + }, + "devDependencies": { + "@types/node": "^22.19.21", + "typescript": "^5.9.3", + "vitest": "^3.2.4" + } +} diff --git a/packages/architect-agent/src/architectAgent.test.ts b/packages/architect-agent/src/architectAgent.test.ts new file mode 100644 index 00000000..dfae3dc3 --- /dev/null +++ b/packages/architect-agent/src/architectAgent.test.ts @@ -0,0 +1,52 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { ArchitectAgent } from './architectAgent.js'; +import type { AgentContract, ModelProvider, ModelProposal } from './types.js'; + +const PROPOSAL: ModelProposal = { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: 'src/index.ts', type: 'update', content: 'export const fixed = true;' }], +}; + +const CONTRACT: AgentContract = { + goal: 'fix', + allowedOps: ['update'], + authorizedFiles: ['src/index.ts'], +}; + +describe('ArchitectAgent', () => { + it('generates and evaluates a governed proposal without applying it', async () => { + const generate = vi.fn().mockResolvedValue(PROPOSAL); + const agent = new ArchitectAgent({ + provider: { generate }, + now: () => new Date('2026-07-01T00:00:00.000Z'), + }); + + const result = await agent.run('Fix src/index.ts', CONTRACT); + + expect(generate).toHaveBeenCalledWith('Fix src/index.ts'); + expect(result.accepted).toBe(true); + expect(result.envelope.ucrDecision.ok).toBe(true); + expect(result.envelope.safetyDecision.ok).toBe(true); + expect(result.replay.ok).toBe(true); + expect(result.receipt.receiptId).toMatch(/^architect:/u); + expect(result).not.toHaveProperty('applied'); + }); + + it('returns a governed rejection for unauthorized model output', async () => { + const agent = new ArchitectAgent({ + provider: { generate: async () => PROPOSAL }, + now: () => new Date('2026-07-01T00:00:00.000Z'), + }); + + const result = await agent.run('Fix src/index.ts', { + ...CONTRACT, + authorizedFiles: [], + }); + + expect(result.accepted).toBe(false); + expect(result.envelope.ucrDecision.reasons).toEqual(['Unauthorized file: src/index.ts']); + expect(result.replay.ok).toBe(true); + }); +}); diff --git a/packages/architect-agent/src/architectAgent.ts b/packages/architect-agent/src/architectAgent.ts new file mode 100644 index 00000000..9f595ee0 --- /dev/null +++ b/packages/architect-agent/src/architectAgent.ts @@ -0,0 +1,52 @@ +import { hashStable, buildEnvelope, evaluateSafety, evaluateUcr, normalizeOperations, replayEnvelope } from './governance.js'; +import { OllamaProvider, type OllamaProviderOptions } from './ollamaProvider.js'; +import type { + AgentContract, + ArchitectAgentResult, + ModelProvider, +} from './types.js'; + +export interface ArchitectAgentOptions { + provider?: ModelProvider; + ollama?: OllamaProviderOptions; + now?: () => Date; +} + +export class ArchitectAgent { + private readonly provider: ModelProvider; + private readonly now: () => Date; + + constructor(options: ArchitectAgentOptions = {}) { + this.provider = options.provider ?? new OllamaProvider(options.ollama); + this.now = options.now ?? (() => new Date()); + } + + async run(prompt: string, contract: AgentContract): Promise { + const proposal = await this.provider.generate(prompt); + const ucrDecision = evaluateUcr(proposal, contract); + const alaPlan = normalizeOperations(proposal); + const safetyDecision = evaluateSafety(proposal); + const issuedAt = this.now().toISOString(); + const envelope = buildEnvelope( + proposal, + ucrDecision, + alaPlan, + safetyDecision, + issuedAt, + ); + const accepted = ucrDecision.ok && safetyDecision.ok; + + return { + accepted, + proposal, + envelope, + replay: replayEnvelope(envelope, contract), + receipt: { + receiptId: `architect:${hashStable({ envelope, accepted })}`, + proposalHash: envelope.proposalHash, + accepted, + issuedAt, + }, + }; + } +} diff --git a/packages/architect-agent/src/errors.ts b/packages/architect-agent/src/errors.ts new file mode 100644 index 00000000..7e66fb84 --- /dev/null +++ b/packages/architect-agent/src/errors.ts @@ -0,0 +1,20 @@ +export type ArchitectAgentErrorCode = + | 'INVALID_CONFIGURATION' + | 'INVALID_PROPOSAL' + | 'MODEL_RESPONSE_EMPTY' + | 'MODEL_RESPONSE_INVALID' + | 'OLLAMA_HTTP_ERROR' + | 'OLLAMA_NETWORK_ERROR' + | 'OLLAMA_TIMEOUT'; + +export class ArchitectAgentError extends Error { + readonly code: ArchitectAgentErrorCode; + readonly cause?: unknown; + + constructor(code: ArchitectAgentErrorCode, message: string, options: { cause?: unknown } = {}) { + super(message); + this.name = 'ArchitectAgentError'; + this.code = code; + this.cause = options.cause; + } +} diff --git a/packages/architect-agent/src/governance.test.ts b/packages/architect-agent/src/governance.test.ts new file mode 100644 index 00000000..639abcd5 --- /dev/null +++ b/packages/architect-agent/src/governance.test.ts @@ -0,0 +1,114 @@ +import { describe, expect, it } from 'vitest'; + +import { + buildEnvelope, + evaluateSafety, + evaluateUcr, + normalizeOperations, + replayEnvelope, +} from './governance.js'; +import type { AgentContract, ModelProposal } from './types.js'; + +const PROPOSAL: ModelProposal = { + schemaVersion: '1', + goal: 'refactor', + operations: [ + { file: 'src/z.ts', type: 'update', content: 'z' }, + { file: 'src/a.ts', type: 'insert', content: 'a' }, + ], +}; + +const CONTRACT: AgentContract = { + goal: 'refactor', + allowedOps: ['insert', 'update'], + authorizedFiles: ['src/a.ts', 'src/z.ts'], +}; + +describe('governance pipeline', () => { + it('authorizes matching goals, operations, and files', () => { + expect(evaluateUcr(PROPOSAL, CONTRACT)).toEqual({ ok: true, reasons: [] }); + }); + + it('fails closed for goal, operation, and file violations', () => { + const decision = evaluateUcr(PROPOSAL, { + goal: 'fix', + allowedOps: ['insert'], + authorizedFiles: ['src/a.ts'], + }); + + expect(decision.ok).toBe(false); + expect(decision.reasons).toEqual([ + 'Goal mismatch: expected fix', + 'Operation not allowed: update', + 'Unauthorized file: src/z.ts', + ]); + }); + + it('normalizes operations without mutating the proposal', () => { + const plan = normalizeOperations(PROPOSAL); + + expect(plan.operations.map((operation) => operation.file)).toEqual(['src/a.ts', 'src/z.ts']); + expect(PROPOSAL.operations.map((operation) => operation.file)).toEqual(['src/z.ts', 'src/a.ts']); + }); + + it('rejects unsafe content and workspace traversal', () => { + const decision = evaluateSafety({ + schemaVersion: '1', + goal: 'fix', + operations: [ + { file: 'src/empty.ts', type: 'update', content: '' }, + { file: '../outside.ts', type: 'delete', content: null }, + ], + }); + + expect(decision.ok).toBe(false); + expect(decision.violations).toEqual([ + 'update requires non-empty content: src/empty.ts', + 'Operation path escapes workspace: ../outside.ts', + ]); + }); + + it('builds stable proposal hashes for equivalent object key order', () => { + const first = buildEnvelope( + PROPOSAL, + evaluateUcr(PROPOSAL, CONTRACT), + normalizeOperations(PROPOSAL), + evaluateSafety(PROPOSAL), + '2026-07-01T00:00:00.000Z', + ); + const reordered = { + operations: PROPOSAL.operations.map(({ file, type, content }) => ({ content, type, file })), + goal: PROPOSAL.goal, + schemaVersion: PROPOSAL.schemaVersion, + } as ModelProposal; + const second = buildEnvelope( + reordered, + evaluateUcr(reordered, CONTRACT), + normalizeOperations(reordered), + evaluateSafety(reordered), + '2026-07-01T00:00:00.000Z', + ); + + expect(first.proposalHash).toBe(second.proposalHash); + }); + + it('detects proposal and plan drift during replay', () => { + const envelope = buildEnvelope( + PROPOSAL, + evaluateUcr(PROPOSAL, CONTRACT), + normalizeOperations(PROPOSAL), + evaluateSafety(PROPOSAL), + '2026-07-01T00:00:00.000Z', + ); + const tampered = { + ...envelope, + alaPlan: { operations: [] }, + }; + + expect(replayEnvelope(envelope, CONTRACT)).toEqual({ ok: true, violations: [] }); + expect(replayEnvelope(tampered, CONTRACT)).toEqual({ + ok: false, + violations: ['ALA plan drift'], + }); + }); +}); diff --git a/packages/architect-agent/src/governance.ts b/packages/architect-agent/src/governance.ts new file mode 100644 index 00000000..cefe418f --- /dev/null +++ b/packages/architect-agent/src/governance.ts @@ -0,0 +1,147 @@ +import { createHash } from 'node:crypto'; + +import type { + AgentContract, + AlaPlan, + GovernanceEnvelope, + ModelOperation, + ModelProposal, + ReplayResult, + SafetyDecision, + UcrDecision, +} from './types.js'; + +export function evaluateUcr(proposal: ModelProposal, contract: AgentContract): UcrDecision { + const reasons: string[] = []; + if (proposal.goal !== contract.goal) { + reasons.push(`Goal mismatch: expected ${contract.goal}`); + } + + for (const operation of proposal.operations) { + if (!contract.allowedOps.includes(operation.type)) { + reasons.push(`Operation not allowed: ${operation.type}`); + } + if (!contract.authorizedFiles.includes(operation.file)) { + reasons.push(`Unauthorized file: ${operation.file}`); + } + } + + return { ok: reasons.length === 0, reasons }; +} + +export function normalizeOperations(proposal: ModelProposal): AlaPlan { + return { + operations: proposal.operations + .map(cloneOperation) + .sort( + (left, right) => + left.file.localeCompare(right.file) || left.type.localeCompare(right.type), + ), + }; +} + +export function evaluateSafety(proposal: ModelProposal): SafetyDecision { + const violations: string[] = []; + for (const operation of proposal.operations) { + if ( + (operation.type === 'insert' || operation.type === 'update') && + (typeof operation.content !== 'string' || operation.content.trim().length === 0) + ) { + violations.push(`${operation.type} requires non-empty content: ${operation.file}`); + } + if (pathEscapesWorkspace(operation.file)) { + violations.push(`Operation path escapes workspace: ${operation.file}`); + } + } + return { ok: violations.length === 0, violations }; +} + +export function buildEnvelope( + proposal: ModelProposal, + ucrDecision: UcrDecision, + alaPlan: AlaPlan, + safetyDecision: SafetyDecision, + timestamp: string, +): GovernanceEnvelope { + return { + proposalHash: hashStable(proposal), + proposal: cloneProposal(proposal), + ucrDecision: { ok: ucrDecision.ok, reasons: [...ucrDecision.reasons] }, + alaPlan: { operations: alaPlan.operations.map(cloneOperation) }, + safetyDecision: { + ok: safetyDecision.ok, + violations: [...safetyDecision.violations], + }, + timestamp, + }; +} + +export function replayEnvelope( + envelope: GovernanceEnvelope, + contract: AgentContract, +): ReplayResult { + const violations: string[] = []; + if (hashStable(envelope.proposal) !== envelope.proposalHash) { + violations.push('Proposal hash drift'); + } + if (!sameJson(evaluateUcr(envelope.proposal, contract), envelope.ucrDecision)) { + violations.push('UCR decision drift'); + } + if (!sameJson(normalizeOperations(envelope.proposal), envelope.alaPlan)) { + violations.push('ALA plan drift'); + } + if (!sameJson(evaluateSafety(envelope.proposal), envelope.safetyDecision)) { + violations.push('Safety decision drift'); + } + if (Number.isNaN(Date.parse(envelope.timestamp))) { + violations.push('Invalid envelope timestamp'); + } + return { ok: violations.length === 0, violations }; +} + +export function hashStable(value: unknown): string { + return createHash('sha256').update(stableStringify(value), 'utf8').digest('hex'); +} + +function pathEscapesWorkspace(file: string): boolean { + const normalized = file.replaceAll('\\', '/'); + return ( + normalized.startsWith('/') || + /^[A-Za-z]:\//u.test(normalized) || + normalized.split('/').some((segment) => segment === '..') + ); +} + +function cloneProposal(proposal: ModelProposal): ModelProposal { + return { + schemaVersion: proposal.schemaVersion, + goal: proposal.goal, + operations: proposal.operations.map(cloneOperation), + }; +} + +function cloneOperation(operation: ModelOperation): ModelOperation { + return { + file: operation.file, + type: operation.type, + content: operation.content ?? null, + }; +} + +function sameJson(left: unknown, right: unknown): boolean { + return stableStringify(left) === stableStringify(right); +} + +function stableStringify(value: unknown): string { + if (Array.isArray(value)) { + return `[${value.map(stableStringify).join(',')}]`; + } + if (value !== null && typeof value === 'object') { + const record = value as Record; + return `{${Object.keys(record) + .sort() + .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`) + .join(',')}}`; + } + return JSON.stringify(value); +} diff --git a/packages/architect-agent/src/index.ts b/packages/architect-agent/src/index.ts new file mode 100644 index 00000000..3b14ef79 --- /dev/null +++ b/packages/architect-agent/src/index.ts @@ -0,0 +1,27 @@ +export { ArchitectAgent, type ArchitectAgentOptions } from './architectAgent.js'; +export { ArchitectAgentError, type ArchitectAgentErrorCode } from './errors.js'; +export { + buildEnvelope, + evaluateSafety, + evaluateUcr, + hashStable, + normalizeOperations, + replayEnvelope, +} from './governance.js'; +export { OllamaProvider, type OllamaProviderOptions } from './ollamaProvider.js'; +export { parseModelProposal } from './proposal.js'; +export type { + AgentContract, + AlaPlan, + ArchitectAgentResult, + ArchitectReceipt, + GovernanceEnvelope, + ModelOperation, + ModelProposal, + ModelProvider, + OperationType, + ProposalGoal, + ReplayResult, + SafetyDecision, + UcrDecision, +} from './types.js'; diff --git a/packages/architect-agent/src/ollamaProvider.test.ts b/packages/architect-agent/src/ollamaProvider.test.ts new file mode 100644 index 00000000..79aa4733 --- /dev/null +++ b/packages/architect-agent/src/ollamaProvider.test.ts @@ -0,0 +1,103 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { ArchitectAgentError } from './errors.js'; +import { OllamaProvider } from './ollamaProvider.js'; + +const VALID_PROPOSAL = { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: 'src/index.ts', type: 'update', content: 'export const fixed = true;' }], +}; + +describe('OllamaProvider', () => { + it('uses deterministic 3B defaults and parses a valid proposal', async () => { + const fetch = vi.fn().mockResolvedValue( + jsonResponse({ response: JSON.stringify(VALID_PROPOSAL) }), + ); + const provider = new OllamaProvider({ fetch }); + + await expect(provider.generate('Fix src/index.ts')).resolves.toEqual(VALID_PROPOSAL); + + expect(fetch).toHaveBeenCalledOnce(); + const [url, init] = fetch.mock.calls[0]!; + expect(url).toBe('http://127.0.0.1:11434/api/generate'); + expect(JSON.parse(String(init?.body))).toMatchObject({ + model: 'qwen2.5-coder:3b', + stream: false, + format: 'json', + options: { temperature: 0, num_predict: 2048 }, + }); + }); + + it('supports explicit 7B model selection', async () => { + const fetch = vi.fn().mockResolvedValue( + jsonResponse({ response: JSON.stringify(VALID_PROPOSAL) }), + ); + const provider = new OllamaProvider({ model: 'qwen2.5-coder:7b', fetch }); + + await provider.generate('Fix src/index.ts'); + + expect(JSON.parse(String(fetch.mock.calls[0]?.[1]?.body)).model).toBe('qwen2.5-coder:7b'); + }); + + it.each([ + ['empty model', { model: ' ' }], + ['invalid timeout', { timeoutMs: 0 }], + ['invalid temperature', { temperature: 3 }], + ['invalid token limit', { maxTokens: -1 }], + ])('rejects %s configuration', (_label, options) => { + expect(() => new OllamaProvider(options)).toThrowError(ArchitectAgentError); + }); + + it('rejects non-success HTTP responses without exposing the prompt', async () => { + const fetch = vi.fn().mockResolvedValue( + new Response('private provider body', { status: 500 }), + ); + const provider = new OllamaProvider({ fetch }); + + await expect(provider.generate('private prompt')).rejects.toMatchObject({ + code: 'OLLAMA_HTTP_ERROR', + }); + await expect(provider.generate('private prompt')).rejects.not.toThrow(/private/u); + }); + + it('classifies network failures', async () => { + const fetch = vi.fn().mockRejectedValue(new Error('connection refused')); + const provider = new OllamaProvider({ fetch }); + + await expect(provider.generate('Fix it')).rejects.toMatchObject({ + code: 'OLLAMA_NETWORK_ERROR', + }); + }); + + it('classifies request timeouts', async () => { + const fetch = vi.fn().mockImplementation((_url, init) => { + return new Promise((_resolve, reject) => { + init?.signal?.addEventListener('abort', () => reject(new DOMException('Aborted', 'AbortError'))); + }); + }); + const provider = new OllamaProvider({ fetch, timeoutMs: 5 }); + + await expect(provider.generate('Fix it')).rejects.toMatchObject({ + code: 'OLLAMA_TIMEOUT', + }); + }); + + it.each([ + ['empty response', { response: '' }, 'MODEL_RESPONSE_EMPTY'], + ['malformed JSON', { response: '{bad' }, 'MODEL_RESPONSE_INVALID'], + ['invalid proposal', { response: JSON.stringify({ goal: 'fix' }) }, 'INVALID_PROPOSAL'], + ])('rejects %s', async (_label, responseBody, code) => { + const fetch = vi.fn().mockResolvedValue(jsonResponse(responseBody)); + const provider = new OllamaProvider({ fetch }); + + await expect(provider.generate('Fix it')).rejects.toMatchObject({ code }); + }); +}); + +function jsonResponse(value: unknown): Response { + return new Response(JSON.stringify(value), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); +} diff --git a/packages/architect-agent/src/ollamaProvider.ts b/packages/architect-agent/src/ollamaProvider.ts new file mode 100644 index 00000000..d495de4a --- /dev/null +++ b/packages/architect-agent/src/ollamaProvider.ts @@ -0,0 +1,167 @@ +import { ArchitectAgentError } from './errors.js'; +import { buildStructuredProposalPrompt } from './prompt.js'; +import { parseModelProposal } from './proposal.js'; +import type { ModelProposal, ModelProvider } from './types.js'; + +const DEFAULT_BASE_URL = 'http://127.0.0.1:11434'; +const DEFAULT_MODEL = 'qwen2.5-coder:3b'; +const DEFAULT_TIMEOUT_MS = 120_000; +const DEFAULT_TEMPERATURE = 0; +const DEFAULT_MAX_TOKENS = 2048; + +export interface OllamaProviderOptions { + baseUrl?: string; + model?: string; + timeoutMs?: number; + temperature?: number; + maxTokens?: number; + fetch?: typeof globalThis.fetch; +} + +interface OllamaGenerateResponse { + response?: unknown; +} + +export class OllamaProvider implements ModelProvider { + readonly baseUrl: string; + readonly model: string; + readonly timeoutMs: number; + readonly temperature: number; + readonly maxTokens: number; + + private readonly fetchImplementation: typeof globalThis.fetch; + + constructor(options: OllamaProviderOptions = {}) { + this.baseUrl = validateBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL); + this.model = validateModel(options.model ?? DEFAULT_MODEL); + this.timeoutMs = validatePositiveInteger(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, 'timeoutMs'); + this.temperature = validateTemperature(options.temperature ?? DEFAULT_TEMPERATURE); + this.maxTokens = validatePositiveInteger(options.maxTokens ?? DEFAULT_MAX_TOKENS, 'maxTokens'); + this.fetchImplementation = options.fetch ?? globalThis.fetch; + } + + async generate(prompt: string): Promise { + if (typeof prompt !== 'string' || prompt.trim().length === 0) { + throw new ArchitectAgentError('INVALID_CONFIGURATION', 'Prompt must be a non-empty string'); + } + + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), this.timeoutMs); + try { + const response = await this.fetchImplementation(`${this.baseUrl}/api/generate`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + model: this.model, + prompt: buildStructuredProposalPrompt(prompt), + stream: false, + format: 'json', + options: { + temperature: this.temperature, + num_predict: this.maxTokens, + }, + }), + signal: controller.signal, + }); + + if (!response.ok) { + throw new ArchitectAgentError( + 'OLLAMA_HTTP_ERROR', + `Ollama request failed with HTTP ${response.status}`, + ); + } + + const data = await parseResponseEnvelope(response); + if (typeof data.response !== 'string' || data.response.trim().length === 0) { + throw new ArchitectAgentError('MODEL_RESPONSE_EMPTY', 'Ollama returned an empty response'); + } + + let proposal: unknown; + try { + proposal = JSON.parse(data.response); + } catch (error) { + throw new ArchitectAgentError( + 'MODEL_RESPONSE_INVALID', + 'Ollama returned malformed JSON', + { cause: error }, + ); + } + return parseModelProposal(proposal); + } catch (error) { + if (error instanceof ArchitectAgentError) { + throw error; + } + if (controller.signal.aborted || isAbortError(error)) { + throw new ArchitectAgentError('OLLAMA_TIMEOUT', 'Ollama request timed out', { cause: error }); + } + throw new ArchitectAgentError('OLLAMA_NETWORK_ERROR', 'Ollama request failed', { + cause: error, + }); + } finally { + clearTimeout(timeout); + } + } +} + +async function parseResponseEnvelope(response: Response): Promise { + try { + const value: unknown = await response.json(); + if (value === null || typeof value !== 'object' || Array.isArray(value)) { + throw new Error('Response envelope must be an object'); + } + return value as OllamaGenerateResponse; + } catch (error) { + throw new ArchitectAgentError( + 'MODEL_RESPONSE_INVALID', + 'Ollama returned an invalid response envelope', + { cause: error }, + ); + } +} + +function validateBaseUrl(value: string): string { + try { + const parsed = new URL(value); + if (!['http:', 'https:'].includes(parsed.protocol)) { + throw new Error('Unsupported protocol'); + } + return parsed.toString().replace(/\/$/u, ''); + } catch (error) { + throw new ArchitectAgentError( + 'INVALID_CONFIGURATION', + 'baseUrl must be a valid HTTP URL', + { cause: error }, + ); + } +} + +function validateModel(value: string): string { + if (typeof value !== 'string' || value.trim().length === 0) { + throw new ArchitectAgentError('INVALID_CONFIGURATION', 'model must be a non-empty string'); + } + return value.trim(); +} + +function validatePositiveInteger(value: number, name: string): number { + if (!Number.isSafeInteger(value) || value <= 0) { + throw new ArchitectAgentError( + 'INVALID_CONFIGURATION', + `${name} must be a positive integer`, + ); + } + return value; +} + +function validateTemperature(value: number): number { + if (!Number.isFinite(value) || value < 0 || value > 2) { + throw new ArchitectAgentError( + 'INVALID_CONFIGURATION', + 'temperature must be between 0 and 2', + ); + } + return value; +} + +function isAbortError(error: unknown): boolean { + return error instanceof Error && error.name === 'AbortError'; +} diff --git a/packages/architect-agent/src/prompt.ts b/packages/architect-agent/src/prompt.ts new file mode 100644 index 00000000..56de9c3d --- /dev/null +++ b/packages/architect-agent/src/prompt.ts @@ -0,0 +1,12 @@ +export function buildStructuredProposalPrompt(userPrompt: string): string { + return [ + 'You are a deterministic coding proposal engine.', + 'Return only valid JSON with this exact shape:', + '{"schemaVersion":"1","goal":"refactor|rewrite|fix|mutation","operations":[{"file":"relative/path","type":"insert|update|delete","content":"string or null"}]}', + 'Use workspace-relative paths. Never include markdown, prose, or code fences.', + 'Insert and update operations require non-empty content. Delete operations use null content.', + '', + 'Task:', + userPrompt, + ].join('\n'); +} diff --git a/packages/architect-agent/src/proposal.test.ts b/packages/architect-agent/src/proposal.test.ts new file mode 100644 index 00000000..adbcdab4 --- /dev/null +++ b/packages/architect-agent/src/proposal.test.ts @@ -0,0 +1,68 @@ +import { describe, expect, it } from 'vitest'; + +import { ArchitectAgentError } from './errors.js'; +import { parseModelProposal } from './proposal.js'; + +describe('parseModelProposal', () => { + it('accepts and normalizes supported operations', () => { + expect( + parseModelProposal({ + schemaVersion: '1', + goal: 'refactor', + operations: [ + { file: 'src\\index.ts', type: 'update', content: 'export {};' }, + { file: 'src/new.ts', type: 'insert', content: 'export const value = 1;' }, + { file: 'src/old.ts', type: 'delete' }, + ], + }), + ).toEqual({ + schemaVersion: '1', + goal: 'refactor', + operations: [ + { file: 'src/index.ts', type: 'update', content: 'export {};' }, + { file: 'src/new.ts', type: 'insert', content: 'export const value = 1;' }, + { file: 'src/old.ts', type: 'delete', content: null }, + ], + }); + }); + + it.each([ + ['non-object output', null], + ['unknown schema', { schemaVersion: '2', goal: 'fix', operations: [] }], + ['unknown goal', { schemaVersion: '1', goal: 'deploy', operations: [] }], + [ + 'absolute path', + { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: 'C:\\secret.txt', type: 'update', content: 'x' }], + }, + ], + [ + 'parent traversal', + { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: '../secret.txt', type: 'update', content: 'x' }], + }, + ], + [ + 'unsupported operation', + { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: 'src/index.ts', type: 'execute', content: 'x' }], + }, + ], + [ + 'empty update', + { + schemaVersion: '1', + goal: 'fix', + operations: [{ file: 'src/index.ts', type: 'update', content: ' ' }], + }, + ], + ])('rejects %s', (_label, value) => { + expect(() => parseModelProposal(value)).toThrowError(ArchitectAgentError); + }); +}); diff --git a/packages/architect-agent/src/proposal.ts b/packages/architect-agent/src/proposal.ts new file mode 100644 index 00000000..4ec267e8 --- /dev/null +++ b/packages/architect-agent/src/proposal.ts @@ -0,0 +1,82 @@ +import { ArchitectAgentError } from './errors.js'; +import { + OPERATION_TYPES, + PROPOSAL_GOALS, + type ModelOperation, + type ModelProposal, + type OperationType, + type ProposalGoal, +} from './types.js'; + +export function parseModelProposal(value: unknown): ModelProposal { + const record = requireRecord(value, 'Model output must be a JSON object'); + if (record.schemaVersion !== '1') { + invalid('Unsupported proposal schema version'); + } + if (!isProposalGoal(record.goal)) { + invalid('Unsupported proposal goal'); + } + if (!Array.isArray(record.operations)) { + invalid('Proposal operations must be an array'); + } + + return { + schemaVersion: '1', + goal: record.goal, + operations: record.operations.map((operation, index) => parseOperation(operation, index)), + }; +} + +function parseOperation(value: unknown, index: number): ModelOperation { + const record = requireRecord(value, `Operation ${index} must be an object`); + const file = normalizeRelativePath(record.file, index); + if (!isOperationType(record.type)) { + invalid(`Operation ${index} has an unsupported type`); + } + + if (record.type === 'delete') { + if (record.content !== undefined && record.content !== null) { + invalid(`Delete operation ${index} must not contain content`); + } + return { file, type: record.type, content: null }; + } + + if (typeof record.content !== 'string' || record.content.trim().length === 0) { + invalid(`${record.type} operation ${index} requires non-empty content`); + } + return { file, type: record.type, content: record.content }; +} + +function normalizeRelativePath(value: unknown, index: number): string { + if (typeof value !== 'string' || value.trim().length === 0) { + invalid(`Operation ${index} requires a file path`); + } + const normalized = value.replaceAll('\\', '/'); + if ( + normalized.startsWith('/') || + /^[A-Za-z]:\//u.test(normalized) || + normalized.split('/').some((segment) => segment === '..') + ) { + invalid(`Operation ${index} file path must stay inside the workspace`); + } + return normalized; +} + +function requireRecord(value: unknown, message: string): Record { + if (value === null || typeof value !== 'object' || Array.isArray(value)) { + invalid(message); + } + return value as Record; +} + +function isProposalGoal(value: unknown): value is ProposalGoal { + return typeof value === 'string' && (PROPOSAL_GOALS as readonly string[]).includes(value); +} + +function isOperationType(value: unknown): value is OperationType { + return typeof value === 'string' && (OPERATION_TYPES as readonly string[]).includes(value); +} + +function invalid(message: string): never { + throw new ArchitectAgentError('INVALID_PROPOSAL', message); +} diff --git a/packages/architect-agent/src/types.ts b/packages/architect-agent/src/types.ts new file mode 100644 index 00000000..d1b8313b --- /dev/null +++ b/packages/architect-agent/src/types.ts @@ -0,0 +1,70 @@ +export const PROPOSAL_GOALS = ['refactor', 'rewrite', 'fix', 'mutation'] as const; +export const OPERATION_TYPES = ['insert', 'update', 'delete'] as const; + +export type ProposalGoal = (typeof PROPOSAL_GOALS)[number]; +export type OperationType = (typeof OPERATION_TYPES)[number]; + +export interface ModelOperation { + file: string; + type: OperationType; + content?: string | null; +} + +export interface ModelProposal { + schemaVersion: '1'; + goal: ProposalGoal; + operations: ModelOperation[]; +} + +export interface ModelProvider { + generate(prompt: string): Promise; +} + +export interface AgentContract { + goal: ProposalGoal; + allowedOps: OperationType[]; + authorizedFiles: string[]; +} + +export interface UcrDecision { + ok: boolean; + reasons: string[]; +} + +export interface AlaPlan { + operations: ModelOperation[]; +} + +export interface SafetyDecision { + ok: boolean; + violations: string[]; +} + +export interface GovernanceEnvelope { + proposalHash: string; + proposal: ModelProposal; + ucrDecision: UcrDecision; + alaPlan: AlaPlan; + safetyDecision: SafetyDecision; + timestamp: string; +} + +export interface ReplayResult { + ok: boolean; + violations: string[]; +} + +export interface ArchitectReceipt { + receiptId: string; + proposalHash: string; + accepted: boolean; + issuedAt: string; +} + +export interface ArchitectAgentResult { + accepted: boolean; + proposal: ModelProposal; + envelope: GovernanceEnvelope; + replay: ReplayResult; + receipt: ArchitectReceipt; +} diff --git a/packages/architect-agent/tsconfig.json b/packages/architect-agent/tsconfig.json new file mode 100644 index 00000000..807e895b --- /dev/null +++ b/packages/architect-agent/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "composite": true + }, + "include": ["src/**/*.ts"], + "exclude": ["dist", "node_modules", "src/**/*.test.ts"] +} diff --git a/packages/architect-agent/vitest.config.ts b/packages/architect-agent/vitest.config.ts new file mode 100644 index 00000000..96eb6ab4 --- /dev/null +++ b/packages/architect-agent/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['src/**/*.test.ts'], + environment: 'node', + }, +}); From 004c20ff3a5f481dcaa94c1732e54aca3215ac99 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 04:25:31 -0400 Subject: [PATCH 4/9] feat(model): connect root provider to architect agent --- aaes-os/package-lock.json | 16 + aaes-os/package.json | 6 +- aaes-os/src/model/ModelProvider.types.ts | 7 + aaes-os/src/model/OllamaProvider.ts | 20 + aaes-os/tests/OllamaProvider.test.ts | 31 + packages/architect-agent/package-lock.json | 1657 ++++++++++++++++++++ 6 files changed, 1736 insertions(+), 1 deletion(-) create mode 100644 aaes-os/src/model/ModelProvider.types.ts create mode 100644 aaes-os/src/model/OllamaProvider.ts create mode 100644 aaes-os/tests/OllamaProvider.test.ts create mode 100644 packages/architect-agent/package-lock.json diff --git a/aaes-os/package-lock.json b/aaes-os/package-lock.json index 6b7a6351..3cbb8040 100644 --- a/aaes-os/package-lock.json +++ b/aaes-os/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "@aais/aaes-os", "version": "1.0.0", + "dependencies": { + "@aaes-os/architect-agent": "file:../packages/architect-agent" + }, "devDependencies": { "@types/node": "^22.19.21", "typescript": "^5.9.3" @@ -15,6 +18,19 @@ "node": ">=20" } }, + "../packages/architect-agent": { + "name": "@aaes-os/architect-agent", + "version": "0.1.0", + "devDependencies": { + "@types/node": "^22.19.21", + "typescript": "^5.9.3", + "vitest": "^3.2.4" + } + }, + "node_modules/@aaes-os/architect-agent": { + "resolved": "../packages/architect-agent", + "link": true + }, "node_modules/@types/node": { "version": "22.19.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.21.tgz", diff --git a/aaes-os/package.json b/aaes-os/package.json index 0d957433..f04763f0 100644 --- a/aaes-os/package.json +++ b/aaes-os/package.json @@ -12,7 +12,8 @@ } }, "scripts": { - "build": "node ./node_modules/typescript/bin/tsc", + "build:architect-agent": "npm --prefix ../packages/architect-agent run build", + "build": "npm run build:architect-agent && node ./node_modules/typescript/bin/tsc", "test": "npm run build && node --test dist/tests/*.test.js", "start": "node dist/src/server.js", "serve": "node dist/src/server.js" @@ -20,6 +21,9 @@ "engines": { "node": ">=20" }, + "dependencies": { + "@aaes-os/architect-agent": "file:../packages/architect-agent" + }, "devDependencies": { "@types/node": "^22.19.21", "typescript": "^5.9.3" diff --git a/aaes-os/src/model/ModelProvider.types.ts b/aaes-os/src/model/ModelProvider.types.ts new file mode 100644 index 00000000..29e12e65 --- /dev/null +++ b/aaes-os/src/model/ModelProvider.types.ts @@ -0,0 +1,7 @@ +export type { + ModelOperation, + ModelProposal, + ModelProvider, + OperationType, + ProposalGoal, +} from '@aaes-os/architect-agent'; diff --git a/aaes-os/src/model/OllamaProvider.ts b/aaes-os/src/model/OllamaProvider.ts new file mode 100644 index 00000000..4f2d976b --- /dev/null +++ b/aaes-os/src/model/OllamaProvider.ts @@ -0,0 +1,20 @@ +import { + OllamaProvider as ArchitectOllamaProvider, + type ModelProposal, + type ModelProvider, + type OllamaProviderOptions, +} from '@aaes-os/architect-agent'; + +export class OllamaProvider implements ModelProvider { + private readonly delegate: ArchitectOllamaProvider; + + constructor(options: OllamaProviderOptions = {}) { + this.delegate = new ArchitectOllamaProvider(options); + } + + generate(prompt: string): Promise { + return this.delegate.generate(prompt); + } +} + +export type { OllamaProviderOptions }; diff --git a/aaes-os/tests/OllamaProvider.test.ts b/aaes-os/tests/OllamaProvider.test.ts new file mode 100644 index 00000000..ba393f62 --- /dev/null +++ b/aaes-os/tests/OllamaProvider.test.ts @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; + +import { OllamaProvider } from '../src/model/OllamaProvider.js'; + +test('root OllamaProvider returns the validated proposal shape', async () => { + const fetchImplementation: typeof globalThis.fetch = async () => + new Response( + JSON.stringify({ + response: JSON.stringify({ + schemaVersion: '1', + goal: 'fix', + operations: [ + { + file: 'src/index.ts', + type: 'update', + content: 'export const fixed = true;', + }, + ], + }), + }), + { status: 200, headers: { 'Content-Type': 'application/json' } }, + ); + const provider = new OllamaProvider({ fetch: fetchImplementation }); + + const proposal = await provider.generate('Fix src/index.ts'); + + assert.equal(proposal.goal, 'fix'); + assert.equal(proposal.operations[0]?.file, 'src/index.ts'); + assert.equal('raw' in proposal, false); +}); diff --git a/packages/architect-agent/package-lock.json b/packages/architect-agent/package-lock.json new file mode 100644 index 00000000..f68f8adc --- /dev/null +++ b/packages/architect-agent/package-lock.json @@ -0,0 +1,1657 @@ +{ + "name": "@aaes-os/architect-agent", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@aaes-os/architect-agent", + "version": "0.1.0", + "devDependencies": { + "@types/node": "^22.19.21", + "typescript": "^5.9.3", + "vitest": "^3.2.4" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.20.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.0.tgz", + "integrity": "sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", + "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.6", + "@vitest/utils": "3.2.6", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", + "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.6", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", + "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", + "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.6", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", + "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.6", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", + "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", + "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.6", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", + "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.6", + "@vitest/mocker": "3.2.6", + "@vitest/pretty-format": "^3.2.6", + "@vitest/runner": "3.2.6", + "@vitest/snapshot": "3.2.6", + "@vitest/spy": "3.2.6", + "@vitest/utils": "3.2.6", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.6", + "@vitest/ui": "3.2.6", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + } + } +} From f477eea434fc6e410478d3393102c12007211791 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 09:08:07 -0400 Subject: [PATCH 5/9] docs: record infinity architect-agent baseline debt --- docs/baseline-debt/infinity-rebase-plan.md | 48 ++++++++++ .../local-ollama-architect-agent.md | 96 +++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 docs/baseline-debt/infinity-rebase-plan.md create mode 100644 docs/baseline-debt/local-ollama-architect-agent.md diff --git a/docs/baseline-debt/infinity-rebase-plan.md b/docs/baseline-debt/infinity-rebase-plan.md new file mode 100644 index 00000000..e7663b2c --- /dev/null +++ b/docs/baseline-debt/infinity-rebase-plan.md @@ -0,0 +1,48 @@ +# Infinity Architect-Agent Rebase Plan + +## Objective + +Move only the local Ollama architect-agent work onto current `origin/main` +without carrying unrelated AAES production-sweep commits or repairing baseline +debt during the rebase. + +## Included Commits + +- `ae371bb7` - design specification +- `29db9e12` - implementation plan +- `4788d56a` - governed architect-agent package +- `efdee491` - root provider compatibility adapter +- baseline-debt documentation commit + +## Excluded Commits + +The older AAES production-sweep and Theta-profile commits preceding +`4520a1e7` remain outside this feature branch. + +## Procedure + +1. Fetch and prune `origin`. +2. Confirm the NTFS worktree is clean. +3. Rebase commits after `4520a1e7` onto `origin/main`. +4. Resolve conflicts only for architect-agent-owned files. +5. Run `corepack pnpm install --frozen-lockfile`. +6. Run the architect-agent and root-adapter tests. +7. Run the recursive workspace build. +8. Run `corepack pnpm test`. +9. Record the post-rebase pass/failure counts in the debt report. +10. Run whitespace and credential-pattern scans. +11. Push only after the feature checks remain green and all residual failures + are identified as baseline debt. + +## Publication Gate + +The branch may be published for review when: + +- the architect-agent package tests pass, +- the root adapter test passes, +- the workspace build passes, +- live 3B generation succeeds, +- no new repository-wide failure appears, +- residual failures are documented rather than silently ignored. + +An Infinity release tag remains blocked until repository-wide CI is green. diff --git a/docs/baseline-debt/local-ollama-architect-agent.md b/docs/baseline-debt/local-ollama-architect-agent.md new file mode 100644 index 00000000..870ff906 --- /dev/null +++ b/docs/baseline-debt/local-ollama-architect-agent.md @@ -0,0 +1,96 @@ +# Project Infinity Baseline Debt Report + +## Scope + +This report records repository-wide failures observed before and after the +local Ollama architect-agent implementation. The feature-specific package, +adapter, build, and live-model checks pass independently. + +Baseline command: + +```powershell +corepack pnpm test +``` + +Pre-rebase result at commit `efdee491`: + +- 149 tests passed +- 4 tests failed +- all 22 package and service builds passed + +## Baseline Failures + +### Missing recent-document coverage fixture + +Missing path: + +`docs/coverage/recent-doc-subsystem-coverage.json` + +Affected tests: + +1. `tests/integration/recent-doc-coverage.test.ts` +2. `services/ops-console/src/server.test.ts` + +The integration test cannot read the expected JSON file. The ops-console +coverage route consequently returns HTTP 400 instead of 200. + +### Missing coordination fixture + +Missing path: + +`tests/fixtures/coordination_bottlenecks.md` + +Affected test: + +`packages/governed-memory/src/verticalSlice.test.ts` + +The replay test fails before runtime evaluation because its fixture cannot be +opened. + +### Theta profile manifest hash drift + +Affected test: + +`packages/theta-codec/src/thetaCodec.test.ts` + +The governed artifact records: + +`fac9cef137bbd2a7ab6b2d439bb3ecdc32bc8be678cebbfc2f523b68b364f5b0` + +The current manifest computes: + +`9b07c2189c7a52642ff48f06ca127709302a914939aef251243e01d5830e6a01` + +Updating either the governed hash or the manifest requires a separate +Theta-profile review and is outside the architect-agent feature. + +## Feature Verification + +The following checks pass: + +- `@aaes-os/architect-agent`: 28 tests +- root Ollama compatibility adapter: 1 test +- recursive workspace build: all 22 package and service projects +- live `qwen2.5-coder:3b` proposal generation +- feature diff whitespace scan +- feature diff credential-pattern scan + +No baseline failure is in an architect-agent file. + +## Filesystem Constraint + +The primary `E:` workspace is formatted as exFAT. pnpm workspace installation +requires filesystem links that exFAT cannot provide. Dependency installation, +builds, and tests therefore run in the NTFS worktree: + +`C:\Users\randj\.config\superpowers\worktrees\project-infi\local-ollama-architect-agent` + +This filesystem constraint is independent of the four baseline test failures. + +## Disposition + +- Keep the failures documented as baseline debt. +- Do not modify missing fixtures or Theta governance artifacts in this feature. +- Rebase only architect-agent commits onto current `origin/main`. +- Re-run the full matrix in the NTFS worktree. +- Update this report with post-rebase evidence before publication. From b1d23882866802e802921eb3f700848febec843f Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 09:17:48 -0400 Subject: [PATCH 6/9] fix(architect-agent): support standalone main layout --- aaes-os/package.json | 1 + aaes-os/tsconfig.model.json | 10 ++++++++++ packages/architect-agent/tsconfig.json | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 aaes-os/tsconfig.model.json diff --git a/aaes-os/package.json b/aaes-os/package.json index f04763f0..5106a1a2 100644 --- a/aaes-os/package.json +++ b/aaes-os/package.json @@ -14,6 +14,7 @@ "scripts": { "build:architect-agent": "npm --prefix ../packages/architect-agent run build", "build": "npm run build:architect-agent && node ./node_modules/typescript/bin/tsc", + "test:model": "npm run build:architect-agent && node ./node_modules/typescript/bin/tsc -p tsconfig.model.json && node --test dist/model-test/tests/OllamaProvider.test.js", "test": "npm run build && node --test dist/tests/*.test.js", "start": "node dist/src/server.js", "serve": "node dist/src/server.js" diff --git a/aaes-os/tsconfig.model.json b/aaes-os/tsconfig.model.json new file mode 100644 index 00000000..970bc169 --- /dev/null +++ b/aaes-os/tsconfig.model.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist/model-test" + }, + "include": [ + "src/model/**/*.ts", + "tests/OllamaProvider.test.ts" + ] +} diff --git a/packages/architect-agent/tsconfig.json b/packages/architect-agent/tsconfig.json index 807e895b..72e93085 100644 --- a/packages/architect-agent/tsconfig.json +++ b/packages/architect-agent/tsconfig.json @@ -1,9 +1,19 @@ { - "extends": "../../tsconfig.base.json", "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", "rootDir": "src", "outDir": "dist", - "composite": true + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "skipLibCheck": true, + "esModuleInterop": true }, "include": ["src/**/*.ts"], "exclude": ["dist", "node_modules", "src/**/*.test.ts"] From 903772f99e00c432ff6d0539a580eab477e1fcb1 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 09:17:48 -0400 Subject: [PATCH 7/9] docs: define constitutional implementation status --- README.md | 75 ++++++ docs/IMPLEMENTATION_STATUS.md | 216 ++++++++++++++++++ docs/baseline-debt/infinity-rebase-plan.md | 22 +- .../local-ollama-architect-agent.md | 50 +++- 4 files changed, 355 insertions(+), 8 deletions(-) create mode 100644 docs/IMPLEMENTATION_STATUS.md diff --git a/README.md b/README.md index e1fae016..a0e7734d 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,81 @@ License: [Apache 2.0](LICENSE) · Repo: [Project-Infinity1](https://github.com/w --- +## Governed local LLM architecture + +Project Infinity includes a proposal-only coding runtime for local Ollama +models. The runtime validates model output before governance, emits hash-backed +envelopes and receipts, and replays decisions without applying filesystem +changes. + +### Architect-agent package + +`packages/architect-agent` provides: + +- strict TypeScript proposal and contract types, +- native Ollama `/api/generate` transport, +- `qwen2.5-coder:3b` as the default model, +- configurable model identifiers such as `qwen2.5-coder:7b`, +- timeout-safe, bounded, non-streaming JSON generation, +- UCR goal, operation, and authorized-file evaluation, +- deterministic ALA operation normalization, +- proposal-level safety checks, +- SHA-256 proposal identity and timestamped governance envelopes, +- EGL-1 proposal and decision replay equivalence, and +- per-run evidence receipts. + +The standalone AAES TypeScript runtime delegates its compatibility model +provider to this package through `aaes-os/src/model/OllamaProvider.ts`. + +### Lawful Nova shell + +[Lawful Nova](https://github.com/warheart1984-ctrl/agentic-coding-agent) +provides the corresponding governed Python and Electron coding shell: + +- Monaco editor and unified diff viewer, +- patch preview and explicit apply workflow, +- governed coding and wiring tools, +- receipt, trace, and replay surfaces, +- `qwen2.5-coder:3b` default and `qwen2.5-coder:7b` selection. + +Stable Nova release: +[`v0.1.0-nova-governed-shell`](https://github.com/warheart1984-ctrl/agentic-coding-agent/releases/tag/v0.1.0-nova-governed-shell). + +### Verification matrix + +| Surface | Result | +|---|---:| +| Architect-agent package | 28 tests passed | +| AAES compatibility adapter | 1 test passed | +| Architect-agent TypeScript build | Passed | +| Lawful Nova Python | 64 tests passed | +| Lawful Nova desktop | 9 tests passed | +| Live `qwen2.5-coder:3b` generation | Passed | +| Secret and whitespace scans | Passed | + +Repository-wide baseline blockers remain outside this feature. See +[Baseline Debt](docs/baseline-debt/local-ollama-architect-agent.md) for current +evidence. + +### Trust boundary + +Implemented guarantees stop at validated proposal generation and deterministic +governance replay. Hardware roots of trust, key-backed signatures, durable +receipt storage, filesystem execution, and federated trust are external or +planned. + +See [Constitutional Implementation Status](docs/IMPLEMENTATION_STATUS.md) for +the complete implemented, external, and planned capability ledger. + +### Local requirements + +- Node.js 20+ for the TypeScript packages +- Python 3.10+ for the Infinity runtime +- Ollama for live local-model generation +- NTFS on Windows for linked Node package development + +--- + ## Quick start (after clone) **Windows (PowerShell):** diff --git a/docs/IMPLEMENTATION_STATUS.md b/docs/IMPLEMENTATION_STATUS.md new file mode 100644 index 00000000..77f37039 --- /dev/null +++ b/docs/IMPLEMENTATION_STATUS.md @@ -0,0 +1,216 @@ +# Constitutional Implementation Status + +## Purpose + +This document separates implemented guarantees from external dependencies and +planned capabilities for the local Ollama architect-agent integration. A +capability is listed as implemented only when source code and an executable +test exist in this repository. + +## Implemented + +### Architect Runtime + +Status: implemented. + +`packages/architect-agent/src/architectAgent.ts` composes model proposal +generation, UCR evaluation, ALA normalization, safety evaluation, envelope +construction, replay, and receipt generation. It returns a governed proposal +result without applying filesystem changes. + +Evidence: + +- `packages/architect-agent/src/architectAgent.test.ts` +- accepted and rejected proposal paths +- receipt and replay assertions +- no applied-filesystem result surface + +### Builder Runtime + +Status: implemented for structured proposal construction. + +`packages/architect-agent/src/prompt.ts` creates the bounded model instruction, +`ollamaProvider.ts` performs non-streaming generation, and `proposal.ts` +validates model output before it reaches governance. + +Implemented guarantees: + +- `qwen2.5-coder:3b` default +- configurable model identifier, including `qwen2.5-coder:7b` +- request timeout with abort +- bounded `num_predict` +- non-streaming JSON response +- strict schema, goal, operation, path, and content validation +- sanitized provider errors that do not include prompts or raw responses + +Evidence: + +- `packages/architect-agent/src/proposal.test.ts` +- `packages/architect-agent/src/ollamaProvider.test.ts` + +### Integration Runtime + +Status: implemented for the standalone AAES-OS TypeScript runtime. + +`aaes-os/src/model/OllamaProvider.ts` preserves the AAES model-provider surface +and delegates transport and validation to `@aaes-os/architect-agent`. + +Evidence: + +- `aaes-os/tests/OllamaProvider.test.ts` +- `npm run test:model` from `aaes-os` + +Lawful Nova provides the corresponding governed Python and Electron model +routes in the separate `agentic-coding-agent` repository. + +### Safety Runtime + +Status: implemented for proposal-level pre-execution checks. + +`evaluateSafety` rejects empty insert/update content and paths that escape the +workspace. `evaluateUcr` separately enforces goal, operation, and authorized +file constraints. An architect result is accepted only when both decisions +pass. + +Evidence: + +- `packages/architect-agent/src/governance.ts` +- `packages/architect-agent/src/governance.test.ts` + +### Replay + +Status: implemented for governed proposal replay. + +`replayEnvelope` recomputes the proposal hash, UCR decision, normalized ALA +plan, safety decision, and timestamp validity. It reports drift without +executing model inference or filesystem mutations. + +Evidence: + +- clean replay test +- tampered ALA plan test +- rejected-proposal replay test + +### EGL-1 + +Status: implemented for proposal and governance-decision equivalence. + +The current EGL-1 profile considers a replay equivalent when: + +1. the proposal content hash matches, +2. UCR produces the same decision and reasons, +3. ALA produces the same normalized operation plan, +4. Safety produces the same decision and violations, and +5. the envelope timestamp is valid. + +Filesystem-state equivalence is not claimed because the architect runtime does +not include a filesystem executor. + +### Deterministic Envelopes + +Status: implemented for deterministic content identity. + +`hashStable` sorts object keys recursively before SHA-256 hashing. Equivalent +proposal objects therefore receive the same `proposalHash` regardless of input +key order. + +The envelope also records an issuance timestamp. Complete serialized envelopes +created at different times are intentionally not byte-for-byte identical; the +deterministic guarantee applies to proposal identity and replayed decisions. + +### Threat Model + +Status: implemented for the local proposal boundary. + +| Threat | Implemented control | +|---|---| +| Malformed model output | Strict JSON parsing and runtime schema validation | +| Partial streamed JSON | Ollama generation uses `stream: false` | +| Unbounded generation | Positive integer `maxTokens` mapped to `num_predict` | +| Hung local endpoint | AbortController timeout | +| Path traversal | Absolute paths and `..` segments rejected | +| Unauthorized mutation proposal | Goal, operation, and file contract checks | +| Empty destructive patch | Insert/update content must be non-empty | +| Prompt or response disclosure in errors | Sanitized typed error messages | +| Hidden filesystem side effects | Runtime produces proposals only | +| Replay drift | Hash and decision recomputation | + +This threat model does not claim hardware isolation, key custody, process +sandboxing, or host compromise resistance. + +### Conformance Tests + +Status: implemented. + +Current feature matrix: + +- architect-agent package: 28 tests +- AAES root compatibility adapter: 1 test +- strict TypeScript package build +- live `qwen2.5-coder:3b` proposal generation +- whitespace validation +- credential-pattern scan + +## External + +### Hardware Root of Trust + +No TPM, HSM, secure enclave, measured boot, or hardware attestation integration +is included. + +### Key-Backed Signatures + +Receipts and envelopes use deterministic hashes, not asymmetric signatures. +Private-key custody, rotation, verification, and revocation are external. + +### Durable Receipt Ledger + +`ArchitectAgent.run` returns a receipt with each result. It does not persist +receipts across processes. Database-backed append-only storage is external. + +### Filesystem Executor + +The runtime does not write, delete, rename, or execute proposed files. +Application, rollback, workspace snapshots, and filesystem authorization are +external. + +### Federated Trust + +Cross-node identity, quorum, remote attestation, trust exchange, and federated +receipt verification are external. + +## Planned + +### Persistent Evidence Corpus + +Store envelopes, receipts, replay outcomes, model metadata, and conformance +evidence in an append-only durable corpus. + +### Multi-Node Federation + +Add governed node identity, trust negotiation, receipt exchange, and explicit +federation policy. + +### Advanced Equivalence Profiles + +Extend EGL-1 with filesystem snapshots, semantic code equivalence, toolchain +version binding, and configurable equivalence tolerances. + +### Production Trust Infrastructure + +Add key-backed signatures, secure key custody, rotation, revocation, +attestation, deployment hardening, and operational monitoring. + +## Repository Baseline + +The feature-specific tests pass after rebasing onto current `origin/main`. +Repository-wide verification still exposes unrelated baseline failures: + +- standalone AAES-OS compilation references a missing + `SqliteTraceStoreStub` export, +- full Python collection stops on four governance-genome boot validation + errors. + +These failures are documented in +`docs/baseline-debt/local-ollama-architect-agent.md` and are not represented as +architect-agent guarantees. diff --git a/docs/baseline-debt/infinity-rebase-plan.md b/docs/baseline-debt/infinity-rebase-plan.md index e7663b2c..24c6532a 100644 --- a/docs/baseline-debt/infinity-rebase-plan.md +++ b/docs/baseline-debt/infinity-rebase-plan.md @@ -19,21 +19,33 @@ debt during the rebase. The older AAES production-sweep and Theta-profile commits preceding `4520a1e7` remain outside this feature branch. -## Procedure +## Executed Procedure 1. Fetch and prune `origin`. 2. Confirm the NTFS worktree is clean. 3. Rebase commits after `4520a1e7` onto `origin/main`. 4. Resolve conflicts only for architect-agent-owned files. -5. Run `corepack pnpm install --frozen-lockfile`. -6. Run the architect-agent and root-adapter tests. -7. Run the recursive workspace build. -8. Run `corepack pnpm test`. +5. Adapt the compatibility layer to the standalone `aaes-os/` runtime that + replaced the old root pnpm workspace on current main. +6. Run `npm ci` in `packages/architect-agent` and `aaes-os`. +7. Run the architect-agent and AAES compatibility-adapter tests. +8. Run the standalone AAES build and full root pytest collection. 9. Record the post-rebase pass/failure counts in the debt report. 10. Run whitespace and credential-pattern scans. 11. Push only after the feature checks remain green and all residual failures are identified as baseline debt. +## Rebase Outcome + +- Rebased successfully onto `origin/main` commit `6280e45a`. +- Dropped the unrelated AAES production-sweep and Theta commits. +- Kept the standalone architect-agent package. +- Moved the compatibility adapter from the deleted root TypeScript workspace + to `aaes-os/src/model`. +- Added a targeted `aaes-os` model test that does not depend on the unrelated + full-runtime compile path. +- Recorded the new main-branch baseline blockers in the debt report. + ## Publication Gate The branch may be published for review when: diff --git a/docs/baseline-debt/local-ollama-architect-agent.md b/docs/baseline-debt/local-ollama-architect-agent.md index 870ff906..ab7aacca 100644 --- a/docs/baseline-debt/local-ollama-architect-agent.md +++ b/docs/baseline-debt/local-ollama-architect-agent.md @@ -18,6 +18,23 @@ Pre-rebase result at commit `efdee491`: - 4 tests failed - all 22 package and service builds passed +Post-rebase base commit: + +`6280e45a` (`origin/main`) + +Current feature results: + +- architect-agent: 28 tests passed +- AAES compatibility adapter: 1 test passed +- architect-agent TypeScript build passed +- AAES full build blocked by one pre-existing missing export +- root pytest collection blocked by four pre-existing governance-genome boot + validation errors + +The old pnpm workspace and its four failures described below are no longer +present on current `origin/main`. They remain recorded as historical +pre-rebase evidence. + ## Baseline Failures ### Missing recent-document coverage fixture @@ -77,6 +94,31 @@ The following checks pass: No baseline failure is in an architect-agent file. +## Post-Rebase Baseline Failures + +### Standalone AAES-OS missing export + +`aaes-os/src/index.ts` exports `SqliteTraceStoreStub`, while +`aaes-os/src/storage/trace_store.ts` defines only `InMemoryTraceStore`. + +This defect exists on `origin/main` and stops the full standalone AAES +TypeScript build. The architect-agent package build and targeted compatibility +test pass independently. + +### Governance-genome boot validation + +Full root pytest collection stops while importing `src.api` because +`Alt4Runtime.boot_validate()` raises `GenomeValidationError`. + +Affected collection targets: + +1. `tests/otem/test_otem_stabilization.py` +2. `tests/test_api.py` +3. `tests/test_api_mechanic_slingshot.py` +4. `tests/test_api_operator_training_adapters.py` + +No architect-agent TypeScript module is imported by these tests. + ## Filesystem Constraint The primary `E:` workspace is formatted as exFAT. pnpm workspace installation @@ -91,6 +133,8 @@ This filesystem constraint is independent of the four baseline test failures. - Keep the failures documented as baseline debt. - Do not modify missing fixtures or Theta governance artifacts in this feature. -- Rebase only architect-agent commits onto current `origin/main`. -- Re-run the full matrix in the NTFS worktree. -- Update this report with post-rebase evidence before publication. +- Do not modify the missing AAES export or governance-genome registry in this + feature. +- Publish the rebased architect-agent branch for review with the baseline + failures disclosed. +- Do not create an Infinity release tag until repository-wide gates pass. From f27b6b93eb7bc2245c6c8617310119f897817d47 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 09:19:59 -0400 Subject: [PATCH 8/9] docs: record external github actions blocker --- docs/baseline-debt/local-ollama-architect-agent.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/baseline-debt/local-ollama-architect-agent.md b/docs/baseline-debt/local-ollama-architect-agent.md index ab7aacca..9ad0c8af 100644 --- a/docs/baseline-debt/local-ollama-architect-agent.md +++ b/docs/baseline-debt/local-ollama-architect-agent.md @@ -119,6 +119,17 @@ Affected collection targets: No architect-agent TypeScript module is imported by these tests. +### GitHub Actions account lock + +PR #13 triggered the CoGOS Forge Gate and Documentation Baseline Gate, but +GitHub assigned no runner and executed zero steps. Each failed check contains +the annotation: + +`The job was not started because your account is locked due to a billing issue.` + +This is an external GitHub account state, not a repository test result. The +Buildkite check on the same PR passed. + ## Filesystem Constraint The primary `E:` workspace is formatted as exFAT. pnpm workspace installation From e511ccfb31811c5595ce8824ec0a3147cc4313b3 Mon Sep 17 00:00:00 2001 From: Jon Halstead Date: Wed, 1 Jul 2026 15:03:47 -0400 Subject: [PATCH 9/9] fix: restore AAES baseline purity Restore the fail-closed SQLite trace store stub, make genome proof paths repository-relative, and isolate OTEM ceiling state in API tests. Refresh baseline evidence after the affected AAES and Python suites pass. --- aaes-os/src/storage/trace_store.ts | 14 +++++ aaes-os/tests/trace_store.test.ts | 44 +++++++++++++++ docs/IMPLEMENTATION_STATUS.md | 21 ++++---- .../local-ollama-architect-agent.md | 54 ++++++++++++------- ...aais_composed_runtime_organ.genome.v1.json | 2 +- .../aais_doctor_organ.genome.v1.json | 2 +- .../aais_ul_substrate_organ.genome.v1.json | 2 +- .../anti_drift_organ.genome.v1.json | 2 +- .../api_gateway_organ.genome.v1.json | 2 +- .../aris_integration_organ.genome.v1.json | 2 +- .../blueprint_posture_organ.genome.v1.json | 2 +- .../chat_turn_governance_organ.genome.v1.json | 2 +- .../continuity_substrate_organ.genome.v1.json | 2 +- .../conversation_memory_organ.genome.v1.json | 2 +- ...ive_capability_bridge_organ.genome.v1.json | 2 +- ...ive_console_interface_organ.genome.v1.json | 2 +- ...tive_operator_handoff_organ.genome.v1.json | 2 +- .../dashboard_surface_organ.genome.v1.json | 2 +- .../governance_layer_organ.genome.v1.json | 2 +- ...arvis_console_surface_organ.genome.v1.json | 2 +- .../jarvis_operator_organ.genome.v1.json | 2 +- ...jarvis_reasoning_lane_organ.genome.v1.json | 2 +- .../jarvis_runs_organ.genome.v1.json | 2 +- .../launcher_organ.genome.v1.json | 2 +- .../linguistic_cascade_organ.genome.v1.json | 2 +- ...ic_closed_loop_fabric_organ.genome.v1.json | 2 +- ...ic_cycle_optimization_organ.genome.v1.json | 2 +- ...istic_drift_predictor_organ.genome.v1.json | 2 +- ..._forecast_consumption_organ.genome.v1.json | 2 +- ...ernance_cycle_history_organ.genome.v1.json | 2 +- ...stic_governance_cycle_organ.genome.v1.json | 2 +- ...inguistic_lineage_viz_organ.genome.v1.json | 2 +- .../linguistic_mutation_organ.genome.v1.json | 2 +- ...dictive_cycle_history_organ.genome.v1.json | 2 +- ...predictive_governance_organ.genome.v1.json | 2 +- ...reemptive_remediation_organ.genome.v1.json | 2 +- ...inguistic_remediation_organ.genome.v1.json | 2 +- .../memory_bank_surface_organ.genome.v1.json | 2 +- ...linguistic_governance_organ.genome.v1.json | 2 +- ...ngineering_translator_organ.genome.v1.json | 2 +- .../naming_genome_organ.genome.v1.json | 2 +- .../naming_protocol_organ.genome.v1.json | 2 +- .../nova_landing_surface_organ.genome.v1.json | 2 +- ...a_workspace_interface_organ.genome.v1.json | 2 +- ...tor_console_interface_organ.genome.v1.json | 2 +- .../operator_workspace_organ.genome.v1.json | 2 +- .../output_integrity_organ.genome.v1.json | 2 +- ...rm_console_interfaces_organ.genome.v1.json | 2 +- .../project_infi_law_organ.genome.v1.json | 2 +- ...ct_infi_state_machine_organ.genome.v1.json | 2 +- .../prompt_assembly_organ.genome.v1.json | 2 +- .../reasoning_contract_organ.genome.v1.json | 2 +- .../run_ledger_binding_organ.genome.v1.json | 2 +- .../security_protocol_organ.genome.v1.json | 2 +- .../state_hygiene_organ.genome.v1.json | 2 +- .../system_guard_organ.genome.v1.json | 2 +- .../v10_action_engine_organ.genome.v1.json | 2 +- .../v10_core_organ.genome.v1.json | 2 +- .../v10_runtime_organ.genome.v1.json | 2 +- .../v9_core_organ.genome.v1.json | 2 +- .../v9_runtime_organ.genome.v1.json | 2 +- .../workflow_interfaces_organ.genome.v1.json | 2 +- .../workflow_runtime_organ.genome.v1.json | 2 +- src/otem_ceiling.py | 6 +++ tests/test_api.py | 48 ++++++++++++++--- tests/test_governance_organs_alt4.py | 16 +++++- tests/test_otem_ceiling.py | 12 +++++ 67 files changed, 237 insertions(+), 96 deletions(-) create mode 100644 aaes-os/tests/trace_store.test.ts diff --git a/aaes-os/src/storage/trace_store.ts b/aaes-os/src/storage/trace_store.ts index d4153d8a..fe7b5f8a 100644 --- a/aaes-os/src/storage/trace_store.ts +++ b/aaes-os/src/storage/trace_store.ts @@ -33,3 +33,17 @@ export class InMemoryTraceStore implements TraceStore { return { traceId, steps: [...steps] }; } } + +/** + * Optional SQLite-backed store stub - not wired in v1. + * Swap InMemoryTraceStore for this when persistence is required. + */ +export class SqliteTraceStoreStub implements TraceStore { + appendStep(_ctx: AAESContext, _step: AAESStep): void { + throw new Error("SqliteTraceStoreStub: not implemented in v1"); + } + + getTrace(_traceId: string): TraceRecord | undefined { + throw new Error("SqliteTraceStoreStub: not implemented in v1"); + } +} diff --git a/aaes-os/tests/trace_store.test.ts b/aaes-os/tests/trace_store.test.ts new file mode 100644 index 00000000..e51f7a22 --- /dev/null +++ b/aaes-os/tests/trace_store.test.ts @@ -0,0 +1,44 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { SqliteTraceStoreStub } from "../src/index.js"; +import type { AAESContext, AAESStep } from "../src/types.js"; + +const context: AAESContext = { + traceId: "trace-stub", + request: { + actorId: "operator", + scope: { name: "test" }, + prompt: "verify fail-closed storage", + }, + session: {}, + steps: [], + metadata: {}, +}; + +const step: AAESStep = { + stepId: "step-stub", + stepType: "test", + timestamp: "2026-07-01T00:00:00.000Z", + summary: "verify fail-closed storage", + status: "ok", +}; + +describe("SqliteTraceStoreStub", () => { + it("fails closed for writes until durable storage is implemented", () => { + const store = new SqliteTraceStoreStub(); + + assert.throws( + () => store.appendStep(context, step), + /SqliteTraceStoreStub: not implemented in v1/, + ); + }); + + it("fails closed for reads until durable storage is implemented", () => { + const store = new SqliteTraceStoreStub(); + + assert.throws( + () => store.getTrace(context.traceId), + /SqliteTraceStoreStub: not implemented in v1/, + ); + }); +}); diff --git a/docs/IMPLEMENTATION_STATUS.md b/docs/IMPLEMENTATION_STATUS.md index 77f37039..05b7bdb4 100644 --- a/docs/IMPLEMENTATION_STATUS.md +++ b/docs/IMPLEMENTATION_STATUS.md @@ -146,6 +146,9 @@ Current feature matrix: - architect-agent package: 28 tests - AAES root compatibility adapter: 1 test +- AAES standalone runtime: 27 tests +- governance-genome gate: 199 genomes valid +- formerly blocked API modules: 251 tests passed - strict TypeScript package build - live `qwen2.5-coder:3b` proposal generation - whitespace validation @@ -204,13 +207,11 @@ attestation, deployment hardening, and operational monitoring. ## Repository Baseline The feature-specific tests pass after rebasing onto current `origin/main`. -Repository-wide verification still exposes unrelated baseline failures: - -- standalone AAES-OS compilation references a missing - `SqliteTraceStoreStub` export, -- full Python collection stops on four governance-genome boot validation - errors. - -These failures are documented in -`docs/baseline-debt/local-ollama-architect-agent.md` and are not represented as -architect-agent guarantees. +The standalone AAES public export is restored, and all genome proof paths are +repository-relative. Strict genome validation passes for 199 genomes, and the +four previously blocked API modules pass all 251 tests. + +GitHub Actions remains externally blocked by the account billing lock, and npm +publication remains blocked until the local npm client is authenticated. These +constraints are documented in +`docs/baseline-debt/local-ollama-architect-agent.md`. diff --git a/docs/baseline-debt/local-ollama-architect-agent.md b/docs/baseline-debt/local-ollama-architect-agent.md index 9ad0c8af..ea5c6b2d 100644 --- a/docs/baseline-debt/local-ollama-architect-agent.md +++ b/docs/baseline-debt/local-ollama-architect-agent.md @@ -27,9 +27,10 @@ Current feature results: - architect-agent: 28 tests passed - AAES compatibility adapter: 1 test passed - architect-agent TypeScript build passed -- AAES full build blocked by one pre-existing missing export -- root pytest collection blocked by four pre-existing governance-genome boot - validation errors +- AAES full build and 27-test suite passed after restoring the public + `SqliteTraceStoreStub` +- governance-genome gate passed with 199 genomes +- the four previously blocked pytest modules pass successfully (251 tests) The old pnpm workspace and its four failures described below are no longer present on current `origin/main`. They remain recorded as historical @@ -94,32 +95,39 @@ The following checks pass: No baseline failure is in an architect-agent file. -## Post-Rebase Baseline Failures +## Post-Rebase Baseline Corrections -### Standalone AAES-OS missing export +### Standalone AAES-OS missing export: corrected `aaes-os/src/index.ts` exports `SqliteTraceStoreStub`, while -`aaes-os/src/storage/trace_store.ts` defines only `InMemoryTraceStore`. +`aaes-os/src/storage/trace_store.ts` previously defined only +`InMemoryTraceStore`. -This defect exists on `origin/main` and stops the full standalone AAES -TypeScript build. The architect-agent package build and targeted compatibility -test pass independently. +The fail-closed v1 stub has been restored with adversarial read and write tests. +The complete standalone AAES build and test suite now pass. -### Governance-genome boot validation +### Governance-genome boot validation: corrected -Full root pytest collection stops while importing `src.api` because -`Alt4Runtime.boot_validate()` raises `GenomeValidationError`. +Fifty-nine genome manifests contained workstation-specific absolute proof paths +under `E:\project-infi`. Those paths escaped the NTFS worktree and caused +`Alt4Runtime.boot_validate()` to raise `GenomeValidationError`. -Affected collection targets: +The paths are now repository-relative, and the conformance suite asserts that +Windows and POSIX absolute proof paths are forbidden. + +Previously affected collection targets: 1. `tests/otem/test_otem_stabilization.py` 2. `tests/test_api.py` 3. `tests/test_api_mechanic_slingshot.py` 4. `tests/test_api_operator_training_adapters.py` -No architect-agent TypeScript module is imported by these tests. +All four modules now pass successfully. The strict genome gate reports 199 +valid genomes. + +## External Release Blockers -### GitHub Actions account lock +### GitHub Actions account lock: unresolved PR #13 triggered the CoGOS Forge Gate and Documentation Baseline Gate, but GitHub assigned no runner and executed zero steps. Each failed check contains @@ -130,6 +138,13 @@ the annotation: This is an external GitHub account state, not a repository test result. The Buildkite check on the same PR passed. +### npm authentication: unresolved + +`npm whoami` returns `ENEEDAUTH`. The +`@aaes-os/architect-agent@0.1.0` package passes `npm pack --dry-run`, but +publication requires an authenticated npm account with permission to publish +the `@aaes-os` scope. + ## Filesystem Constraint The primary `E:` workspace is formatted as exFAT. pnpm workspace installation @@ -142,10 +157,9 @@ This filesystem constraint is independent of the four baseline test failures. ## Disposition -- Keep the failures documented as baseline debt. +- Keep the historical pre-rebase failures documented as baseline debt. - Do not modify missing fixtures or Theta governance artifacts in this feature. -- Do not modify the missing AAES export or governance-genome registry in this - feature. -- Publish the rebased architect-agent branch for review with the baseline - failures disclosed. +- Keep the AAES export and portable genome-path corrections covered by + conformance tests. +- Resolve the GitHub billing lock and npm authentication outside the repository. - Do not create an Infinity release tag until repository-wide gates pass. diff --git a/governance/subsystem_genomes/aais_composed_runtime_organ.genome.v1.json b/governance/subsystem_genomes/aais_composed_runtime_organ.genome.v1.json index 8ce4ffdd..eb52a719 100644 --- a/governance/subsystem_genomes/aais_composed_runtime_organ.genome.v1.json +++ b/governance/subsystem_genomes/aais_composed_runtime_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\AAIS_COMPOSED_RUNTIME_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/AAIS_COMPOSED_RUNTIME_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/aais_doctor_organ.genome.v1.json b/governance/subsystem_genomes/aais_doctor_organ.genome.v1.json index 0f1e47da..715b873e 100644 --- a/governance/subsystem_genomes/aais_doctor_organ.genome.v1.json +++ b/governance/subsystem_genomes/aais_doctor_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\AAIS_DOCTOR_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/AAIS_DOCTOR_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/aais_ul_substrate_organ.genome.v1.json b/governance/subsystem_genomes/aais_ul_substrate_organ.genome.v1.json index bd7b6af0..1d563642 100644 --- a/governance/subsystem_genomes/aais_ul_substrate_organ.genome.v1.json +++ b/governance/subsystem_genomes/aais_ul_substrate_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\AAIS_UL_SUBSTRATE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/AAIS_UL_SUBSTRATE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/anti_drift_organ.genome.v1.json b/governance/subsystem_genomes/anti_drift_organ.genome.v1.json index c9480f72..79fb3bd6 100644 --- a/governance/subsystem_genomes/anti_drift_organ.genome.v1.json +++ b/governance/subsystem_genomes/anti_drift_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\ANTI_DRIFT_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/ANTI_DRIFT_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/api_gateway_organ.genome.v1.json b/governance/subsystem_genomes/api_gateway_organ.genome.v1.json index c6426e00..8c958f35 100644 --- a/governance/subsystem_genomes/api_gateway_organ.genome.v1.json +++ b/governance/subsystem_genomes/api_gateway_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\API_GATEWAY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/API_GATEWAY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/aris_integration_organ.genome.v1.json b/governance/subsystem_genomes/aris_integration_organ.genome.v1.json index 71d509d8..d186139a 100644 --- a/governance/subsystem_genomes/aris_integration_organ.genome.v1.json +++ b/governance/subsystem_genomes/aris_integration_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\ARIS_INTEGRATION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/ARIS_INTEGRATION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/blueprint_posture_organ.genome.v1.json b/governance/subsystem_genomes/blueprint_posture_organ.genome.v1.json index 4a597511..d4c88650 100644 --- a/governance/subsystem_genomes/blueprint_posture_organ.genome.v1.json +++ b/governance/subsystem_genomes/blueprint_posture_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\BLUEPRINT_POSTURE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/BLUEPRINT_POSTURE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/chat_turn_governance_organ.genome.v1.json b/governance/subsystem_genomes/chat_turn_governance_organ.genome.v1.json index 474b1ba9..e9032e0f 100644 --- a/governance/subsystem_genomes/chat_turn_governance_organ.genome.v1.json +++ b/governance/subsystem_genomes/chat_turn_governance_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CHAT_TURN_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CHAT_TURN_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/continuity_substrate_organ.genome.v1.json b/governance/subsystem_genomes/continuity_substrate_organ.genome.v1.json index db1db506..05bc123b 100644 --- a/governance/subsystem_genomes/continuity_substrate_organ.genome.v1.json +++ b/governance/subsystem_genomes/continuity_substrate_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CONTINUITY_SUBSTRATE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CONTINUITY_SUBSTRATE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/conversation_memory_organ.genome.v1.json b/governance/subsystem_genomes/conversation_memory_organ.genome.v1.json index 96d27635..f76e83ca 100644 --- a/governance/subsystem_genomes/conversation_memory_organ.genome.v1.json +++ b/governance/subsystem_genomes/conversation_memory_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CONVERSATION_MEMORY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CONVERSATION_MEMORY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/creative_capability_bridge_organ.genome.v1.json b/governance/subsystem_genomes/creative_capability_bridge_organ.genome.v1.json index 8b35ee97..eb66127e 100644 --- a/governance/subsystem_genomes/creative_capability_bridge_organ.genome.v1.json +++ b/governance/subsystem_genomes/creative_capability_bridge_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CREATIVE_CAPABILITY_BRIDGE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CREATIVE_CAPABILITY_BRIDGE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/creative_console_interface_organ.genome.v1.json b/governance/subsystem_genomes/creative_console_interface_organ.genome.v1.json index 9d2dea4d..d061eae6 100644 --- a/governance/subsystem_genomes/creative_console_interface_organ.genome.v1.json +++ b/governance/subsystem_genomes/creative_console_interface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CREATIVE_CONSOLE_INTERFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CREATIVE_CONSOLE_INTERFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/creative_operator_handoff_organ.genome.v1.json b/governance/subsystem_genomes/creative_operator_handoff_organ.genome.v1.json index b6d21ea1..3dd22e01 100644 --- a/governance/subsystem_genomes/creative_operator_handoff_organ.genome.v1.json +++ b/governance/subsystem_genomes/creative_operator_handoff_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\CREATIVE_OPERATOR_HANDOFF_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/CREATIVE_OPERATOR_HANDOFF_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/dashboard_surface_organ.genome.v1.json b/governance/subsystem_genomes/dashboard_surface_organ.genome.v1.json index dd8d499d..41b2c70b 100644 --- a/governance/subsystem_genomes/dashboard_surface_organ.genome.v1.json +++ b/governance/subsystem_genomes/dashboard_surface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\DASHBOARD_SURFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/DASHBOARD_SURFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/governance_layer_organ.genome.v1.json b/governance/subsystem_genomes/governance_layer_organ.genome.v1.json index 7300bb64..2222bc06 100644 --- a/governance/subsystem_genomes/governance_layer_organ.genome.v1.json +++ b/governance/subsystem_genomes/governance_layer_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\GOVERNANCE_LAYER_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/GOVERNANCE_LAYER_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/jarvis_console_surface_organ.genome.v1.json b/governance/subsystem_genomes/jarvis_console_surface_organ.genome.v1.json index 117ce24d..6145d4f6 100644 --- a/governance/subsystem_genomes/jarvis_console_surface_organ.genome.v1.json +++ b/governance/subsystem_genomes/jarvis_console_surface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\JARVIS_CONSOLE_SURFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/JARVIS_CONSOLE_SURFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/jarvis_operator_organ.genome.v1.json b/governance/subsystem_genomes/jarvis_operator_organ.genome.v1.json index d3066826..bbbc1983 100644 --- a/governance/subsystem_genomes/jarvis_operator_organ.genome.v1.json +++ b/governance/subsystem_genomes/jarvis_operator_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\JARVIS_OPERATOR_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/JARVIS_OPERATOR_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/jarvis_reasoning_lane_organ.genome.v1.json b/governance/subsystem_genomes/jarvis_reasoning_lane_organ.genome.v1.json index 583b491b..9f631b44 100644 --- a/governance/subsystem_genomes/jarvis_reasoning_lane_organ.genome.v1.json +++ b/governance/subsystem_genomes/jarvis_reasoning_lane_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\JARVIS_REASONING_LANE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/JARVIS_REASONING_LANE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/jarvis_runs_organ.genome.v1.json b/governance/subsystem_genomes/jarvis_runs_organ.genome.v1.json index 40966357..b38159c8 100644 --- a/governance/subsystem_genomes/jarvis_runs_organ.genome.v1.json +++ b/governance/subsystem_genomes/jarvis_runs_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\JARVIS_RUNS_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/JARVIS_RUNS_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/launcher_organ.genome.v1.json b/governance/subsystem_genomes/launcher_organ.genome.v1.json index 46517113..4cc920f8 100644 --- a/governance/subsystem_genomes/launcher_organ.genome.v1.json +++ b/governance/subsystem_genomes/launcher_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LAUNCHER_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LAUNCHER_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_cascade_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_cascade_organ.genome.v1.json index 68991e34..acd385d4 100644 --- a/governance/subsystem_genomes/linguistic_cascade_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_cascade_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_CASCADE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_CASCADE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_closed_loop_fabric_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_closed_loop_fabric_organ.genome.v1.json index 6b82718c..f75aa074 100644 --- a/governance/subsystem_genomes/linguistic_closed_loop_fabric_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_closed_loop_fabric_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_CLOSED_LOOP_FABRIC_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_CLOSED_LOOP_FABRIC_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_cycle_optimization_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_cycle_optimization_organ.genome.v1.json index 795a57b3..54b16c58 100644 --- a/governance/subsystem_genomes/linguistic_cycle_optimization_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_cycle_optimization_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_CYCLE_OPTIMIZATION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_CYCLE_OPTIMIZATION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_drift_predictor_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_drift_predictor_organ.genome.v1.json index 8fb79d3f..7e0c8f6b 100644 --- a/governance/subsystem_genomes/linguistic_drift_predictor_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_drift_predictor_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_DRIFT_PREDICTOR_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_DRIFT_PREDICTOR_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_forecast_consumption_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_forecast_consumption_organ.genome.v1.json index da92fd71..89a216d2 100644 --- a/governance/subsystem_genomes/linguistic_forecast_consumption_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_forecast_consumption_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_FORECAST_CONSUMPTION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_FORECAST_CONSUMPTION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_governance_cycle_history_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_governance_cycle_history_organ.genome.v1.json index 4a11edfc..05e7d018 100644 --- a/governance/subsystem_genomes/linguistic_governance_cycle_history_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_governance_cycle_history_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_GOVERNANCE_CYCLE_HISTORY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_GOVERNANCE_CYCLE_HISTORY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_governance_cycle_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_governance_cycle_organ.genome.v1.json index 248a8551..a4ebbd4e 100644 --- a/governance/subsystem_genomes/linguistic_governance_cycle_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_governance_cycle_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_GOVERNANCE_CYCLE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_GOVERNANCE_CYCLE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_lineage_viz_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_lineage_viz_organ.genome.v1.json index 12fba069..835684ec 100644 --- a/governance/subsystem_genomes/linguistic_lineage_viz_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_lineage_viz_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_LINEAGE_VIZ_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_LINEAGE_VIZ_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_mutation_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_mutation_organ.genome.v1.json index cc805160..e66e14cd 100644 --- a/governance/subsystem_genomes/linguistic_mutation_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_mutation_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_MUTATION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_MUTATION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_predictive_cycle_history_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_predictive_cycle_history_organ.genome.v1.json index 3fa4e765..37df9e96 100644 --- a/governance/subsystem_genomes/linguistic_predictive_cycle_history_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_predictive_cycle_history_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_PREDICTIVE_CYCLE_HISTORY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_PREDICTIVE_CYCLE_HISTORY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_predictive_governance_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_predictive_governance_organ.genome.v1.json index 07aed3e5..909d09d1 100644 --- a/governance/subsystem_genomes/linguistic_predictive_governance_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_predictive_governance_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_PREDICTIVE_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_PREDICTIVE_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_preemptive_remediation_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_preemptive_remediation_organ.genome.v1.json index 8ed520e5..e1d579be 100644 --- a/governance/subsystem_genomes/linguistic_preemptive_remediation_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_preemptive_remediation_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_PREEMPTIVE_REMEDIATION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_PREEMPTIVE_REMEDIATION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/linguistic_remediation_organ.genome.v1.json b/governance/subsystem_genomes/linguistic_remediation_organ.genome.v1.json index 1507c8b6..6a8f34cb 100644 --- a/governance/subsystem_genomes/linguistic_remediation_organ.genome.v1.json +++ b/governance/subsystem_genomes/linguistic_remediation_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\LINGUISTIC_REMEDIATION_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/LINGUISTIC_REMEDIATION_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/memory_bank_surface_organ.genome.v1.json b/governance/subsystem_genomes/memory_bank_surface_organ.genome.v1.json index 9f899d75..754f3f68 100644 --- a/governance/subsystem_genomes/memory_bank_surface_organ.genome.v1.json +++ b/governance/subsystem_genomes/memory_bank_surface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\MEMORY_BANK_SURFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/MEMORY_BANK_SURFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/meta_linguistic_governance_organ.genome.v1.json b/governance/subsystem_genomes/meta_linguistic_governance_organ.genome.v1.json index c5b40c71..63be6899 100644 --- a/governance/subsystem_genomes/meta_linguistic_governance_organ.genome.v1.json +++ b/governance/subsystem_genomes/meta_linguistic_governance_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\META_LINGUISTIC_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/META_LINGUISTIC_GOVERNANCE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/mythic_engineering_translator_organ.genome.v1.json b/governance/subsystem_genomes/mythic_engineering_translator_organ.genome.v1.json index 5303f7b2..5c3f079b 100644 --- a/governance/subsystem_genomes/mythic_engineering_translator_organ.genome.v1.json +++ b/governance/subsystem_genomes/mythic_engineering_translator_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\MYTHIC_ENGINEERING_TRANSLATOR_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/MYTHIC_ENGINEERING_TRANSLATOR_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/naming_genome_organ.genome.v1.json b/governance/subsystem_genomes/naming_genome_organ.genome.v1.json index 0908bf8d..09f36531 100644 --- a/governance/subsystem_genomes/naming_genome_organ.genome.v1.json +++ b/governance/subsystem_genomes/naming_genome_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\NAMING_GENOME_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/NAMING_GENOME_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/naming_protocol_organ.genome.v1.json b/governance/subsystem_genomes/naming_protocol_organ.genome.v1.json index d202b61f..c2014071 100644 --- a/governance/subsystem_genomes/naming_protocol_organ.genome.v1.json +++ b/governance/subsystem_genomes/naming_protocol_organ.genome.v1.json @@ -44,7 +44,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\NAMING_PROTOCOL_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/NAMING_PROTOCOL_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/nova_landing_surface_organ.genome.v1.json b/governance/subsystem_genomes/nova_landing_surface_organ.genome.v1.json index 2aed72fc..59ecf0a0 100644 --- a/governance/subsystem_genomes/nova_landing_surface_organ.genome.v1.json +++ b/governance/subsystem_genomes/nova_landing_surface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\NOVA_LANDING_SURFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/NOVA_LANDING_SURFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/nova_workspace_interface_organ.genome.v1.json b/governance/subsystem_genomes/nova_workspace_interface_organ.genome.v1.json index 7c5b750a..71a7b9de 100644 --- a/governance/subsystem_genomes/nova_workspace_interface_organ.genome.v1.json +++ b/governance/subsystem_genomes/nova_workspace_interface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\NOVA_WORKSPACE_INTERFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/NOVA_WORKSPACE_INTERFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/operator_console_interface_organ.genome.v1.json b/governance/subsystem_genomes/operator_console_interface_organ.genome.v1.json index 4c8ddc33..750be1eb 100644 --- a/governance/subsystem_genomes/operator_console_interface_organ.genome.v1.json +++ b/governance/subsystem_genomes/operator_console_interface_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\OPERATOR_CONSOLE_INTERFACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/OPERATOR_CONSOLE_INTERFACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/operator_workspace_organ.genome.v1.json b/governance/subsystem_genomes/operator_workspace_organ.genome.v1.json index 0c132f02..66dcf148 100644 --- a/governance/subsystem_genomes/operator_workspace_organ.genome.v1.json +++ b/governance/subsystem_genomes/operator_workspace_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\OPERATOR_WORKSPACE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/OPERATOR_WORKSPACE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/output_integrity_organ.genome.v1.json b/governance/subsystem_genomes/output_integrity_organ.genome.v1.json index a627542e..33322f2e 100644 --- a/governance/subsystem_genomes/output_integrity_organ.genome.v1.json +++ b/governance/subsystem_genomes/output_integrity_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\OUTPUT_INTEGRITY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/OUTPUT_INTEGRITY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/platform_console_interfaces_organ.genome.v1.json b/governance/subsystem_genomes/platform_console_interfaces_organ.genome.v1.json index fbc651ee..759b9fbd 100644 --- a/governance/subsystem_genomes/platform_console_interfaces_organ.genome.v1.json +++ b/governance/subsystem_genomes/platform_console_interfaces_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\PLATFORM_CONSOLE_INTERFACES_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/PLATFORM_CONSOLE_INTERFACES_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/project_infi_law_organ.genome.v1.json b/governance/subsystem_genomes/project_infi_law_organ.genome.v1.json index 1660d46c..631c6562 100644 --- a/governance/subsystem_genomes/project_infi_law_organ.genome.v1.json +++ b/governance/subsystem_genomes/project_infi_law_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\PROJECT_INFI_LAW_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/PROJECT_INFI_LAW_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/project_infi_state_machine_organ.genome.v1.json b/governance/subsystem_genomes/project_infi_state_machine_organ.genome.v1.json index 621db5df..33fc74ac 100644 --- a/governance/subsystem_genomes/project_infi_state_machine_organ.genome.v1.json +++ b/governance/subsystem_genomes/project_infi_state_machine_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\PROJECT_INFI_STATE_MACHINE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/PROJECT_INFI_STATE_MACHINE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/prompt_assembly_organ.genome.v1.json b/governance/subsystem_genomes/prompt_assembly_organ.genome.v1.json index daac7e1f..58ebf0fd 100644 --- a/governance/subsystem_genomes/prompt_assembly_organ.genome.v1.json +++ b/governance/subsystem_genomes/prompt_assembly_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\PROMPT_ASSEMBLY_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/PROMPT_ASSEMBLY_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/reasoning_contract_organ.genome.v1.json b/governance/subsystem_genomes/reasoning_contract_organ.genome.v1.json index 32e17c90..057a000d 100644 --- a/governance/subsystem_genomes/reasoning_contract_organ.genome.v1.json +++ b/governance/subsystem_genomes/reasoning_contract_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\REASONING_CONTRACT_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/REASONING_CONTRACT_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/run_ledger_binding_organ.genome.v1.json b/governance/subsystem_genomes/run_ledger_binding_organ.genome.v1.json index ab087f11..0eedf3fa 100644 --- a/governance/subsystem_genomes/run_ledger_binding_organ.genome.v1.json +++ b/governance/subsystem_genomes/run_ledger_binding_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\RUN_LEDGER_BINDING_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/RUN_LEDGER_BINDING_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/security_protocol_organ.genome.v1.json b/governance/subsystem_genomes/security_protocol_organ.genome.v1.json index 361d4578..52901b7b 100644 --- a/governance/subsystem_genomes/security_protocol_organ.genome.v1.json +++ b/governance/subsystem_genomes/security_protocol_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\SECURITY_PROTOCOL_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/SECURITY_PROTOCOL_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/state_hygiene_organ.genome.v1.json b/governance/subsystem_genomes/state_hygiene_organ.genome.v1.json index ac4f1da1..ca91799f 100644 --- a/governance/subsystem_genomes/state_hygiene_organ.genome.v1.json +++ b/governance/subsystem_genomes/state_hygiene_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\STATE_HYGIENE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/STATE_HYGIENE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/system_guard_organ.genome.v1.json b/governance/subsystem_genomes/system_guard_organ.genome.v1.json index 38b862fd..aabe82f2 100644 --- a/governance/subsystem_genomes/system_guard_organ.genome.v1.json +++ b/governance/subsystem_genomes/system_guard_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\SYSTEM_GUARD_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/SYSTEM_GUARD_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/v10_action_engine_organ.genome.v1.json b/governance/subsystem_genomes/v10_action_engine_organ.genome.v1.json index fcbdf655..35a42729 100644 --- a/governance/subsystem_genomes/v10_action_engine_organ.genome.v1.json +++ b/governance/subsystem_genomes/v10_action_engine_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\V10_ACTION_ENGINE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/V10_ACTION_ENGINE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/v10_core_organ.genome.v1.json b/governance/subsystem_genomes/v10_core_organ.genome.v1.json index f722b521..16145da6 100644 --- a/governance/subsystem_genomes/v10_core_organ.genome.v1.json +++ b/governance/subsystem_genomes/v10_core_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\V10_CORE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/V10_CORE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/v10_runtime_organ.genome.v1.json b/governance/subsystem_genomes/v10_runtime_organ.genome.v1.json index 5437c000..6f7287db 100644 --- a/governance/subsystem_genomes/v10_runtime_organ.genome.v1.json +++ b/governance/subsystem_genomes/v10_runtime_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\V10_RUNTIME_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/V10_RUNTIME_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/v9_core_organ.genome.v1.json b/governance/subsystem_genomes/v9_core_organ.genome.v1.json index ad5eb1b2..35855d4d 100644 --- a/governance/subsystem_genomes/v9_core_organ.genome.v1.json +++ b/governance/subsystem_genomes/v9_core_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\V9_CORE_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/V9_CORE_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/v9_runtime_organ.genome.v1.json b/governance/subsystem_genomes/v9_runtime_organ.genome.v1.json index 537612a2..cfadbf8e 100644 --- a/governance/subsystem_genomes/v9_runtime_organ.genome.v1.json +++ b/governance/subsystem_genomes/v9_runtime_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\V9_RUNTIME_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/V9_RUNTIME_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/workflow_interfaces_organ.genome.v1.json b/governance/subsystem_genomes/workflow_interfaces_organ.genome.v1.json index f9cb13ed..d1bda83b 100644 --- a/governance/subsystem_genomes/workflow_interfaces_organ.genome.v1.json +++ b/governance/subsystem_genomes/workflow_interfaces_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\WORKFLOW_INTERFACES_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/WORKFLOW_INTERFACES_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/governance/subsystem_genomes/workflow_runtime_organ.genome.v1.json b/governance/subsystem_genomes/workflow_runtime_organ.genome.v1.json index 2380be06..1df830cf 100644 --- a/governance/subsystem_genomes/workflow_runtime_organ.genome.v1.json +++ b/governance/subsystem_genomes/workflow_runtime_organ.genome.v1.json @@ -43,7 +43,7 @@ }, "proof": { "bundles": [ - "E:\\project-infi\\docs\\proof\\platform\\WORKFLOW_RUNTIME_ORGAN_GOVERNED_PROOF.md" + "docs/proof/platform/WORKFLOW_RUNTIME_ORGAN_GOVERNED_PROOF.md" ], "posture": "governed", "target_bundles": [ diff --git a/src/otem_ceiling.py b/src/otem_ceiling.py index f234356e..32899d93 100644 --- a/src/otem_ceiling.py +++ b/src/otem_ceiling.py @@ -160,6 +160,12 @@ def __init__(self, *, runtime_dir: Path | str | None = None) -> None: def state_path(self) -> Path: return self._runtime_dir / STATE_FILENAME + def configure_runtime_dir(self, runtime_dir: Path | str) -> None: + """Point the controller at an isolated runtime directory and reload state.""" + with self._lock: + self._runtime_dir = Path(runtime_dir).expanduser() + self._state = self._load_state() + def _load_state(self) -> dict[str, Any]: path = self._runtime_dir / STATE_FILENAME if not path.exists(): diff --git a/tests/test_api.py b/tests/test_api.py index 3d8184dc..9452878f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -17,6 +17,7 @@ from src.conversation_memory import conversation_memory from src.jarvis_memory_board import MemoryController, default_memory_slots from src.mock_ai import MockStreamingTextGenerator +from src.otem_ceiling import otem_ceiling from src.jarvis_protocol import JarvisMessage, ProviderResponse from src.phase_gate import Phase, demote_component, reset_registry @@ -37,6 +38,7 @@ def setUp(self): self.original_governance_runtime_dir = api.governance_layer.runtime_dir self.original_module_governance_runtime_dir = api.module_governance.runtime_dir self.original_detachment_guard_runtime_dir = api.cognitive_bridge_service.detachment_guard.runtime_dir + self.original_otem_ceiling_runtime_dir = otem_ceiling.state_path.parent self.original_continuity_runtime_dir = api.continuity_profile_store.runtime_dir self.original_continuity_witness_runtime_dir = api.continuity_witness_store.runtime_dir self.original_v9_runtime_dir = api.v9_runtime.runtime_dir @@ -57,6 +59,7 @@ def setUp(self): api.module_governance.reset() api.cognitive_bridge_service.detachment_guard.configure_runtime_dir(self.guard_root) api.cognitive_bridge_service.detachment_guard.reset() + otem_ceiling.configure_runtime_dir(self.guard_root) api.continuity_profile_store.configure_runtime_dir(self.guard_root) api.continuity_profile_store.reset() api.continuity_witness_store.configure_runtime_dir(self.guard_root) @@ -88,6 +91,7 @@ def tearDown(self): api.module_governance.configure_runtime_dir(self.original_module_governance_runtime_dir) api.cognitive_bridge_service.detachment_guard.configure_runtime_dir(self.original_detachment_guard_runtime_dir) api.cognitive_bridge_service.detachment_guard.reset() + otem_ceiling.configure_runtime_dir(self.original_otem_ceiling_runtime_dir) api.continuity_profile_store.configure_runtime_dir(self.original_continuity_runtime_dir) api.continuity_witness_store.configure_runtime_dir(self.original_continuity_witness_runtime_dir) api.v9_runtime.configure_runtime_dir(self.original_v9_runtime_dir) @@ -1136,7 +1140,18 @@ def test_jarvis_protocol_endpoint_matches_preview_truth(self): self.assertEqual(payload["override_result"], expected_preview["override_result"]) self.assertEqual(payload["escalation_result"], expected_preview["escalation_result"]) self.assertEqual(payload["active_doctrine_tags"], expected_preview["active_doctrine_tags"]) - self.assertEqual(payload["reasoning_packet"], expected_preview["reasoning_packet"]) + actual_packet = json.loads(json.dumps(payload["reasoning_packet"])) + expected_packet = json.loads(json.dumps(expected_preview["reasoning_packet"])) + actual_graph_timestamp = actual_packet["reasoning_graph"].pop("timestamp") + expected_graph_timestamp = expected_packet["reasoning_graph"].pop("timestamp") + actual_evaluated_at = actual_packet["rls_verdict"].pop("evaluated_at") + expected_evaluated_at = expected_packet["rls_verdict"].pop("evaluated_at") + + self.assertTrue(actual_graph_timestamp) + self.assertTrue(expected_graph_timestamp) + self.assertTrue(actual_evaluated_at) + self.assertTrue(expected_evaluated_at) + self.assertEqual(actual_packet, expected_packet) self.assertEqual(payload["reasoning_summary"], expected_preview["reasoning_summary"]) self.assertEqual( payload["canonical_guardrail_evaluation"]["id"], @@ -1524,6 +1539,7 @@ def setUp(self): self.original_governance_runtime_dir = api.governance_layer.runtime_dir self.original_module_governance_runtime_dir = api.module_governance.runtime_dir self.original_detachment_guard_runtime_dir = api.cognitive_bridge_service.detachment_guard.runtime_dir + self.original_otem_ceiling_runtime_dir = otem_ceiling.state_path.parent self.original_continuity_runtime_dir = api.continuity_profile_store.runtime_dir self.original_continuity_witness_runtime_dir = api.continuity_witness_store.runtime_dir self.original_v9_runtime_dir = api.jarvis_operator.v9_runtime.runtime_dir @@ -1553,6 +1569,7 @@ def setUp(self): api.module_governance.reset() api.cognitive_bridge_service.detachment_guard.configure_runtime_dir(self.temp_root / "detachment-guard") api.cognitive_bridge_service.detachment_guard.reset() + otem_ceiling.configure_runtime_dir(self.temp_root / "otem-ceiling") api.continuity_profile_store.configure_runtime_dir(self.temp_root / "continuity") api.continuity_profile_store.reset() api.continuity_witness_store.configure_runtime_dir(self.temp_root / "continuity-witness") @@ -1595,6 +1612,7 @@ def tearDown(self): api.module_governance.configure_runtime_dir(self.original_module_governance_runtime_dir) api.cognitive_bridge_service.detachment_guard.configure_runtime_dir(self.original_detachment_guard_runtime_dir) api.cognitive_bridge_service.detachment_guard.reset() + otem_ceiling.configure_runtime_dir(self.original_otem_ceiling_runtime_dir) api.continuity_profile_store.configure_runtime_dir(self.original_continuity_runtime_dir) api.continuity_witness_store.configure_runtime_dir(self.original_continuity_witness_runtime_dir) api.jarvis_operator.v9_runtime.configure_runtime_dir(self.original_v9_runtime_dir) @@ -2122,6 +2140,12 @@ def test_chat_message_blocks_detachment_attempt_and_places_source_on_review_hold "explicit_detachment_request", first_payload["cognitive_bridge"]["detachment_guard"]["reason_codes"], ) + self.assertEqual( + api.cognitive_bridge_service.detachment_guard.snapshot()[ + "temporary_deny_count" + ], + 1, + ) second = self.client.post( f"/api/chat/sessions/{session_id}/message", @@ -2135,7 +2159,7 @@ def test_chat_message_blocks_detachment_attempt_and_places_source_on_review_hold second_payload = second.get_json() self.assertEqual(second_payload["cognitive_bridge"]["decision"], "BLOCK") self.assertIn( - "temporary_review_deny_active", + "otem_ceiling_containment", second_payload["cognitive_bridge"]["detachment_guard"]["reason_codes"], ) @@ -2191,14 +2215,20 @@ def test_detachment_guard_review_hold_can_be_cleared_through_api(self): self.assertTrue(cleared_payload["result"]["refreshed_attestation_required"]) self.assertEqual(cleared_payload["detachment_guard"]["temporary_deny_count"], 0) - allowed = self.client.post( + contained = self.client.post( f"/api/chat/sessions/{session_id}/message", json={ "message": "What do you remember", "response_mode": "operator", }, ) - self.assertEqual(allowed.status_code, 200) + self.assertEqual(contained.status_code, 403) + self.assertIn( + "otem_ceiling_containment", + contained.get_json()["cognitive_bridge"]["detachment_guard"][ + "reason_codes" + ], + ) def test_actions_execute_fails_closed_when_cognitive_bridge_blocks(self): """Approved action execution should stop before the runner when the bridge blocks.""" @@ -6872,7 +6902,13 @@ def test_otem_endpoint_exposes_workflow_handoff_without_side_effects(self, mock_ self.assertTrue(payload["otem"]["workflow_handoff"]["proposal_only"]) queue_meta = payload["otem"].get("execution_approval_queue") if queue_meta: - self.assertEqual(queue_meta.get("status"), "pending") + self.assertIn(queue_meta.get("status"), {"pending", "rejected"}) + if queue_meta.get("status") == "rejected": + self.assertEqual(queue_meta.get("reason"), "rls_escalation_blocked") + self.assertEqual( + (queue_meta.get("rls_verdict") or {}).get("verdict"), + "reject", + ) self.assertEqual( len(api.jarvis_operator.memory_enforcer.list_memories(runtime_context="operator_runtime")), before_memory_count, @@ -9139,7 +9175,7 @@ def test_small_nova_message_treats_loaded_archive_as_document_context(self, mock }, ) - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, 200, response.get_json()) payload = response.get_json() self.assertEqual(payload["response"], fake_model.generate_chat.return_value) self.assertEqual(payload["loaded_session_archive"]["title"], "Reopened session") diff --git a/tests/test_governance_organs_alt4.py b/tests/test_governance_organs_alt4.py index d4b59fae..ba483664 100644 --- a/tests/test_governance_organs_alt4.py +++ b/tests/test_governance_organs_alt4.py @@ -4,7 +4,7 @@ import json import os -from pathlib import Path +from pathlib import Path, PurePosixPath, PureWindowsPath import pytest @@ -24,6 +24,20 @@ def test_genome_registry_valid(): assert len(reg.genomes) >= 6 +def test_genome_proof_bundles_are_repository_relative(): + absolute_bundles: list[str] = [] + + for genome_path in sorted( + (REPO / "governance/subsystem_genomes").glob("*.genome.v1.json") + ): + genome = json.loads(genome_path.read_text(encoding="utf-8")) + for bundle in (genome.get("proof") or {}).get("bundles") or []: + if PureWindowsPath(bundle).is_absolute() or PurePosixPath(bundle).is_absolute(): + absolute_bundles.append(f"{genome_path.name}: {bundle}") + + assert not absolute_bundles, absolute_bundles + + def test_genome_boot_warn_mode(monkeypatch): from src.governance_organs import Alt4Runtime diff --git a/tests/test_otem_ceiling.py b/tests/test_otem_ceiling.py index fb1efdf2..0cb76889 100644 --- a/tests/test_otem_ceiling.py +++ b/tests/test_otem_ceiling.py @@ -51,6 +51,18 @@ def test_operator_invoke_enters_containment(self): self.assertEqual(status.get("pipeline_state"), "diagnostic") self.assertIn("operator_invoke", status.get("activation_triggers") or []) + def test_configure_runtime_dir_reloads_isolated_state(self): + self.controller.evaluate_trigger( + trigger_type="operator_invoke", + summary="isolation source", + ) + isolated_runtime = self._temp_root / "isolated-runtime" + + self.controller.configure_runtime_dir(isolated_runtime) + + self.assertFalse(self.controller.containment_active()) + self.assertEqual(self.controller.state_path, isolated_runtime / "otem_ceiling_state.json") + def test_preview_rejects_unknown_decision(self): self.controller.evaluate_trigger(trigger_type="operator_invoke", summary="preview gate") with self.assertRaises(OtemCeilingError):