Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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):**
Expand Down
16 changes: 16 additions & 0 deletions aaes-os/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion aaes-os/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
}
},
"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: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"
},
"engines": {
"node": ">=20"
},
"dependencies": {
"@aaes-os/architect-agent": "file:../packages/architect-agent"
},
"devDependencies": {
"@types/node": "^22.19.21",
"typescript": "^5.9.3"
Expand Down
7 changes: 7 additions & 0 deletions aaes-os/src/model/ModelProvider.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type {
ModelOperation,
ModelProposal,
ModelProvider,
OperationType,
ProposalGoal,
} from '@aaes-os/architect-agent';
20 changes: 20 additions & 0 deletions aaes-os/src/model/OllamaProvider.ts
Original file line number Diff line number Diff line change
@@ -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<ModelProposal> {
return this.delegate.generate(prompt);
}
}

export type { OllamaProviderOptions };
14 changes: 14 additions & 0 deletions aaes-os/src/storage/trace_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
31 changes: 31 additions & 0 deletions aaes-os/tests/OllamaProvider.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
44 changes: 44 additions & 0 deletions aaes-os/tests/trace_store.test.ts
Original file line number Diff line number Diff line change
@@ -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/,
);
});
});
10 changes: 10 additions & 0 deletions aaes-os/tsconfig.model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist/model-test"
},
"include": [
"src/model/**/*.ts",
"tests/OllamaProvider.test.ts"
]
}
Loading
Loading