Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
bb49cf5
feat(cli): add init --template to scaffold from bundled examples
apresmoi Aug 15, 2026
9c50852
feat(daimon): compile autonomous runtime organizations
apresmoi Aug 23, 2026
ab49a22
fix(auth): serialize immutable target secret publication
apresmoi Aug 28, 2026
990d691
feat(manifest): declare autonomous network resources
apresmoi Aug 28, 2026
56bf60a
feat(runtime): consume autonomous daimon contracts
apresmoi Aug 28, 2026
e2d8558
feat(build): package provenance-bound runtimes
apresmoi Aug 28, 2026
62b7f65
feat(compiler): provision isolated runtime organizations
apresmoi Aug 28, 2026
8ac5110
feat(deployment): ship verified no-replace activation
apresmoi Aug 28, 2026
2e3c524
feat(deployment): migrate persistent runtime state
apresmoi Aug 28, 2026
08c83ee
feat(deployment): cut over verified runtime candidates
apresmoi Aug 28, 2026
d46ab2b
fix(deployment): preserve durable lifecycle completion
apresmoi Aug 28, 2026
3ae62e5
feat(distribution): reattach consumed runtime state
apresmoi Aug 28, 2026
490f08a
test(e2e): compile explicit runtime mcp declarations
apresmoi Aug 28, 2026
d1eadde
docs: define operational runtime boundaries
apresmoi Aug 28, 2026
88bcdf9
docs(website): explain autonomous runtime deployment
apresmoi Aug 28, 2026
9baf198
ci: verify provenance-bound runtime artifacts
apresmoi Aug 28, 2026
d97d356
fix(runtime): emit declared skills into the roots Moltnet installs it…
apresmoi Aug 30, 2026
68e77fe
fix(daimon): re-vendor the contract manifest and pin agents[].memory …
apresmoi Aug 30, 2026
a719f89
feat(memory): lower Spawnfile memory declarations into the Daimon run…
apresmoi Aug 30, 2026
f3ccf04
feat(usage): aggregate per-agent and per-provider token usage behind …
apresmoi Aug 30, 2026
c49685e
feat(export): carry both usage ledger generations into exported run a…
apresmoi Aug 30, 2026
6f2a9a1
fix(compiler): reattach durable memory and usage volumes across redep…
apresmoi Aug 30, 2026
2c67b16
fix(moltnet): select the binary probe by execution platform, not buil…
apresmoi Aug 30, 2026
f27b2ee
feat(compiler): reject a daimon attachment when the staged Moltnet la…
apresmoi Aug 30, 2026
cd08a41
ci: check out a Daimon fixture for the source-provenance build test
apresmoi Aug 30, 2026
e50fef5
feat(moltnet): pin release v0.1.18 and admit its daimon-bridge capabi…
apresmoi Aug 30, 2026
430cc6f
ci: test only spawnfile, dropping sibling-repo suites and cross-repo …
apresmoi Aug 30, 2026
7af72a4
ci: bound every job with a timeout
apresmoi Aug 30, 2026
a25a8ed
ci: name every job after what it verifies
apresmoi Aug 30, 2026
ca04312
fix(cli): report the cause when a product-state clone fails
apresmoi Aug 30, 2026
0124ef5
docs: require every change to land through a pull request
apresmoi Aug 30, 2026
df3594d
ci: run the product-state preseed check as root so it can read the vo…
apresmoi Aug 30, 2026
794759f
ci: drop the daimon runtime image from the matrix it cannot build
apresmoi Aug 30, 2026
799f01b
test: exercise the Daimon ownership guard symlink rejection in a cont…
apresmoi Aug 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:

jobs:
deploy:
name: deploy spawnfile.com
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ concurrency:

jobs:
publish:
name: publish spawnfile to npm
timeout-minutes: 20
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
Expand All @@ -43,6 +45,11 @@ jobs:
- name: Audit runtime dependencies
run: npm audit --omit=dev --audit-level=high

- name: Enable cross-architecture helper builds
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64

- name: Verify tag matches package version
shell: bash
run: |
Expand All @@ -61,9 +68,33 @@ jobs:
exit 1
fi

- name: Rebuild dual-architecture native helpers
run: npm run build:native

- name: Build
run: npm run build

- name: Verify Git-free offline linux/amd64 source build
run: npm run test:source-provenance-docker

- name: Check out Moltnet provenance fixture
uses: actions/checkout@v4
with:
repository: noopolis/moltnet
path: moltnet-fixture

- name: Verify Git-free offline linux/amd64 Moltnet build
env:
SPAWNFILE_TEST_MOLTNET_SOURCE: ${{ github.workspace }}/moltnet-fixture
run: npm run test:moltnet-source-provenance-docker

- name: Remove Moltnet provenance fixture
if: always()
run: rm -rf -- moltnet-fixture

- name: Verify native helper syscalls
run: node --test scripts/native-helper-artifacts.test.mjs scripts/native-helper-integration.test.mjs

- name: Verify package contents
run: npm run verify:package-closure

Expand Down
26 changes: 18 additions & 8 deletions .github/workflows/runtime-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ concurrency:

jobs:
build:
name: ${{ matrix.runtime }} runtime image
timeout-minutes: 30
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -57,14 +59,22 @@ jobs:
context: runtime-images/picoclaw
build_args: |
PICOCLAW_VERSION=v0.3.1
- runtime: daimon
image: noopolis/spawnfile-runtime-daimon
version: 0.1.2
context: runtime-images/daimon
build_args: |
DAIMON_VERSION=0.1.2
MNEME_VERSION=0.1.1
PI_VERSION=0.79.10
# The Daimon runtime image is deliberately absent from this matrix.
# It cannot be built by a plain `docker build` of a context: the
# Dockerfile opens with `FROM daimon_package` and needs a
# `--build-context` carrying a packed Daimon tarball, plus a
# capability receipt, three content digests, and eight pinned CLI
# artifact URLs and hashes. It also hard-pins linux/amd64, which
# contradicts this job's two-platform build. The entry that used to
# sit here passed DAIMON_VERSION/MNEME_VERSION/PI_VERSION — three
# args the Dockerfile does not declare — so it had never produced an
# image, only a red check.
#
# `npm run build:local-daimon` (scripts/build-local-daimon-runtime.mjs)
# assembles all of that and is the supported path today. Publishing
# from CI means teaching this workflow to call that script with a
# non-loopback registry target, which `resolveLocalImageTag` currently
# refuses by design.
steps:
- name: Check out
uses: actions/checkout@v4
Expand Down
151 changes: 21 additions & 130 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ permissions:

jobs:
root:
name: compiler + runtime tests
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- name: Check out Spawnfile
Expand All @@ -28,144 +30,33 @@ jobs:
- name: Audit runtime dependencies
run: npm audit --omit=dev --audit-level=high

- name: Enable cross-architecture helper builds
uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64

- name: Typecheck
run: npm run typecheck

- name: Rebuild dual-architecture native helpers
run: npm run build:native

- name: Build
run: npm run build

- name: Verify native helper syscalls
run: node --test scripts/native-helper-artifacts.test.mjs scripts/native-helper-integration.test.mjs

# Preseed reads the candidate volume through its Docker Mountpoint and
# relies on host rename/fsync/hardlink semantics a container cannot give
# it. On a rootful Linux daemon /var/lib/docker/volumes/*/_data is
# root-owned 0700, so this needs root — it passes unprivileged on macOS
# only because Docker runs in a VM there.
- name: Verify named-volume product-state preseed
run: sudo -E env "PATH=$PATH" npm run test:product-state-volume

- name: Boundary tests
run: npm run test:boundaries

- name: Coverage
run: npm run coverage

simfile:
runs-on: ubuntu-latest
steps:
- name: Check out Simfile
uses: actions/checkout@v4
with:
repository: noopolis/simfile
path: ecosystem/simfile

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: ecosystem/simfile/package-lock.json

- name: Install dependencies
working-directory: ecosystem/simfile
run: npm ci

- name: Typecheck
working-directory: ecosystem/simfile
run: npm run typecheck

- name: Test
working-directory: ecosystem/simfile
run: npm test

daimon:
runs-on: ubuntu-latest
steps:
- name: Check out Daimon
uses: actions/checkout@v4
with:
repository: noopolis/daimon
path: ecosystem/daimon

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: ecosystem/daimon/package-lock.json

- name: Install dependencies
working-directory: ecosystem/daimon
run: npm ci

- name: Typecheck
working-directory: ecosystem/daimon
run: npm run typecheck

- name: Test
working-directory: ecosystem/daimon
run: npm test

mneme:
runs-on: ubuntu-latest
steps:
- name: Check out Mneme
uses: actions/checkout@v4
with:
repository: noopolis/mneme
path: ecosystem/mneme

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: ecosystem/mneme/package-lock.json

- name: Install dependencies
working-directory: ecosystem/mneme
run: npm ci

- name: Typecheck
working-directory: ecosystem/mneme
run: npm run typecheck

- name: Test
working-directory: ecosystem/mneme
run: npm test

stele:
runs-on: ubuntu-latest
steps:
- name: Check out Stele
uses: actions/checkout@v4
with:
repository: noopolis/stele
path: ecosystem/stele

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: ecosystem/stele/package-lock.json

- name: Install dependencies
working-directory: ecosystem/stele
run: npm ci

- name: Typecheck
working-directory: ecosystem/stele
run: npm run typecheck

- name: Test
working-directory: ecosystem/stele
run: npm test

moltnet:
runs-on: ubuntu-latest
steps:
- name: Check out Moltnet
uses: actions/checkout@v4
with:
repository: noopolis/moltnet
path: ecosystem/moltnet

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ecosystem/moltnet/go.mod

- name: Test
working-directory: ecosystem/moltnet
run: go test ./...
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ node_modules
.env
.moltnet
.worktree-bootstrap.json
.local-daimon-runtime-identity.json
21 changes: 18 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,22 @@ This repository is the reference implementation of the Spawnfile v0.1 compiler.
- The CLI should stay thin. Business logic belongs in compiler modules, not command handlers.
- The compiler should operate on resolved graph data, not raw YAML, after load and validation.

## Commits
## Branches and pull requests

- Use conventional commits (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`).
- Never add co-author attributions, sign-off lines, or AI credit to commits. No `Co-Authored-By`, no `Signed-off-by`, no mentions of AI tools in commit messages since its obvious.
**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.
Loading
Loading