Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
37db1eb
feat(runtime): run autonomous subscription-backed agents
apresmoi Aug 23, 2026
8fc21aa
feat(contracts): publish canonical runtime manifests
apresmoi Aug 28, 2026
c4aec8c
feat(grok): secure subscription-backed CLI sessions
apresmoi Aug 28, 2026
78ddc0e
feat(broker): add native engine broker ABI
apresmoi Aug 28, 2026
baa88fd
feat(broker): enforce durable Grok turn authority
apresmoi Aug 28, 2026
b7ae476
feat(runtime): route engines through scoped production capabilities
apresmoi Aug 28, 2026
96b321a
feat(runtime): run durable organization runtime v2 schedules
apresmoi Aug 28, 2026
fad269d
build(runtime): package native and explicit test runtimes
apresmoi Aug 28, 2026
5eddf40
docs(runtime): document autonomous brokered agent execution
apresmoi Aug 28, 2026
69b7c8a
style(native): normalize broker source endings
apresmoi Aug 28, 2026
759f425
chore(build): ignore generated test runtime
apresmoi Aug 28, 2026
3b9ceeb
fix(native): restore broker source trailing newlines to match committ…
apresmoi Aug 30, 2026
7c2cd0e
fix(observability): allocate causal sequence numbers atomically under…
apresmoi Aug 30, 2026
c67ab7c
fix(runtime): publish reconciliation leases via link so readers never…
apresmoi Aug 30, 2026
882650d
feat(memory): wire Mneme recall and turn write-back through the organ…
apresmoi Aug 30, 2026
2c622d6
feat(usage): record per-turn token accounting to an advisory append-o…
apresmoi Aug 30, 2026
a9d4256
feat(agy): give AGY full tool cognition, MCP registration, and usage …
apresmoi Aug 30, 2026
b33fc72
ci: bound every job with a timeout
apresmoi Aug 30, 2026
2f2ab3d
ci: name every job after what it verifies
apresmoi Aug 30, 2026
65f3978
docs: require every change to land through a pull request
apresmoi Aug 30, 2026
9f166a4
fix(test-runtime): bound child teardown and stub the Moltnet CLI
apresmoi Aug 30, 2026
d59c965
fix(broker): survive a client that disconnects mid-turn
apresmoi Aug 30, 2026
c28eeea
fix(pi): treat an empty process group as settled on Linux
apresmoi Aug 30, 2026
c24f3d8
test(runtime): derive CLI health waits from the test timeout
apresmoi Aug 30, 2026
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:

jobs:
test:
name: harness + runtime tests
timeout-minutes: 25
runs-on: ubuntu-latest
steps:
- name: Check out
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ concurrency:

jobs:
publish:
name: publish @noopolis/daimon to npm
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Check out
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/
dist/
dist-test-runtime/
.runtime/
*.tsbuildinfo

20 changes: 20 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,23 @@ deployment. Daimon owns only the per-agent runtime boundary.
policy, recall, or MCP.
- Pi-specific logic belongs under `src/pi/`.
- Examples should be runnable with `npm run e2e:pi-agent`.

## Branches and pull requests

**Never commit to `main`.** Every change lands through a pull request, without
exception — including one-line fixes, CI configuration, documentation, and
version bumps. Work on a branch, push it, open the PR, and let CI run.

Direct commits to `main` bypass the checks that catch what local runs do not.
A zero-byte receipt store, a package that ships without its native binary, and
a two-week-red pipeline all reached `main` in this ecosystem while every local
gate was green — CI found them the first time it ran over the code.

- Branch names describe the change: `feat/…`, `fix/…`, `ci/…`, `docs/…`.
- Commit messages are conventional and single-line (`feat:`, `fix:`, `docs:`,
`ci:`, `chore:`, `refactor:`, `test:`).
- Never add co-author lines, sign-offs, or AI attributions.
- Commit as you go rather than in one batch at the end, so history shows how
the work progressed.
- Merge with a merge commit rather than a squash when the individual commits
carry meaning; squashing collapses that history irreversibly.
8 changes: 8 additions & 0 deletions Dockerfile.test-runtime
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:22-bookworm-slim
WORKDIR /opt/noopolis/daimon-test
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
COPY dist-test-runtime /opt/noopolis/daimon-test/dist
LABEL org.noopolis.daimon.explicit-test-runtime="true"
USER 65534:65534
ENTRYPOINT ["/usr/local/bin/node", "/opt/noopolis/daimon-test/dist/runtime/testRuntimeSubprocess.js"]
117 changes: 117 additions & 0 deletions MIGRATION_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Daimon organization-runtime migration plan

## Phase 1A: public contract — complete

- Add only the versioned, organization-neutral
`noopolis.daimon.organization-runtime.v1` parser, schema, public types, and
`@noopolis/daimon/runtime` export.
- The v1 config is a strict flat projection: host control binding plus an
unordered, non-empty collection of isolated agent records. It cannot carry
organization graph, coordination, scheduling, deployment, or Moltnet data.
The standard JSON Schema covers structure; the pure public parser is
normative for semantic checks such as duplicate agent ids.
- Define the host, wake, activity, health, and shutdown interfaces now. Phase
1A is validation-only; Phase 1B provides the host, process, server, engine
dispatch, and CLI implementation while retaining the same public contract.

## Phase 1B: isolated runtime host — complete

- Add the organization-neutral `noopolis.daimon.organization-runtime.v1`
host implementation behind the already published public API.
- A host reads one config, validates it, creates one isolated existing Daimon
harness per agent record, routes authenticated wake, health, and activity
operations by agent id, serializes each agent's wakes independently, and
quiesces all children on shutdown.
- The schema is a strict flat projection. It enumerates only: schema version,
agent id, runtime-home path, workspace path, engine intent, control endpoint,
and surface bindings. It rejects every unknown field and specifically rejects
team, parent, member, role, edge, schedule, wake-selection, deployment, and
Moltnet-topology semantics. The host does no wake generation or coordination;
it only provides agent-id routing, per-agent queue/lifecycle/health/activity.
- Engine process creation remains in Daimon. The public runtime does not accept
arbitrary commands, raw process handles, or caller-supplied environment maps.
Fake engines are test-only injection points and make this phase deterministic.

The exact v1 JSON shape is:

```ts
type OrganizationRuntimeEngineIntent =
| { kind: "codex" | "grok" | "agy" };
type OrganizationRuntimeAgentConfig = Readonly<{
id: string;
name: string;
instructions: string;
runtimeHomePath: string;
workspacePath: string;
engine: OrganizationRuntimeEngineIntent;
}>;
type OrganizationRuntimeConfig = Readonly<{
version: "noopolis.daimon.organization-runtime.v1";
host: Readonly<{
bindHost: string;
port: number;
controlTokenEnv: string;
}>;
agents: readonly OrganizationRuntimeAgentConfig[];
}>;
```

All objects are strict; there are no optional properties or arbitrary metadata
bags in v1. `id` is unique, root agent paths are absolute, caller-created real
directories, and physically isolated by held directory identities. Runtime
homes must be owned `0700`; workspaces must be owned and not group/other
writable. The
control token is identified only by a safe environment-variable name; secret
material never appears in the config. Unknown schema versions are rejected
before a host starts or a child is constructed. The public signatures are:

```ts
parseOrganizationRuntimeConfig(value: unknown): OrganizationRuntimeConfig;

interface OrganizationRuntimeHost {
start(): Promise<void>;
wake(request: OrganizationRuntimeWakeRequest): Promise<OrganizationRuntimeWakeResult>;
health(agentId?: string): Promise<OrganizationRuntimeHealth>;
activity(request: OrganizationRuntimeActivityRequest): Promise<OrganizationRuntimeActivityPage>;
stop(): Promise<OrganizationRuntimeShutdownCompletion>;
}
```

`OrganizationRuntimeHost` exposes `wake`, `health`, `activity`, and idempotent
`stop`; each request is keyed by an agent id and the host exposes no
coordination/wake-generation API. Fake engine construction is internal
test-only injection, never config data or a public production escape hatch.
The CLI is exactly `daimon-runtime run --config <path>`.

## Files

- Add `src/runtime/` with its own `AGENTS.md` and `CLAUDE.md` symlink. It now
contains the strict contract, isolated host, control server, CLI, and focused
tests, with each source file kept below 400 lines.
- Additive pre-1.0 bump to `0.2.0`; retain the existing `.`, `./pi`, and
`./observability` entrypoints unchanged, then add `./runtime`.
- Update docs only as required to expose this exact contract and retain safe
compatible per-agent APIs.

## Tests and verification

- Contract coverage: invalid config; forbidden organization fields; safe auth
environment names; agent-home/workspace path syntax and physical roots;
duplicate ids; closed Codex/Grok/AGY engine intents; public method types;
retained imports; package closure.
- Run typecheck, focused tests, full unit suite, build, `npm pack`, install the
packed tarball into a clean temporary consumer, import the retained and new
entrypoints there, and inspect the final diff for forbidden consumer
terminology and raw credential/process APIs.

## Migration and terminal conditions

- This completed phase introduces the Daimon host and public contract only; it does not
change any downstream consumer. A deferred downstream compiler/consumer E2E
phase will emit one compiled v1 config, start one container entrypoint/host
process, verify N isolated one-agent runtimes with targeted and concurrent
fake wakes, and prove that the consumer never instantiates Daimon handles or
engines. No Docker work is permitted in this Daimon phase.
- Stop and return for review when implementation, test evidence, package
closure, and an explicit public-contract summary are complete. Do not touch
credentials, Docker, live repositories, or external services.
Loading
Loading