@sigrun/sigrun 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +214 -0
- package/CONTEXT.md +163 -0
- package/LICENSE +21 -0
- package/README.md +691 -2
- package/THIRD_PARTY_NOTICES.md +28 -0
- package/dist/backup/marker.js +80 -0
- package/dist/backup/run-backup.js +339 -0
- package/dist/cli.js +952 -0
- package/dist/commands/expand.js +245 -0
- package/dist/commands/templates.js +272 -0
- package/dist/config.js +1146 -0
- package/dist/extension.d.ts +431 -0
- package/dist/harness/activity.js +42 -0
- package/dist/harness/ambient.js +261 -0
- package/dist/harness/auth.js +130 -0
- package/dist/harness/boot.js +865 -0
- package/dist/harness/builtins.js +191 -0
- package/dist/harness/event-bus.js +1203 -0
- package/dist/harness/health.js +30 -0
- package/dist/harness/identity/index.js +37 -0
- package/dist/harness/identity/invites.js +94 -0
- package/dist/harness/identity/json-store.js +108 -0
- package/dist/harness/identity/setup-code.js +81 -0
- package/dist/harness/identity/tokens.js +101 -0
- package/dist/harness/identity/users.js +93 -0
- package/dist/harness/interactions.js +283 -0
- package/dist/harness/loader.js +1236 -0
- package/dist/harness/memory-default.js +35 -0
- package/dist/harness/naming.js +193 -0
- package/dist/harness/packages.js +1002 -0
- package/dist/harness/providers/auth-bridge.js +60 -0
- package/dist/harness/providers/index.js +277 -0
- package/dist/harness/providers/models-store.js +105 -0
- package/dist/harness/providers/refresh.js +161 -0
- package/dist/harness/providers/scheduler.js +89 -0
- package/dist/harness/registry.js +9 -0
- package/dist/harness/reserved-sections.js +24 -0
- package/dist/harness/seam-host.js +239 -0
- package/dist/harness/sections/context-files.js +78 -0
- package/dist/harness/sections/model-guidance.js +77 -0
- package/dist/harness/settings.js +1053 -0
- package/dist/harness/stores.js +450 -0
- package/dist/harness/tools.js +500 -0
- package/dist/harness/workspace.js +73 -0
- package/dist/index.js +39 -0
- package/dist/jobs/docs.js +257 -0
- package/dist/jobs/fire.js +342 -0
- package/dist/jobs/index.js +228 -0
- package/dist/jobs/observe.js +165 -0
- package/dist/jobs/reconcile.js +245 -0
- package/dist/jobs/schedule.js +77 -0
- package/dist/jobs/spec.js +248 -0
- package/dist/jobs/task.js +190 -0
- package/dist/jobs/transfer.js +53 -0
- package/dist/serve.js +164 -0
- package/dist/server/auth/claim-lock.js +28 -0
- package/dist/server/auth/ip.js +51 -0
- package/dist/server/auth/login-limiter.js +52 -0
- package/dist/server/auth/loopback.js +47 -0
- package/dist/server/auth/pipeline.js +330 -0
- package/dist/server/auth/principal.js +26 -0
- package/dist/server/commands.js +198 -0
- package/dist/server/content-parts.js +142 -0
- package/dist/server/context.js +13 -0
- package/dist/server/conversation-handler.js +61 -0
- package/dist/server/conversation-ops.js +310 -0
- package/dist/server/events/hub.js +39 -0
- package/dist/server/events/types.js +8 -0
- package/dist/server/helpers.js +351 -0
- package/dist/server/host-bridge.js +131 -0
- package/dist/server/index.js +232 -0
- package/dist/server/notifications.js +185 -0
- package/dist/server/ownership.js +67 -0
- package/dist/server/readiness.js +36 -0
- package/dist/server/routes/auth.js +172 -0
- package/dist/server/routes/conversations.js +341 -0
- package/dist/server/routes/events.js +161 -0
- package/dist/server/routes/extension-routes.js +127 -0
- package/dist/server/routes/extensions.js +168 -0
- package/dist/server/routes/files.js +308 -0
- package/dist/server/routes/interactions.js +260 -0
- package/dist/server/routes/jobs.js +271 -0
- package/dist/server/routes/meta.js +146 -0
- package/dist/server/routes/metrics.js +219 -0
- package/dist/server/routes/onboarding.js +268 -0
- package/dist/server/routes/probes.js +53 -0
- package/dist/server/routes/providers.js +198 -0
- package/dist/server/routes/settings.js +48 -0
- package/dist/server/routes/stream.js +131 -0
- package/dist/server/routes/submissions.js +317 -0
- package/dist/server/routes/users.js +169 -0
- package/dist/server/schema-fixture.js +950 -0
- package/dist/server/session-meta.js +247 -0
- package/dist/server/static.js +169 -0
- package/dist/server/views.js +71 -0
- package/dist/skills/index.js +418 -0
- package/node_modules/@sigrun/shared/CHANGELOG.md +16 -0
- package/node_modules/@sigrun/shared/LICENSE +21 -0
- package/node_modules/@sigrun/shared/README.md +10 -0
- package/node_modules/@sigrun/shared/dist/access.d.ts +55 -0
- package/node_modules/@sigrun/shared/dist/access.js +72 -0
- package/node_modules/@sigrun/shared/dist/ambient.d.ts +111 -0
- package/node_modules/@sigrun/shared/dist/ambient.js +23 -0
- package/node_modules/@sigrun/shared/dist/commands.d.ts +75 -0
- package/node_modules/@sigrun/shared/dist/commands.js +25 -0
- package/node_modules/@sigrun/shared/dist/conversations.d.ts +31 -0
- package/node_modules/@sigrun/shared/dist/conversations.js +94 -0
- package/node_modules/@sigrun/shared/dist/interactions.d.ts +91 -0
- package/node_modules/@sigrun/shared/dist/interactions.js +21 -0
- package/node_modules/@sigrun/shared/dist/jobs.d.ts +100 -0
- package/node_modules/@sigrun/shared/dist/jobs.js +19 -0
- package/node_modules/@sigrun/shared/dist/json.d.ts +20 -0
- package/node_modules/@sigrun/shared/dist/json.js +13 -0
- package/node_modules/@sigrun/shared/dist/session-meta.d.ts +103 -0
- package/node_modules/@sigrun/shared/dist/session-meta.js +13 -0
- package/node_modules/@sigrun/shared/dist/settings.d.ts +401 -0
- package/node_modules/@sigrun/shared/dist/settings.js +19 -0
- package/node_modules/@sigrun/shared/dist/themes.d.ts +50 -0
- package/node_modules/@sigrun/shared/dist/themes.js +156 -0
- package/node_modules/@sigrun/shared/dist/turns.d.ts +102 -0
- package/node_modules/@sigrun/shared/dist/turns.js +166 -0
- package/node_modules/@sigrun/shared/dist/view-delta.d.ts +54 -0
- package/node_modules/@sigrun/shared/dist/view-delta.js +135 -0
- package/node_modules/@sigrun/shared/dist/views.d.ts +742 -0
- package/node_modules/@sigrun/shared/dist/views.js +38 -0
- package/node_modules/@sigrun/shared/package.json +83 -0
- package/package.json +89 -5
- package/webui/dist/assets/index-Rl0KhCLa.css +1 -0
- package/webui/dist/assets/index-rOiARZLF.js +50 -0
- package/webui/dist/index.html +37 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.1] - 2026-10-22
|
|
11
|
+
### Fixed
|
|
12
|
+
- `@sigrun/sigrun@0.1.0` shipped a correct tarball but a dev-shape packument
|
|
13
|
+
(the `file:../sigrun-ext-*` specifiers reached the registry's manifest):
|
|
14
|
+
clean installs resolved no built-in extensions and quarantined them at
|
|
15
|
+
boot. The publish-deps restore now runs in `postpublish` only — npm 11
|
|
16
|
+
runs pack → postpack → packument submission, so the old `postpack`
|
|
17
|
+
restore raced the manifest write. Version bumped so the registry gets a
|
|
18
|
+
clean packument; 0.1.0's tarball was byte-correct and remains installable
|
|
19
|
+
by direct tarball URL.
|
|
20
|
+
## [0.1.0] - 2026-10-21
|
|
21
|
+
### Added (server)
|
|
22
|
+
- Conversation list fields: name, last-activity, parent (fork lineage),
|
|
23
|
+
archived and pinned on the list payload — the per-conversation meta
|
|
24
|
+
N+1 is gone; fork trees sort by newest activity anywhere in the tree.
|
|
25
|
+
- Automatic conversation naming: a one-shot naming call driven by the
|
|
26
|
+
`namingModel` setting (a model id, or `false` to disable; defaults to
|
|
27
|
+
the server default model with thinking off). Forks of named
|
|
28
|
+
conversations inherit `"<name> (fork)"`.
|
|
29
|
+
|
|
30
|
+
### Added (tui)
|
|
31
|
+
- Fullscreen alt-screen UI with mouse support: per-keymap themes,
|
|
32
|
+
status bar, and a turn-grouped transcript with foldable turns.
|
|
33
|
+
- Action layer with configurable keymaps (standard / vim / emacs):
|
|
34
|
+
turn-aware search, prompt-jump and picker actions replace the
|
|
35
|
+
alt-screen built-ins; vim mode has real insert / normal / command
|
|
36
|
+
modes with `v` opening the prompt in vim.
|
|
37
|
+
- Key reference overlay (`?` in standard/emacs, `g?` in vim).
|
|
38
|
+
|
|
39
|
+
### Added (webui)
|
|
40
|
+
- Theme system: palette / accent / mode, applied across the rail,
|
|
41
|
+
header and right-panel shell; visual design adapted from hermes-webui
|
|
42
|
+
by nesquena and contributors (credited in THIRD_PARTY_NOTICES).
|
|
43
|
+
- Sidebar: named, grouped, searchable conversation list with pin and
|
|
44
|
+
archive.
|
|
45
|
+
- Transcript: turn-grouped rendering with an activity line per turn
|
|
46
|
+
("Thinking · 2 tools"), markdown everywhere, filterable tables
|
|
47
|
+
(filter bar above > 6 data rows), copy buttons on code blocks, a
|
|
48
|
+
transcript outline, and a scroll fade.
|
|
49
|
+
- Composer model and thinking pickers.
|
|
50
|
+
|
|
51
|
+
- Thinking blocks: `thinking` content blocks render as collapsible
|
|
52
|
+
`<details>` before each assistant message's text — expanded + pulsing
|
|
53
|
+
while the generation streams (`pi.live.generation.message` partials
|
|
54
|
+
render as a provisional entry), collapsed at rest, hidden entirely by
|
|
55
|
+
the new Interface setting.
|
|
56
|
+
- A "working…" indicator (three pulsing dots) driven by `steer.busy`,
|
|
57
|
+
reading "compacting…" while a compaction task is live, plus a persistent
|
|
58
|
+
compaction-failure alert from `pi.live.compactionFailure`.
|
|
59
|
+
- Submit chords: Ctrl+Enter / Cmd+Enter submit; the Interface setting's
|
|
60
|
+
"enter sends the prompt" adds plain-Enter submit (Shift+Enter stays a
|
|
61
|
+
newline).
|
|
62
|
+
- Settings sections: the panel gains a left nav (General / Tools /
|
|
63
|
+
Interface / Advanced). Interface holds the new client-only prefs
|
|
64
|
+
(`enterToSend`, `showThinking`) — localStorage-backed (`sigrun.prefs`),
|
|
65
|
+
applied live, never sent to the server.
|
|
66
|
+
- Workspace drawer: below 1000px the workspace panel opens as a right-side
|
|
67
|
+
overlay drawer (top-bar toggle, backdrop click / in-panel ✕ to close)
|
|
68
|
+
instead of being hidden.
|
|
69
|
+
|
|
70
|
+
### Changed (webui)
|
|
71
|
+
- Tool-call-only assistant messages render nothing — the empty bubble
|
|
72
|
+
above a tool card is gone.
|
|
73
|
+
- The Compact button is removed (compaction is automatic server-side;
|
|
74
|
+
`/compact` remains a slash command). Composer controls sit in one row
|
|
75
|
+
(Attach · usage ring · Send) and the textarea matches their height.
|
|
76
|
+
- The settings gear is larger; the top bar wraps badges instead of
|
|
77
|
+
overflowing horizontally at narrow widths.
|
|
78
|
+
|
|
79
|
+
### Fixed (webui)
|
|
80
|
+
- The Tools section's checkboxes collapsed into a vertical column with the
|
|
81
|
+
explanatory note clipped off the right edge (a `flex-direction` leak from
|
|
82
|
+
the `.settings-field` base), forcing a horizontal scrollbar.
|
|
83
|
+
- `pi.live` doc narrowing gained the `generation`/`compactions`/
|
|
84
|
+
`compactionFailure` shapes the new consumers read.
|
|
85
|
+
- Unified `extensions` list (install-and-load): one settings.json array
|
|
86
|
+
covers npm specifiers, `file:`/path checkouts, and git sources
|
|
87
|
+
(`git:host/path[@ref]` cloned into `<config-dir>/git/` with fetch/reconcile
|
|
88
|
+
+ entry discovery: sigrun manifest > pi-compat manifest > dist/index.js >
|
|
89
|
+
index.ts). `{enabled: false}` = present-but-not-loaded. The separate
|
|
90
|
+
`packages` list is gone; `SIGRUN_EXTENSIONS` accepts the same grammar
|
|
91
|
+
per CSV chunk (JSON-object entries included).
|
|
92
|
+
### Added
|
|
93
|
+
- pi-style extension packages: the settings file's top-level `packages`
|
|
94
|
+
array (file-only — no `SIGRUN_PACKAGES`) declares npm specifiers boot
|
|
95
|
+
installs into `<config-dir>/packages/` (a real npm root: synthetic
|
|
96
|
+
private `package.json` + `node_modules/`, pi's `~/.pi/agent/npm` shape),
|
|
97
|
+
pruning undeclared entries, with a no-subprocess fast path when the dir
|
|
98
|
+
already matches. The loader resolves each `extensions` name against the
|
|
99
|
+
packages dir FIRST (deployment-installed wins), then bare import
|
|
100
|
+
resolution (paths, `file://` URLs, dev checkouts, image-bundled
|
|
101
|
+
packages). Install failure/timeout (120s) fails the boot naming the
|
|
102
|
+
specifier. Deployments declare extensions in `settings.json` and
|
|
103
|
+
restart — no image rebuild. Compose mounts the config dir on the data
|
|
104
|
+
volume (`SIGRUN_CONFIG_DIR=/data/config`); the chart defaults
|
|
105
|
+
`SIGRUN_CONFIG_DIR=/data/config` onto the same PVC as the database.
|
|
106
|
+
- `server.webui` settings section (the webui channel surface):
|
|
107
|
+
`enabled` (default `true`; `false` is a positively API-only deploy —
|
|
108
|
+
nothing mounts even when a bundle is present) and `bundle` (the
|
|
109
|
+
selector — a value matching `^[a-z][a-z0-9_-]*$` is a contributed-bundle
|
|
110
|
+
NAME, a path-shaped value is a directory). `SIGRUN_WEBUI` is the strict
|
|
111
|
+
env gate (`true`/`false`, anything else fails loud);
|
|
112
|
+
`SIGRUN_WEBUI_BUNDLE` remains the env selector form.
|
|
113
|
+
`PATCH {server:{webui:{…}}}` sub-merges per key (a partial update no
|
|
114
|
+
longer drops a previously set `bundle`); a defaulted first boot
|
|
115
|
+
persists no webui keys at all.
|
|
116
|
+
- Extension-contributed webui bundles: a factory result may carry
|
|
117
|
+
`webuiBundles: [{name, dir}]` (contract in `docs/extending.md`) — `dir`
|
|
118
|
+
resolves against the extension entry file's directory (the bundle lives
|
|
119
|
+
in the extension's package, never the server cwd), the server owns the
|
|
120
|
+
`index.html` check at serve time (a missing index is a boot error naming
|
|
121
|
+
the extension), and name collisions are last-registered-wins with a
|
|
122
|
+
warn. Selection by name via `server.webui.bundle`; the selected
|
|
123
|
+
bundle mounts exactly like the built-in one and
|
|
124
|
+
`capabilities.channels` reports its name (`"webui"` for the built-in
|
|
125
|
+
default).
|
|
126
|
+
- `/v1/meta` gains a `collisions` field (`webui` + `providers`):
|
|
127
|
+
boot-merge collision records surfaced for operator visibility — the
|
|
128
|
+
provider collision sink was retained since the provider plan but never
|
|
129
|
+
readable until now.
|
|
130
|
+
|
|
131
|
+
### Deprecated
|
|
132
|
+
- `server.webuiBundle` — the legacy flat key reads as a deprecated alias
|
|
133
|
+
for `server.webui.bundle` for one release (accepted with a deprecation
|
|
134
|
+
warn). Selector precedence: `SIGRUN_WEBUI_BUNDLE` >
|
|
135
|
+
`server.webui.bundle` > legacy `server.webuiBundle` > the built-in
|
|
136
|
+
default. Bootstrap never writes the legacy key; migrate to
|
|
137
|
+
`server.webui.bundle`.
|
|
138
|
+
|
|
139
|
+
### Changed
|
|
140
|
+
- `charts/sigrun` is rewritten as a bjw-s common library (app-template
|
|
141
|
+
5.2.1) wrapper: the hand-written Deployment/Service/PVC/CronJob/
|
|
142
|
+
ServiceMonitor templates are replaced by
|
|
143
|
+
`templates/common.yaml` (loader init + generate) over a 5.2.1-schema
|
|
144
|
+
values.yaml (`controllers`/`service`/`persistence`/`serviceMonitor`).
|
|
145
|
+
The PrometheusRule stays a small hand template (the library has no
|
|
146
|
+
PrometheusRule class), gated independently on
|
|
147
|
+
`monitoring.prometheusRule.enabled`. The backup CronJob and the
|
|
148
|
+
ServiceMonitor are now opt-in defaults (public portable shape); the
|
|
149
|
+
Deployment's Recreate strategy, /healthz + /readyz probes, sigrun-env
|
|
150
|
+
envFrom secret, and the RWO sigrun-data PVC at /data are unchanged
|
|
151
|
+
contracts. test/manifests.test.ts asserts against the new render.
|
|
152
|
+
- **BREAKING** (packaging): `@sigrun/tui` is a spawned package, not an
|
|
153
|
+
in-process import — `sigrun run`/`attach` spawn the `sigrun-tui` bin
|
|
154
|
+
(`tui/dist/launch.js`) as a child process; the agent-dies-with-the-TUI
|
|
155
|
+
lifecycle is preserved by the parent watching the child's exit. The
|
|
156
|
+
tui declares its own runtime deps (`@earendil-works/pi-tui` plus the
|
|
157
|
+
new `@sigrun/shared` leaf package carrying the theme tokens and shared
|
|
158
|
+
primitives) and core lists it as an optional dependency: `serve` needs
|
|
159
|
+
no tui, and a missing tui degrades `run`/`attach` with an actionable
|
|
160
|
+
"install @sigrun/tui" message instead of a module-not-found crash.
|
|
161
|
+
- The CLI is buildable and installable: `npm run build` compiles
|
|
162
|
+
`@sigrun/shared` + `src` → `dist` (sourcemaps off; the `sigrun` bin is
|
|
163
|
+
`dist/cli.js` under plain node — the tsx shebang is gone); `tsx` moves
|
|
164
|
+
to devDependencies (dev `start`/`tui` scripts keep it); `prepublishOnly`
|
|
165
|
+
builds core + webui. Deploy entries run the built form — the Dockerfile
|
|
166
|
+
build stage gains `npm run build` with `CMD ["node", "dist/index.js"]`,
|
|
167
|
+
the chart's container command and backup CronJob are
|
|
168
|
+
`node dist/index.js` / `node /app/dist/backup/run-backup.js`, and
|
|
169
|
+
docker-compose runs `node dist/index.js` (no tsx in any deploy path).
|
|
170
|
+
- The default webui bundle anchors to the package root instead of the
|
|
171
|
+
process cwd — an installed `sigrun serve` finds the bundle it ships
|
|
172
|
+
from any working directory; explicit path selectors keep cwd-relative
|
|
173
|
+
semantics, and an absent default stays the supported API-only deploy.
|
|
174
|
+
|
|
175
|
+
### Removed
|
|
176
|
+
- **BREAKING**: the extension-loader `.ts`-entry fallback. Extension
|
|
177
|
+
sources (`git:` and path checkouts) must ship a built `dist/index.js` —
|
|
178
|
+
a `.ts` entry no longer loads — it resolves only to quarantine at load
|
|
179
|
+
with a clear "build the package and ship its built entry
|
|
180
|
+
(dist/index.js)" error instead of riding the dev tree's tsx loader
|
|
181
|
+
(whose behavior under plain node depends on the host's
|
|
182
|
+
type-stripping flags). npm packages were never affected.
|
|
183
|
+
|
|
184
|
+
### Changed (packaging)
|
|
185
|
+
- Published as `@sigrun/sigrun` (CLI command stays `sigrun`) with
|
|
186
|
+
`@sigrun/shared` and `@sigrun/tui` as workspace-published companions —
|
|
187
|
+
exact intra-family pins (`0.1.0`), `publishConfig` access/provenance,
|
|
188
|
+
`repository.directory` for the workspace packages, and a manifest
|
|
189
|
+
hygiene suite (`test/package-manifest.test.ts`) pinning the published
|
|
190
|
+
shape. `webui` stays a private build input (its bundle ships inside
|
|
191
|
+
core's tarball as `webui/dist`).
|
|
192
|
+
- The npm tarball is the runnable package only: `files` narrows to
|
|
193
|
+
`dist`, `webui/dist`, and the docs files — deploy assets (`scripts/`,
|
|
194
|
+
`docker/`, `charts/`, `Dockerfile`) live in the GitHub repo.
|
|
195
|
+
- The three built-in extensions (`codemode`, MCP, tool search) ship as
|
|
196
|
+
core dependencies under their published names `@sigrun/ext-codemode`,
|
|
197
|
+
`@sigrun/ext-mcp`, `@sigrun/ext-tool-search` — the working tree keeps
|
|
198
|
+
`file:` dev links until the family publishes (Task 8).
|
|
199
|
+
- The extension contract surface is `@sigrun/sigrun/extension`
|
|
200
|
+
(types-only subpath; every import, doc, and the consumer fixture
|
|
201
|
+
re-keyed).
|
|
202
|
+
- The deprecated `createMemory` named-export loader bridge is DELETED
|
|
203
|
+
(release-0.1): packages must export the factory as default —
|
|
204
|
+
`@sigrun/memory-markdown` 0.1.0 does. The named `extension`
|
|
205
|
+
export bridge remains deprecated (loads with one warning).
|
|
206
|
+
|
|
207
|
+
### Added
|
|
208
|
+
- Durable personal assistant on pi-durable 1.2.0: the Harness (durable sessions,
|
|
209
|
+
tasks, compaction, settings store), the §5 server + webui, the skills/search
|
|
210
|
+
tool surface, extension loader (quarantine-on-failure), deploy manifests
|
|
211
|
+
(base + homelab overlay), and the pi-parity feature set (approvals, memory
|
|
212
|
+
surface, settings panel, command surface).
|
|
213
|
+
- pi-durable upgraded 1.0.2 → 1.2.0: ToolExecutionResult `output` rename across
|
|
214
|
+
core, registry-driven settings roster, `modelTools` two-layer filtering.
|
package/CONTEXT.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Context: why sigrun exists
|
|
2
|
+
|
|
3
|
+
> Companion to the sigrun specs in `docs/superpowers/specs/` (the *what*):
|
|
4
|
+
> `2026-10-04-sigrun-core.md` (core, zero external dependencies),
|
|
5
|
+
> `2026-10-04-sigrun-hermes-replacement.md` (parity extensions + cutover),
|
|
6
|
+
> `2026-10-04-sigrun-improvements.md` (post-hermes capabilities). The original
|
|
7
|
+
> `2026-10-02-sigrun.md` is superseded and retained as decision history (the numbered
|
|
8
|
+
> decision record, App B 1–23, lives there; its deployment §6 was carried into the core
|
|
9
|
+
> spec, so the three active specs stand alone).
|
|
10
|
+
> This document is the *why* — what the assistant is for, what it replaces, and
|
|
11
|
+
> the constraints that shaped it. Written 2026-10-02.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. What sigrun replaces, and why
|
|
16
|
+
|
|
17
|
+
The user has run `hermes-agent` (in-cluster, via the `hermes-pantheon`
|
|
18
|
+
chart) plus `hermes-webui` as a personal assistant. The assistant is genuinely
|
|
19
|
+
useful — the memory system especially — but the software has become a bad fit:
|
|
20
|
+
|
|
21
|
+
- **It is heavy.** The local config is ~800 lines. After the 2026-09-25
|
|
22
|
+
gateway-only cleanup, the overwhelming majority of it is dead: bedrock
|
|
23
|
+
discovery, docker sandbox variants, personalities, Mixture-of-Agents presets,
|
|
24
|
+
per-provider fallback plumbing, image-generation providers. The features that
|
|
25
|
+
actually get used are a handful of tools, cron, memory, and the webui.
|
|
26
|
+
- **The webui runs a second agent loop.** hermes-webui imports the hermes code
|
|
27
|
+
and re-implements the agent loop independently of the primary CLI agent. Two
|
|
28
|
+
loops, two state paths, one codebase that has to keep them in sync.
|
|
29
|
+
- **The workspace went away.** When hermes ran locally in the same WSL instance
|
|
30
|
+
as pi and opencode, everything shared a filesystem, and code written by pi was
|
|
31
|
+
immediately visible to hermes. Moving hermes into the cluster bought
|
|
32
|
+
always-on availability and lost that adjacency.
|
|
33
|
+
- **It is not a good coding agent.** Attempts to use it as one produced poor
|
|
34
|
+
results. Coding stays in pi.
|
|
35
|
+
|
|
36
|
+
Sigrun keeps the parts that earn their place (memory, scheduled jobs,
|
|
37
|
+
agentic maintenance tools, web research, the webui as the primary surface)
|
|
38
|
+
and discards the rest by construction.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. What the assistant is actually for
|
|
43
|
+
|
|
44
|
+
Stated by the user, in their words:
|
|
45
|
+
|
|
46
|
+
- **Research.** The most common use. "Go find out about X." Which naturally
|
|
47
|
+
escalates:
|
|
48
|
+
- **Research that turns into work.** If finding out about X reveals a tool to
|
|
49
|
+
build or software to update, the assistant should open a ticket in Forgejo and
|
|
50
|
+
hand the actual work to pi — not attempt the coding itself.
|
|
51
|
+
- **Steering coding work from away from the desk.** Not doing the work, but
|
|
52
|
+
being able to answer a pi session's questions or prompt it to continue while
|
|
53
|
+
on a phone or laptop. Heavy lifting stays in pi inside herdr.
|
|
54
|
+
- **Routine maintenance.** Existing cron jobs performing household and
|
|
55
|
+
self-hosted-service maintenance. The user wants *more* of this and keeps
|
|
56
|
+
not getting to it — calendar access, household context, and similar
|
|
57
|
+
assistant-ish chores.
|
|
58
|
+
- **Ambient awareness.** Ingesting data sources such as Discord logs so the user
|
|
59
|
+
can catch up on what they missed, gauge community impressions of new models,
|
|
60
|
+
and track events. Read-only to start.
|
|
61
|
+
- **Memory.** Honcho is described as "incredibly valuable." Parity with the
|
|
62
|
+
current honcho behavior is a v1 requirement, not an enhancement.
|
|
63
|
+
- **Household multi-user, eventually.** "An agent that can assist my entire
|
|
64
|
+
household has clear value," with guardrails around data sharing. Authelia is
|
|
65
|
+
already the IdP, so this is an SP problem, not an identity problem.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 3. Constraints that shaped the design
|
|
70
|
+
|
|
71
|
+
### 3.1 The workspace problem
|
|
72
|
+
|
|
73
|
+
The single most concrete complaint. A shared workspace between agents was
|
|
74
|
+
valuable and the cluster migration broke it. But running a whole-home assistant
|
|
75
|
+
from a personal workstation is not a good answer either — the workstation sleeps,
|
|
76
|
+
and the assistant should not.
|
|
77
|
+
|
|
78
|
+
Resolution: the assistant's *core* lives in-cluster (always on, durable), and the
|
|
79
|
+
*workspace* is resolved rather than fixed. Day one uses a static workspace
|
|
80
|
+
configuration; the swap to dynamic resolution is a wrapper change, not a
|
|
81
|
+
rewrite. The interaction surfaces (webui now, TUI and
|
|
82
|
+
audio later) attach to the in-cluster core from anywhere over the tailnet.
|
|
83
|
+
|
|
84
|
+
Precedent the user liked and lost: `opencode serve` on the workstation with
|
|
85
|
+
`opencode attach` from any of three machines, working over the tailnet. That
|
|
86
|
+
serve/attach model is exactly what a durable harness gives back — one long-lived
|
|
87
|
+
process owning state, thin clients attaching.
|
|
88
|
+
|
|
89
|
+
### 3.2 pi-durable is the substrate
|
|
90
|
+
|
|
91
|
+
Chosen because it is the only option that makes the "second agent loop" problem
|
|
92
|
+
structurally impossible: the loop lives in the harness, and every surface
|
|
93
|
+
(webui, TUI, cron trigger, future channels) is a client submitting to and
|
|
94
|
+
watching conversations. It also brings crash survival and idempotent
|
|
95
|
+
submissions (requestId dedup — exactly-once-across-crash semantics are
|
|
96
|
+
pending M1 verification), which the current stack lacks.
|
|
97
|
+
|
|
98
|
+
Known constraints accepted at choice time:
|
|
99
|
+
|
|
100
|
+
- Experimental; the API changes between releases (`1.0.2` at spec time;
|
|
101
|
+
pinned exactly, with a captured-schema drift fixture and an upgrade drill
|
|
102
|
+
in the core spec).
|
|
103
|
+
- One process owns a storage file at a time; no cross-process locking. Matches
|
|
104
|
+
the single-harness design anyway.
|
|
105
|
+
|
|
106
|
+
Resolved since the choice (2026-10-04 probes against the pinned package):
|
|
107
|
+
image input **works** (base64 inline in submissions — verified live), and the
|
|
108
|
+
async-approval mechanism works across crash+restart (`beforeTool` + durable
|
|
109
|
+
memo — verified live). These were open questions at choice time; they are now
|
|
110
|
+
verified facts recorded in the core spec's Appendix C.
|
|
111
|
+
|
|
112
|
+
### 3.3 Keep pi's philosophy
|
|
113
|
+
|
|
114
|
+
The user's stated preference: **minimal core, well-defined interfaces for
|
|
115
|
+
extensibility, and an ecosystem.** Their pi install is the proof it works — 19
|
|
116
|
+
packages, each doing one thing, composed into a workflow.
|
|
117
|
+
|
|
118
|
+
So sigrun is: a small harness, a webui, and a set of extensions that are
|
|
119
|
+
individually replaceable. Not a platform.
|
|
120
|
+
|
|
121
|
+
### 3.4 The webui is the primary surface
|
|
122
|
+
|
|
123
|
+
Called out twice in the design conversation. The plan is to take hermes-webui's
|
|
124
|
+
UX shamelessly (three-panel layout, composer footer, tool cards, context ring)
|
|
125
|
+
while replacing everything beneath it with thin client calls to the harness API
|
|
126
|
+
— which is why the stack decision in the spec is *port the frontend, gated on a
|
|
127
|
+
60% reuse measurement*, with a rebuild as the documented fallback.
|
|
128
|
+
|
|
129
|
+
### 3.5 Cross-agent tools belong in the fabric, not the agent
|
|
130
|
+
|
|
131
|
+
Hard-won: the assistant needs a work ledger that spans repositories and
|
|
132
|
+
outlives any particular agent. If the kanban is a hermes plugin, moving to a
|
|
133
|
+
different assistant means re-doing the integration. So cards live in the
|
|
134
|
+
fabric's card system (skuld), and sigrun is just a client — as pi will be, as
|
|
135
|
+
anything else will be.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 4. What sigrun deliberately does not do
|
|
140
|
+
|
|
141
|
+
- **Coding.** pi + herdr own that. Sigrun creates the ticket and the card.
|
|
142
|
+
- **Provider management.** Bifrost already routes models with virtual keys,
|
|
143
|
+
budgets, and failover chains. Sigrun points at one VK.
|
|
144
|
+
- **Multi-user UI in v1.** The `owner` field exists; the auth flow does not.
|
|
145
|
+
- **Write-side Discord, voice, generalized object memory.** Deferred, each with
|
|
146
|
+
a documented seam so it can be added without redesign.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 5. Names
|
|
151
|
+
|
|
152
|
+
**sigrun** — a Norse valkyrie; a messenger/attendant figure. Chosen over:
|
|
153
|
+
|
|
154
|
+
- **iris** — reads as the lesser-known female counterpart to hermes; the user
|
|
155
|
+
disliked the implicit gender-flip construction.
|
|
156
|
+
- **argus** — the watcher; also the guy hermes slew, which is an odd name for
|
|
157
|
+
hermes's replacement.
|
|
158
|
+
- Various scribe/messenger deities (thoth, seshat, ogma, muninn) — all already
|
|
159
|
+
taken in the agent/AI space, several by direct competitors.
|
|
160
|
+
- Norse fits: the bifrost gateway already lives in that mythology.
|
|
161
|
+
|
|
162
|
+
**skuld** — held in reserve for the work-item side of the fabric ("that which
|
|
163
|
+
shall become").
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael MacLeod
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|