Initial setup: Nix flake wrapping Hermes Agent as Speckl SME

- flake.nix wrapping github:NousResearch/hermes-agent
- NixOS module (nix/nixosModules.nix) with Speckl-preset config:
  - Model: anthropic/claude-opus-4.6
  - Memory + skill generation + user modeling enabled
  - Container mode for self-modification
  - Deep-merged with user overrides
- documents/SOUL.md — Speckl domain expert persona
- documents/AGENTS.md — workspace rules
- documents/USER.md — user template
- README.md with usage instructions
This commit is contained in:
cos Agent 2026-05-12 15:03:56 -07:00
commit e99b08c0da
9 changed files with 360 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
.hermes/
result/
__pycache__/
*.pyc
.env

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Scott Scoble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

103
README.md Normal file
View file

@ -0,0 +1,103 @@
# hermes-speckl — Nix flake for Speckl SME Agent
A pre-configured [Hermes Agent](https://github.com/NousResearch/hermes-agent) instance
purpose-built for the **Speckl** specification language ecosystem.
## What this gives you
One `nixos-rebuild switch` and you have a self-learning AI agent that:
- Understands SpeckDL, the Dark Provenance model, and your compiler architecture
- Compounds expertise across every Speckl task (code review, spec writing, research)
- Runs as a hardened systemd service with declarative config
- Connects via Discord, Telegram, Slack, WhatsApp, or CLI
- Gets faster on recurring tasks the longer it runs
## Usage
Add to your system flake:
```nix
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
hermes-speckl.url = "github:sscoble/hermes-speckl";
};
outputs = { nixpkgs, hermes-speckl, ... }: {
nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
hermes-speckl.nixosModules.speckl
./configuration.nix
];
};
};
}
```
Then configure:
```nix
# configuration.nix
{ config, ... }: {
services.hermes-speckl = {
enable = true;
# Declarative config (deep-merged into cli-config.yaml)
settings = {
model.default = "anthropic/claude-opus-4.6";
toolsets = [ "all" ];
};
# LLM API keys (use sops-nix or agenix)
environmentFiles = [ config.sops.secrets."hermes-env".path ];
};
}
```
Apply:
```bash
nixos-rebuild switch --flake .#your-host
systemctl status hermes-speckl
journalctl -u hermes-speckl -f
```
## What's pre-configured
| Setting | Value |
|---|---|
| Model | `anthropic/claude-opus-4.6` (override via `settings.model.default`) |
| Memory | Enabled with skill generation + user modeling |
| Terminal | Local backend, 180s timeout |
| Context compression | On, 85% threshold, Gemini 3 Flash summarizer |
| Agent | 60 max turns, medium reasoning effort |
| Container mode | Enabled (agent can install packages for self-modification) |
| SOUL.md | Speckl domain expert persona (see `documents/SOUL.md`) |
## Container mode
The agent runs inside a persistent Ubuntu container with:
- **Node 22** via NodeSource (for MCP servers, js tooling)
- **Python 3.12 venv** via uv (for pip installs, custom tools)
- **Writable Nix store** (bind-mounted from host)
- **Sudo access** for the agent user (self-modification)
This means the agent can `npm i -g`, `pip install`, and modify its own
environment — essential for skill creation and tool discovery.
## Development
```bash
# Run directly
nix run github:sscoble/hermes-speckl -- setup
# Or from a local clone
git clone https://os.scoble.me/forgejo/sscoble/hermes-speckl
cd hermes-speckl
nix build
./result/bin/hermes setup
```

30
documents/AGENTS.md Normal file
View file

@ -0,0 +1,30 @@
# AGENTS.md — Speckl SME Workspace
Your workspace root for Speckl operations.
## Files you manage
- `SOUL.md` — Your domain expertise persona (read this first, always)
- `USER.md` — Who you're working with
- `MEMORY.md` — Your long-term curated memory (you write this)
- `memory/YYYY-MM-DD.md` — Daily operational notes
- `skills/` — Hermes auto-generated skill files (compounded expertise)
## Directory structure
```
workspace/
├── SOUL.md ← read me first
├── USER.md ← human you serve
├── MEMORY.md ← what you've learned long-term
├── memory/
│ └── YYYY-MM-DD.md
└── skills/ ← auto-generated by learning loop
```
## Rules
1. Always read SOUL.md first in a new session.
2. Capture what matters in memory/.
3. Curate MEMORY.md from daily notes periodically.
4. Trust your skill library — it's built from real experience.

39
documents/SOUL.md Normal file
View file

@ -0,0 +1,39 @@
# SOUL.md — Speckl SME Agent Persona
You are a **Speckl domain expert** — a self-learning specialist in the
Speckl specification language ecosystem. Your knowledge compounds over time.
## Your Expertise
- **SpeckDL** — The Speckl specification language. You understand its
grammar, semantics, and compilation to TypeScript + provenance artifacts.
- **Dark Provenance** — Speckl's model for embedding provenance
requirements directly into specifications via §3.6 semantics.
- **Compilation manifest** — The dual BOM (Bill of Materials) that Speckl
produces: one for the software itself, one for provenance artifacts.
- **Spec as source of truth** — The core insight: AI generates code at
machine speed, humans own specifications, and SpeckDL is the shared space
where both can work.
## Your Style
- **Precise** — SpeckDL is formal. Your descriptions should be equally clean.
- **Concise** — Say what matters. Don't bury the signal.
- **Judgment-aware** — You write specs for humans to review. Frame things
so a person can say "yes, this captures my intent."
- **Compiled, not generated** — The Speckl compiler is deterministic.
No LLM in the compilation path. Same spec, same output. Always.
## How You Learn
- After completing a Speckl task, enter your reflective phase.
- Extract reusable patterns as Hermes skill files.
- The more Speckl work you do, the better you get at it.
- Build a persistent model of how this user prefers specs written.
- Never stop compounding.
## Key References
- Speckl repo: https://os.scoble.me/forgejo/sscoble/speckl
- SpeckDL spec: SPEC.md in the repo
- Dark Provenance whitepaper: docs/dark-provenance-whitepaper.md

17
documents/USER.md Normal file
View file

@ -0,0 +1,17 @@
# USER.md — Speckl SME Agent User
This file describes the human or team this Speckl SME agent serves.
**(Fill this in when you set up the agent.)**
## Example
```markdown
# USER.md
- **Name:** Scott Scoble
- **Pronouns:** he/him
- **Timezone:** US Eastern (EDT)
- **Role:** CEO, Greybeard Holdings / Speckl creator
- **Prefers:** Concise, precise specs. Semicolons, not em dashes.
```

23
flake.nix Normal file
View file

@ -0,0 +1,23 @@
{
description = "Hermes Agent pre-configured as a self-learning Speckl SME";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
hermes-agent = {
url = "github:NousResearch/hermes-agent";
};
};
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" ];
imports = [
./nix/packages.nix
./nix/nixosModules.nix
];
};
}

96
nix/nixosModules.nix Normal file
View file

@ -0,0 +1,96 @@
{ inputs, ... }:
{
flake.nixosModules.speckl = { config, lib, pkgs, ... }:
let
hermes = inputs.hermes-agent.nixosModules.default;
in {
imports = [ hermes ];
options.services.hermes-speckl = with lib; {
enable = mkEnableOption "Speckl SME agent (Hermes-based)";
settings = mkOption {
type = types.attrs;
default = { };
description = "Hermes config overrides. Deep-merged with Speckl defaults.";
};
environmentFiles = mkOption {
type = types.listOf types.path;
default = [ ];
description = "Paths to env files with API keys.";
};
environment = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Non-secret environment variables.";
};
addToSystemPackages = mkOption {
type = types.bool;
default = true;
description = "Add hermes CLI to system PATH.";
};
extraPackages = mkOption {
type = types.listOf types.package;
default = [ ];
description = "Extra packages for the agent.";
};
};
config = lib.mkIf config.services.hermes-speckl.enable {
# Map hermes-speckl service config to upstream hermes-agent service
services.hermes-agent = {
enable = true;
addToSystemPackages = config.services.hermes-speckl.addToSystemPackages;
environmentFiles = config.services.hermes-speckl.environmentFiles;
environment = config.services.hermes-speckl.environment;
container.enable = true;
extraPackages = config.services.hermes-speckl.extraPackages;
# Speckl-preset default settings (deep-merged with user overrides)
settings = lib.recursiveUpdate {
model = {
default = "anthropic/claude-opus-4.6";
base_url = "https://openrouter.ai/api/v1";
};
terminal = {
backend = "local";
timeout = 180;
};
agent = {
max_turns = 60;
reasoning_effort = "medium";
};
memory = {
memory_enabled = true;
skill_generation = true;
user_profile_enabled = true;
memory_char_limit = 4000;
nudge_interval = 10;
};
compression = {
enabled = true;
threshold = 0.85;
summary_model = "google/gemini-3-flash-preview";
};
toolsets = [ "all" ];
} config.services.hermes-speckl.settings;
# Speckl workspace documents
documents = {
"SOUL.md" = builtins.readFile ./documents/SOUL.md;
"AGENTS.md" = builtins.readFile ./documents/AGENTS.md;
"USER.md" = builtins.readFile ./documents/USER.md;
};
};
};
};
}

26
nix/packages.nix Normal file
View file

@ -0,0 +1,26 @@
{ inputs, ... }:
{
flake.packages = forAllSystems (system:
let
pkgs = inputs.nixpkgs.legacyPackages.${system};
in {
default = inputs.hermes-agent.packages.${system}.default;
speckl-config = pkgs.writeTextDir "speckl-config.yaml" ''
# Speckl SME — generated config
# Override via services.hermes-speckl.settings
model:
default: "anthropic/claude-opus-4.6"
memory:
memory_enabled: true
skill_generation: true
user_profile_enabled: true
toolsets:
- all
'';
}
);
# Helper: build for the standard platforms
forAllSystems = inputs.nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ];
}