@cognisphere-sh/cognisphere-harness 0.0.0-stage → 0.13.0

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.
Files changed (134) hide show
  1. package/CHANGELOG.md +2025 -0
  2. package/LICENSE +21 -0
  3. package/bin/cognisphere.mjs +7 -0
  4. package/dist-web/assets/file-editor-CqGYKmT3.js +32 -0
  5. package/dist-web/assets/index-BDa9M_Wt.css +2 -0
  6. package/dist-web/assets/index-CDE-jsH8.js +336 -0
  7. package/dist-web/assets/markdown-sumxz7Eq.js +29 -0
  8. package/dist-web/assets/radix-DHW5y7jr.js +49 -0
  9. package/dist-web/assets/react-BIlrhC09.js +59 -0
  10. package/dist-web/index.html +28 -0
  11. package/home-template/CLAUDE.md +96 -0
  12. package/home-template/app/README.md +80 -0
  13. package/home-template/app/artifacts-routes/README.md +81 -0
  14. package/home-template/app/artifacts-routes/lib/artifacts.ts +87 -0
  15. package/home-template/app/artifacts-routes/private/artifacts/[slug]/ShareToggle.tsx +110 -0
  16. package/home-template/app/artifacts-routes/private/artifacts/[slug]/page.tsx +45 -0
  17. package/home-template/app/artifacts-routes/private/artifacts/[slug]/raw/route.ts +19 -0
  18. package/home-template/app/artifacts-routes/private/artifacts/[slug]/share/route.ts +33 -0
  19. package/home-template/app/artifacts-routes/public/artifacts/[slug]/route.ts +18 -0
  20. package/home-template/app/auth-routes/README.md +69 -0
  21. package/home-template/app/auth-routes/api/auth/login/route.ts +8 -0
  22. package/home-template/app/auth-routes/api/auth/logout/route.ts +5 -0
  23. package/home-template/app/auth-routes/api/auth/me/route.ts +5 -0
  24. package/home-template/app/auth-routes/lib/auth.ts +62 -0
  25. package/home-template/app/auth-routes/lib/harness.ts +16 -0
  26. package/home-template/app/auth-routes/login/page.tsx +28 -0
  27. package/home-template/config.example +50 -0
  28. package/home-template/docs/app/README.md +11 -0
  29. package/home-template/docs/base-harness/README.md +205 -0
  30. package/home-template/docs/base-harness/skills.md +97 -0
  31. package/home-template/docs/harness/README.md +21 -0
  32. package/home-template/scripts/app/README.md +33 -0
  33. package/home-template/scripts/aws/backup.sh +64 -0
  34. package/home-template/scripts/aws/config.example +18 -0
  35. package/home-template/scripts/aws/setup.sh +147 -0
  36. package/home-template/scripts/build.sh +21 -0
  37. package/home-template/scripts/contabo/config.example +24 -0
  38. package/home-template/scripts/contabo/setup.sh +141 -0
  39. package/home-template/scripts/lib/remote-bootstrap.sh +76 -0
  40. package/home-template/scripts/server.sh +189 -0
  41. package/home-template/scripts/setup-server.sh +230 -0
  42. package/package.json +53 -3
  43. package/skills/cognisphere-upgrade/CHANGELOG.md +37 -0
  44. package/skills/cognisphere-upgrade/SKILL.md +217 -0
  45. package/skills/create-plugin/CHANGELOG.md +30 -0
  46. package/skills/create-plugin/SKILL.md +214 -0
  47. package/skills/create-plugin/template/index.ts +47 -0
  48. package/skills/create-plugin/template/seed/scripts/hello/hello-cli +2 -0
  49. package/skills/create-plugin/template/seed/system_prompts/plugin-hello.md +4 -0
  50. package/skills/create-skill/CHANGELOG.md +26 -0
  51. package/skills/create-skill/SKILL.md +105 -0
  52. package/src/agents/base-agent/bootstrap/bootstrap.sh +136 -0
  53. package/src/agents/base-agent/bootstrap/requirements.txt +17 -0
  54. package/src/agents/base-agent/extensions/bash-guard.ts +36 -0
  55. package/src/agents/base-agent/extensions/context-meta.ts +187 -0
  56. package/src/agents/base-agent/extensions/skill-update-notice.ts +147 -0
  57. package/src/agents/base-agent/knowledge/index.md +10 -0
  58. package/src/agents/base-agent/knowledge/memory.md +24 -0
  59. package/src/agents/base-agent/scripts/agent/agent-browser +62 -0
  60. package/src/agents/base-agent/scripts/agent/ddgs +63 -0
  61. package/src/agents/base-agent/scripts/agent/markitdown +62 -0
  62. package/src/agents/base-agent/scripts/agent/session-reader +442 -0
  63. package/src/agents/base-agent/system_prompts/0-base_prompt.md +412 -0
  64. package/src/agents/base-agent/system_prompts/1-agent.md +17 -0
  65. package/src/agents/base-agent/workspace/index.md +13 -0
  66. package/src/agents/nova/system_prompts/1-agent.md +44 -0
  67. package/src/api/admin.ts +59 -0
  68. package/src/api/agents.ts +915 -0
  69. package/src/api/auth.ts +340 -0
  70. package/src/api/credentials.ts +27 -0
  71. package/src/api/files.ts +234 -0
  72. package/src/api/gws-oauth.ts +381 -0
  73. package/src/api/harness.ts +62 -0
  74. package/src/api/models.ts +282 -0
  75. package/src/api/secrets.ts +211 -0
  76. package/src/api/webhook.ts +66 -0
  77. package/src/cli/agent.ts +96 -0
  78. package/src/cli/index.ts +66 -0
  79. package/src/cli/init.ts +194 -0
  80. package/src/cli/plugin.ts +49 -0
  81. package/src/cli/run.ts +156 -0
  82. package/src/cli/upgrade.ts +134 -0
  83. package/src/cli/util.ts +176 -0
  84. package/src/core/agent-manager.ts +1092 -0
  85. package/src/core/config.ts +108 -0
  86. package/src/core/logger.ts +16 -0
  87. package/src/core/main.ts +233 -0
  88. package/src/core/model-access.ts +55 -0
  89. package/src/core/models-catalog.ts +534 -0
  90. package/src/core/models-store.ts +96 -0
  91. package/src/core/oauth-logins.ts +307 -0
  92. package/src/core/pi-delivery-receipts.ts +69 -0
  93. package/src/core/pi-models-sync.ts +118 -0
  94. package/src/core/plugin-registry.ts +87 -0
  95. package/src/core/queue.ts +670 -0
  96. package/src/core/rpc.ts +380 -0
  97. package/src/core/runner.ts +964 -0
  98. package/src/core/secrets.ts +153 -0
  99. package/src/core/types.ts +257 -0
  100. package/src/plugins/admin/index.ts +49 -0
  101. package/src/plugins/admin/seed/system_prompts/plugin-admin.md +7 -0
  102. package/src/plugins/agent-messaging/index.ts +148 -0
  103. package/src/plugins/agent-messaging/seed/scripts/agent-msg/send +94 -0
  104. package/src/plugins/agent-messaging/seed/system_prompts/plugin-agent-messaging.md +31 -0
  105. package/src/plugins/artifacts/index.ts +271 -0
  106. package/src/plugins/artifacts/seed/scripts/artifacts/artifact +158 -0
  107. package/src/plugins/artifacts/seed/skills/artifacts/publish-artifact/CHANGELOG.md +26 -0
  108. package/src/plugins/artifacts/seed/skills/artifacts/publish-artifact/SKILL.md +145 -0
  109. package/src/plugins/artifacts/seed/skills/artifacts/publish-artifact/artifacts/template.html +59 -0
  110. package/src/plugins/artifacts/seed/system_prompts/plugin-artifacts.md +23 -0
  111. package/src/plugins/gws/index.ts +753 -0
  112. package/src/plugins/gws/seed/scripts/gws/email +386 -0
  113. package/src/plugins/gws/seed/scripts/gws/format-email-lib.d.mts +52 -0
  114. package/src/plugins/gws/seed/scripts/gws/format-email-lib.mjs +146 -0
  115. package/src/plugins/gws/seed/scripts/gws/routes +117 -0
  116. package/src/plugins/gws/seed/scripts/gws/settings +98 -0
  117. package/src/plugins/gws/seed/skills/gws/read-email/CHANGELOG.md +20 -0
  118. package/src/plugins/gws/seed/skills/gws/read-email/SKILL.md +86 -0
  119. package/src/plugins/gws/seed/skills/gws/route-email/CHANGELOG.md +14 -0
  120. package/src/plugins/gws/seed/skills/gws/route-email/SKILL.md +84 -0
  121. package/src/plugins/gws/seed/skills/gws/search-email/CHANGELOG.md +15 -0
  122. package/src/plugins/gws/seed/skills/gws/search-email/SKILL.md +100 -0
  123. package/src/plugins/gws/seed/system_prompts/plugin-gws.md +50 -0
  124. package/src/plugins/scheduler/index.ts +149 -0
  125. package/src/plugins/scheduler/seed/scripts/scheduler/cron-fires +248 -0
  126. package/src/plugins/scheduler/seed/scripts/scheduler/scheduler-cli +157 -0
  127. package/src/plugins/scheduler/seed/system_prompts/plugin-scheduler.md +41 -0
  128. package/src/plugins/telegram/index.ts +422 -0
  129. package/src/plugins/telegram/seed/scripts/telegram/routes +95 -0
  130. package/src/plugins/telegram/seed/scripts/telegram/telegram-cli +278 -0
  131. package/src/plugins/telegram/seed/skills/telegram/route-chats/CHANGELOG.md +7 -0
  132. package/src/plugins/telegram/seed/skills/telegram/route-chats/SKILL.md +63 -0
  133. package/src/plugins/telegram/seed/system_prompts/plugin-telegram.md +48 -0
  134. package/README.md +0 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,2025 @@
1
+ # Changelog
2
+
3
+ All notable changes to CogniSphere are recorded here, one section per version.
4
+
5
+ This file is the single source the **upgrade skill** reads to migrate a harness
6
+ from its current version to a target version. Each release that requires changes
7
+ to a harness's on-disk artifacts MUST include a `### Breaking changes` block
8
+ whose entries follow the form:
9
+
10
+ ```
11
+ - <what changed> [affects: <path glob in the harness dir>]
12
+ ```
13
+
14
+ The skill collects every section in `(current, target]`, proposes a diff against
15
+ the harness directory, and applies it after user approval. See
16
+ [CLI upgrades](docs/low-level/cli.md#upgrades).
17
+
18
+ The format is based on [Keep a Changelog](https://keepachangelog.com/) and this
19
+ project adheres to [Semantic Versioning](https://semver.org/).
20
+
21
+ ## [0.13.0]
22
+
23
+ ### Breaking changes
24
+
25
+ - **Published to npmjs.org; no install token.** `@cognisphere-sh/*` packages
26
+ now come from the public npm registry instead of GitHub Packages. Delete the
27
+ `@cognisphere-sh:registry=https://npm.pkg.github.com` line from the home's
28
+ `.npmrc` (delete the file if nothing else is in it), or installs keep asking
29
+ GitHub Packages, which has no 0.13.0. `COGNISPHERE_NPM_TOKEN` and the
30
+ `npm.pkg.github.com/:_authToken` line in `~/.npmrc` are no longer used and
31
+ can be removed. [affects: .npmrc]
32
+
33
+ - **Each harness has its own Pi config folder.** The server sets
34
+ `PI_CODING_AGENT_DIR` to `harness/.secrets/pi/`, so Pi's `auth.json`,
35
+ `models.json` and `settings.json` no longer live in the run user's
36
+ `~/.pi/agent`. Subscription sign-ins (Claude Pro/Max, Codex, ChatGPT) must
37
+ be connected again once from the Models page; they are not copied, because
38
+ two copies of a rotating refresh token sign each other out. Hand-written
39
+ settings in `~/.pi/agent` no longer apply to the harness. Pi also starts
40
+ with `--no-approve`, so an agent folder's `.pi/` files are never loaded.
41
+ [affects: .secrets/pi/]
42
+
43
+ ### Changed
44
+
45
+ - Deploy scripts no longer need a GitHub token: `setup-server.sh` and
46
+ `build.sh` drop the `read:packages` checks and the `~/.npmrc` token line,
47
+ `remote-bootstrap.sh` logs `gh` in only to clone the repo, the systemd units
48
+ drop `COGNISPHERE_NPM_TOKEN`, and `config.example` drops the key
49
+ (refreshed wholesale on upgrade).
50
+ - `init` no longer writes a `.npmrc` into new homes.
51
+ - **Pi upgraded to 0.99.2** (`@earendil-works/pi-ai` and
52
+ `@earendil-works/pi-coding-agent`, pinned exactly). The runner now spawns
53
+ the `pi` bundled with the harness package instead of a global `pi` on
54
+ `PATH`, so the binary always matches the pinned version. Requires Node
55
+ `>=22.19.0` (as Pi already did).
56
+ - `bootstrap.sh` no longer installs a global `pi` or reads `PI_VERSION`.
57
+ Existing agents' copies still do; that step is now unused and can be
58
+ dropped when reseeding. [affects: agents/*/bootstrap/bootstrap.sh]
59
+ - A batch now ends when Pi reports `agent_settled` instead of `agent_end`, so
60
+ Pi's own retries (up to 3, backoff capped at 60 s), context-overflow
61
+ recovery and late follow-ups run inside the same batch. Queue retries
62
+ still apply after that.
63
+ - Delivery receipts are saved in the session file as `cognisphere.delivery`
64
+ custom entries (outside the model's context) and reported over RPC as
65
+ `entry_appended`. Inputs an extension `handled` are marked done.
66
+ - `context-meta` extension: the per-call `Model:` / `ContextUsage:` lines now
67
+ reach the model. They were dropped because the last message before each
68
+ call is the extension's own checkpoint, which the hook skipped. Reseed the
69
+ base extension. [affects: agents/*/extensions/context-meta.ts]
70
+ - Models page: Sign in with ChatGPT on the OpenAI provider; OpenAI Codex is
71
+ now labelled "(legacy)"; curated model lists refreshed to models that exist
72
+ in Pi 0.99.2 (Claude Opus/Sonnet 5.5, GPT-6.x, Gemini 3.x, Grok 4.7, …).
73
+ - `home-template/docs/base-harness/README.md`: bootstrap no longer pins `pi`;
74
+ new sign-in providers (refreshed wholesale on upgrade).
75
+
76
+ ## [0.12.0]
77
+
78
+ ### Breaking changes
79
+
80
+ - **App→harness auth is now a bearer secret, not the operator login.**
81
+ `scripts/server.sh secrets` no longer writes `HARNESS_USER`/`HARNESS_PASS`
82
+ into `app/.env.local`; it writes the same pair as `APP_USER`/`APP_PASS`
83
+ (the app's *own* default sign-in), an `APP_SESSION_SECRET` for the app's
84
+ own cookie (generated once, reused from the previous `.env.local`), and
85
+ mints `harness/.secrets/app-secret` (hex, 0600, reused across restarts —
86
+ the harness also generates it on first boot if absent) written as
87
+ `HARNESS_APP_SECRET`. The app and the harness console mint independent
88
+ session tokens. New reference tree `app/auth-routes/` (refreshed on
89
+ upgrade like `artifacts-routes/`): config-credential login + `app_sid`
90
+ cookie, `lib/harness.ts` bearer client, and `getUser()` as the single
91
+ seam to swap in Clerk/Supabase/NextAuth. `/api/*`, `/admin/*` and
92
+ `GET /api/auth/me` accept `Authorization: Bearer <secret>` alongside the
93
+ `pi_sid` cookie; `X-App-User: <id>` (trusted only with a valid bearer)
94
+ sets the harness-side `user`, else `"app"`. Apps that logged in with
95
+ `HARNESS_USER`/`HARNESS_PASS` or forwarded the browser's `pi_sid`
96
+ cookie to the harness should switch to the bearer + own their user auth;
97
+ webhook plugins that verified a cookie via `/api/auth/me` verify the
98
+ bearer the same way by forwarding `authorization`/`x-app-user` instead.
99
+ Recipe in `app/auth-routes/README.md`.
100
+ [affects: scripts/server.sh, config.example, app/README.md, app/auth-routes/**, docs/base-harness/README.md, .claude/skills/cognisphere-upgrade/SKILL.md]
101
+
102
+ ### Changed
103
+
104
+ - `docs/low-level/api.md` §1/§3, `docs/low-level/agents.md#persistent-layout` and
105
+ `docs/low-level/cli.md` document the app bearer,
106
+ `.secrets/app-secret`, and the new `app/.env.local` keys. The upgrade
107
+ skill now refreshes `app/auth-routes/` and drift-checks the home's copies.
108
+
109
+ ## [0.11.1]
110
+
111
+ ### Breaking changes
112
+
113
+ - **`bootstrap.sh` pins the global `pi`.** It previously installed
114
+ `@earendil-works/pi-coding-agent` unpinned and only when `pi` was
115
+ missing, so deployed hosts ran whatever npm resolved at first boot.
116
+ It now compares `pi --version` to `PI_VERSION` (0.84.4) and installs
117
+ that exact version on mismatch, every agent start. Reseed from the
118
+ base agent; no operator action beyond that.
119
+ [affects: agents/*/bootstrap/bootstrap.sh]
120
+
121
+ ### Changed
122
+
123
+ - `home-template/docs/base-harness/README.md`: documents the pinned-`pi`
124
+ behaviour of `bootstrap.sh` (refreshed wholesale on upgrade).
125
+ - **pi upgraded to 0.84.4** (`@earendil-works/pi-ai` +
126
+ `@earendil-works/pi-coding-agent`, from 0.84.1). No harness code
127
+ changes were required: the `pi --mode rpc` flag set, the RPC events the
128
+ harness consumes, the session JSONL format (`CURRENT_SESSION_VERSION`
129
+ still 3), pi-ai's `KnownProvider` union (mirrored in
130
+ `core/models-catalog.ts`, verified identical) and the `ExtensionAPI` /
131
+ `ModelRuntime` / `readStoredCredential` / `getAgentDir` surfaces are all
132
+ unchanged. Verified `pi --mode rpc` on the bundled 0.84.3+ runtime still
133
+ loads the base agent's `.ts` extensions via `-e` (jiti is now
134
+ lazy-loaded). Relevant upstream behaviour changes, all favourable:
135
+ 0.84.2/0.84.4 fixed `pi.sendMessage(..., { triggerTurn: false })`
136
+ placement so `context-meta`'s mid-run checkpoints and
137
+ `skill-update-notice`'s notices land after the turn's tool results
138
+ instead of between a tool call and its result; 0.84.4 also runs
139
+ threshold auto-compaction between tool execution and the next LLM call
140
+ (so `compaction_start`/`compaction_end` can now arrive mid-run, not only
141
+ in prompt preflight — handled by the RPC client change below); 0.84.3
142
+ fixed threshold compaction being skipped when a provider omits usage.
143
+
144
+ ### Fixed
145
+
146
+ - **RPC prompt ack no longer times out during auto-compaction.** pi runs
147
+ threshold compaction in the prompt's preflight, before acking the prompt
148
+ frame, and summarizing a large session can take minutes — the harness's
149
+ 60 s ack timeout then failed the batch repeatedly. `PiRpcClient` now
150
+ suspends pending frame timeouts on `compaction_start` and re-arms them on
151
+ `compaction_end`, and logs both at info with `reason` and
152
+ `tokensBefore` / `estimatedTokensAfter` (`docs/low-level/core.md#execution-and-example`).
153
+
154
+ ## [0.11.0]
155
+
156
+ ### Changed
157
+
158
+ - **gws sign-in moved to the agent's Settings tab.** Per-agent Google
159
+ sign-in/sign-out and the scope picker now live on the gws plugin card
160
+ in each agent's Settings tab (`GwsSignInBlock`); the console's
161
+ app-level Settings page keeps only the shared OAuth client id/secret.
162
+ The OAuth callback redirects back to `/agents/<agentId>/settings`.
163
+ - **Frontend apps can host the sign-in button.** The OAuth callback
164
+ (`GET /api/gws/oauth/callback`) is now mounted outside the auth wall —
165
+ the single-use `state` nonce issued by the authenticated start route is
166
+ the auth — and `POST /api/gws/oauth/:agentId/start` accepts an optional
167
+ `returnTo` for where the browser lands afterwards. Recipe (Next.js
168
+ route handler using `HARNESS_USER`/`HARNESS_PASS` + the `/api/*`
169
+ proxy) added to `home-template/app/README.md`; register the app
170
+ origin's `/api/gws/oauth/callback` as an extra redirect URI on the
171
+ Google client.
172
+ - **Gmail scope rationalized.** `gmail.modify` is always requested — it
173
+ is Google's read/write Gmail tier (read, drafts, send, labels,
174
+ mark-read; everything except permanent deletion) and the poll loop's
175
+ mark-read needs it; the narrower Gmail scopes (`readonly`, `compose`,
176
+ `send`, `labels`) are strict subsets of it, so no granular Gmail
177
+ choice is offered. Optional per-service scopes (Calendar, Drive, …)
178
+ unchanged, still stored in the gws config key `oauthScopes`.
179
+ - `home-template/app/README.md` and `docs/base-harness/README.md`
180
+ updated accordingly (both refreshed wholesale by the upgrade skill).
181
+
182
+ ### Removed
183
+
184
+ - **Legacy gws authentication.** The manual `gws auth login` +
185
+ `gws auth export` path is no longer supported or surfaced: the
186
+ `managed` field is gone from `GET /api/gws/oauth` (`signedIn` now
187
+ means "signed in via the web flow"), the "operator-managed
188
+ credentials file" labeling is gone from the console, and the plugin's
189
+ not-signed-in error points only at the web console. A hand-set
190
+ `GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` secret still functions at the
191
+ plugin level but shows as not signed in.
192
+
193
+ ## [0.10.2]
194
+
195
+ ### Breaking changes
196
+
197
+ - Base prompt: main (non-task) threads are now coordinators, not workers —
198
+ they delegate skill-driven procedures, file reads, and sizable work to
199
+ task threads instead of doing it (or reading `SKILL.md`s) themselves;
200
+ the **Task threads** section carries the rule. Refreshed wholesale on
201
+ upgrade [affects: agents/*/system_prompts/0-base_prompt.md]
202
+ - Nova's persona prompt: the "delegate large code reads" working-style
203
+ bullet now defers to the base prompt's coordinator-not-worker rule
204
+ (code reads, searches, and implementation go to task threads). This
205
+ file is deployment-owned — apply the same edit to existing novas [affects: agents/nova/system_prompts/1-agent.md]
206
+
207
+ ## [0.10.1]
208
+
209
+ ### Breaking changes
210
+
211
+ - Skill description spec tightened (`create-skill` v1.3.0): "what's
212
+ included" is a brief sketch of the main procedures, not an exhaustive
213
+ contents list; partial applicability moves under "use when"; the whole
214
+ description stays under 1000 characters. During upgrade, audit every
215
+ skill and rephrase any description that doesn't conform, with a
216
+ patch bump and changelog entry per rephrased skill [affects: agents/*/skills/*/*/SKILL.md]
217
+
218
+ ### Changed
219
+
220
+ - `docs/base-harness/skills.md` and the `create-skill` skill restate the
221
+ new description spec (both refreshed wholesale by the upgrade skill).
222
+
223
+ ## [0.10.0]
224
+
225
+ ### Added
226
+
227
+ - **Web-based Google sign-in/sign-out for gws agents.** New Google
228
+ Workspace card on the console's Settings page and `/api/gws/oauth/*`
229
+ routes (`api/gws-oauth.ts`): the operator saves a "Web application"
230
+ OAuth client from their own GCP project once per harness
231
+ (`.secrets/gws/oauth-client.json`, redirect URI
232
+ `<console origin>/api/gws/oauth/callback`), then signs each
233
+ gws-enabled agent in with a browser consent flow. The callback writes
234
+ the standard `authorized_user` JSON (the shape
235
+ `gws auth export --unmasked` produces) to
236
+ `.secrets/gws/<agentId>/credentials.json`, points the agent's
237
+ `gws.GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE` secret at it, and
238
+ soft-reloads the agent — replacing the manual `gws auth login` +
239
+ `gws auth export` dance. Sign-out revokes the refresh token, deletes
240
+ the managed files, clears the secret, and reloads. Hand-set
241
+ credentials paths keep working and are labeled "operator-managed" in
242
+ the card.
243
+ - **Per-agent OAuth scope selection.** New optional gws plugin config
244
+ key `oauthScopes` (comma-separated scope URLs; read by the sign-in
245
+ flow, ignored by the plugin at runtime). The Settings card edits it
246
+ per agent as checkboxes grouped by service (Calendar, Drive, Docs,
247
+ Sheets, Slides, Contacts, Tasks — full and read-only variants);
248
+ `gmail.modify` + `openid email` are always requested. Granted scopes
249
+ are recorded at sign-in and shown per agent; changing the config
250
+ requires signing in again to take effect.
251
+
252
+ ## [0.9.2]
253
+
254
+ ### Fixed
255
+
256
+ - **Batch teardown now reaps the pi child's entire process tree.** Pi is
257
+ spawned in its own process group (`detached: true`) and, once it exits,
258
+ the group is SIGKILL-swept — so headless browsers, dev servers, and
259
+ anything else the agent's bash tool left running die with the batch
260
+ instead of accumulating on the server. The 5s no-exit escalation also
261
+ kills the group, not just pi.
262
+ - **/tmp no longer fills up.** A janitor sweeps known agent debris from the
263
+ OS temp dir at boot and every 6h (age > 24h): pi's `pi-bash-*.log`
264
+ output-spill files (pi writes them for any oversized command output and
265
+ never deletes them) and browser profile dirs
266
+ (`.org.chromium.*`, `puppeteer_dev_chrome_profile-*`, `playwright*`).
267
+
268
+ ### Changed
269
+
270
+ - **Agent-spawned processes are now strictly batch-scoped.** A background
271
+ process started during one turn no longer survives to the next — the
272
+ group sweep at batch end kills it. No shipped plugin or seed relied on
273
+ cross-batch daemons; if a future workload needs one, run it outside the
274
+ agent (e.g. a plugin) or ask for a skip-sweep flag.
275
+
276
+ ## [0.9.1]
277
+
278
+ ### Fixed
279
+
280
+ - **Memory leaks in the harness execution path.** Three long-running-process
281
+ leaks closed:
282
+ - The per-file session-cost cache (`api/agents.ts`) never evicted — entries
283
+ for deleted threads lived for the life of the process. A failed stat now
284
+ evicts, and past 4096 entries a sweep drops entries whose file is gone.
285
+ - The shared Ajv singleton pinned a compiled validator per agent restart
286
+ (its cache is keyed by schema object identity and `agent.json` is
287
+ re-parsed on every start). Validation now uses a throwaway Ajv per call.
288
+ - A wedged `pi` child that never acked its prompt frame held its worker
289
+ slot, batch state, and OS process forever. `sendPrompt` now times out
290
+ after 60 s; the batch fails and the child is torn down.
291
+ - **Async EPIPE on the pi child's stdin no longer crashes the server.** The
292
+ stdin stream had no `error` listener, so a child dying mid-write raised an
293
+ unhandled `'error'` event; it now logs at debug.
294
+
295
+ ## [0.9.0]
296
+
297
+ ### Added
298
+
299
+ - **The agent owns her gws notification settings.** New agent-writable overlay
300
+ `plugins/gws/state/settings.json`, managed by the seeded
301
+ `scripts/gws/settings` CLI (`show|set|reset`) and re-read by the plugin on
302
+ every poll tick — the same live-reload pattern as `routes.json`, so a change
303
+ applies within one poll. Per-key precedence: `settings.json` →
304
+ operator `config.json` → defaults. Overridable keys: `pollIntervalSec`,
305
+ `gmailQuery`, `allowedSenders`, `requireAgentInTo` (`firstOfThreadOnly`
306
+ stays operator-only).
307
+ - **Passive mailbox.** `pollIntervalSec: -1` disables polling entirely: no
308
+ notifications, nothing marked read — the agent reads mail only when she
309
+ chooses to search. While passive the loop still re-reads settings every
310
+ 60s, so setting a real interval again resumes within a minute (pending
311
+ unread arrives on the next poll).
312
+ - **Settings announced on start.** Each plugin start posts one `gws_settings`
313
+ message on the plugin's `main` channel — mailbox address, effective
314
+ settings, routing-rule count, and how to change them — so the agent can
315
+ re-assert her preferences after every harness restart.
316
+
317
+ ### Changed
318
+
319
+ - **gws defaults: notify on all unread inbox, poll every 15 minutes.**
320
+ `pollIntervalSec` 60 → 900 and `requireAgentInTo` true → false — by default
321
+ the latest message of *every* unread inbox thread now wakes the agent,
322
+ routed to its per-thread id as before; Cc/Bcc-only mail is skipped only
323
+ when `requireAgentInTo` is switched back on. Operators who want the old
324
+ behavior set both keys explicitly in `plugins/gws/config.json`.
325
+
326
+ ### Breaking changes
327
+
328
+ - New seeded `scripts/gws/settings` — the settings overlay's CLI. Plugin seeds
329
+ re-copy on the next agent start, so restarting each agent installs it
330
+ [affects: agents/*/scripts/gws/]
331
+ - `system_prompts/plugin-gws.md` rewritten (still 50 lines): new inbound
332
+ default, the Settings section, and the "ask to be kept in `To:`" outbound
333
+ rule dropped (it existed only for the old `requireAgentInTo: true` default);
334
+ it re-seeds on the next agent start
335
+ [affects: agents/*/system_prompts/plugin-gws.md]
336
+ - gws skills `read-email` (1.1.1), `search-email` (1.0.1), `route-email`
337
+ (1.0.1): wording that hardcoded the old you-in-`To` delivery rule now points
338
+ at the agent-owned settings; they re-seed on the next agent start
339
+ [affects: agents/*/skills/gws/]
340
+ - The default flip means an existing `plugins/gws/config.json` that never set
341
+ `pollIntervalSec` / `requireAgentInTo` changes behavior on upgrade — set
342
+ them explicitly to keep the old 60s / To-only behavior
343
+ [affects: agents/*/plugins/gws/config.json]
344
+
345
+ ## [0.8.25]
346
+
347
+ ### Changed
348
+
349
+ - **The web UI's thread list renders task threads as a tree.** A thread spawned
350
+ as a task (`<parent>-§-[TASK]-§-<slug>`) now nests under its parent to any
351
+ depth, so a task thread that itself spawns tasks shows up where it belongs
352
+ instead of as a top-level row. Each child is labeled by its task slug, rows
353
+ indent per level with a collapse chevron, and search keeps the matching
354
+ subtree. Replaces the flat two-level "tasks (n)" dropdown. Web-only — no
355
+ harness artifacts change.
356
+
357
+ ## [0.8.24]
358
+
359
+ ### Added
360
+
361
+ - **`scheduler-cli list` takes filters.** `--thread-id ID` narrows to the
362
+ schedules bound to one thread, `--active`/`--paused` split by state, and
363
+ `--from WHEN [--to WHEN]` keeps only the schedules that *fire* inside a
364
+ window, adding a `fires` array of the occurrences to each. `WHEN` is ISO
365
+ (`2026-08-17T09:00:00Z`) or bare (`2026-08-17`, `2026-08-17 09:00`); bare
366
+ means wall clock in the harness timezone, read from `harness.json`. Defaults
367
+ are `--from` now and `--to` +7 days, the window is capped at 366 days, and
368
+ `--max N` (default 50) caps the fires listed per schedule. Bare `list` is
369
+ unchanged. Until now an agent asking "what have I got scheduled this week?"
370
+ had to read every schedule and evaluate the crons in its head.
371
+ - **`scripts/scheduler/cron-fires`** — the fire-time evaluator behind
372
+ `--from`/`--to`, seeded alongside `scheduler-cli`. jq cannot evaluate cron and
373
+ `croner` is not resolvable from an agent dir (no `node_modules` of its own),
374
+ so it is a dependency-free minute scan: timezone-aware via
375
+ `Intl.formatToParts`, 5- and 6-field expressions, names/ranges/steps/lists,
376
+ and the cron dom+dow OR convention. Unparseable crons come back with an
377
+ `error` field and over-long fire lists with `"truncated": true`, so nothing
378
+ is dropped silently. `node scripts/scheduler/cron-fires --self-check` runs
379
+ its assertions.
380
+
381
+ ### Breaking changes
382
+
383
+ - New `scripts/scheduler/cron-fires` — `scheduler-cli list --from/--to` needs
384
+ it and exits non-zero without it. Plugin seeds re-copy on the next agent
385
+ start, so restarting each agent installs it
386
+ [affects: agents/*/scripts/scheduler/]
387
+ - `scripts/scheduler/scheduler-cli` gained the `list` flags; it re-seeds on the
388
+ next agent start [affects: agents/*/scripts/scheduler/scheduler-cli]
389
+ - `system_prompts/plugin-scheduler.md` documents the new `list` flags (34 → 41
390
+ lines, still inside the 50-line budget); it re-seeds on the next agent start
391
+ [affects: agents/*/system_prompts/plugin-scheduler.md]
392
+
393
+ ## [0.8.23]
394
+
395
+ ### Changed
396
+
397
+ - gws prompt fragment: the inbound section no longer explains *why* outbound
398
+ mail must ask to be kept in `To:` — the rule itself is unchanged under
399
+ **Rules**, and saying it twice spent two lines of a 50-line budget on one
400
+ instruction.
401
+
402
+ ### Breaking changes
403
+
404
+ - `system_prompts/plugin-gws.md` reworded; it re-seeds on the next agent start,
405
+ so restarting the gws agents is all that is required
406
+ [affects: agents/*/system_prompts/plugin-gws.md]
407
+
408
+ ## [0.8.22]
409
+
410
+ ### Added
411
+
412
+ - **`scripts/gws/email`** — the agent-facing Gmail CLI, seeded with the `gws`
413
+ plugin. `email read <messageId>` (full body, `--strip-quotes`,
414
+ `--attachments` → `plugins/gws/inbox/<messageId>/`), `email thread <threadId>`
415
+ (skim id/from/date/snippet, or `--full` for every body), `email search
416
+ '<gmail query>' [--max N]` (hits listed with subject/from/date/snippet — the
417
+ raw API returns bare ids), `email labels`, and `email label <id> --add NAME
418
+ --remove NAME --archive --read|--unread [--create] [--thread]`, which
419
+ resolves label names to Gmail's opaque label ids and refuses an unknown name
420
+ unless `--create`. It replaces the stdin-only `scripts/gws/format-email`.
421
+ - **Plugin-shipped skills for `gws` and `telegram`**, seeded under
422
+ `skills/<plugin-id>/<slug>/` like the `artifacts` plugin's: `read-email`
423
+ (full bodies, quoted history, thread skimming, attachments), `search-email`
424
+ (Gmail query syntax, filing with labels/archive/read, and the standing
425
+ `settings.filters` rules), `route-email` (thread-routing rules) and
426
+ `route-chats` (Telegram chat routing).
427
+
428
+ ### Changed
429
+
430
+ - **gws notifications are a preview, not the mail.** An `email_received` body
431
+ is now the `Subject/From/To/TimeStamp` header, the **first two lines** of the
432
+ sender's own text (quoted reply history stripped first), and the *names* of
433
+ any attachments. Attachments are no longer downloaded at poll time — the
434
+ agent fetches what it needs with `scripts/gws/email`, so a mailbox of long
435
+ quoted-history threads stops spending context on mail nobody reads.
436
+ - **Plugin prompt fragments are capped at 50 lines**, with every step-by-step
437
+ procedure moved into a plugin-owned skill: `plugin-gws.md` 204 → 50 lines,
438
+ `plugin-telegram.md` 75 → 48. A fragment costs every turn of every thread; a
439
+ skill costs one description line until an agent needs it.
440
+ - `docs/low-level/agents.md`, `docs/base-harness/skills.md` and the `create-plugin` skill
441
+ (v1.3.0) document the 50-line budget and what belongs in a fragment
442
+ (identity, event shape, always-on rules) versus a skill. Both scaffold trees
443
+ are refreshed wholesale by the upgrade skill.
444
+
445
+ ### Breaking changes
446
+
447
+ - `scripts/gws/format-email` is replaced by `scripts/gws/email`. Plugin seeds
448
+ are overwritten on every agent start but never pruned, so the stale script
449
+ has to be deleted by hand [affects: agents/*/scripts/gws/format-email]
450
+ - Email notifications no longer carry the full body: any agent instruction or
451
+ knowledge note that assumes one — or that pipes `gws gmail users messages get
452
+ … | format-email` — must be reworded to call `scripts/gws/email read
453
+ <MessageId>` [affects: agents/*/system_prompts/1-*.md]
454
+ - The gws/telegram prompt fragments, the new `email` CLI and the four new
455
+ skills re-seed themselves on the next agent start; restarting the affected
456
+ agents is all that is required [affects: agents/*/skills/gws/]
457
+
458
+ ## [0.8.21]
459
+
460
+ ### Added
461
+
462
+ - **`artifacts` plugin** — agents publish self-contained static HTML (reports,
463
+ summaries, dashboards) and share a link on the app's own domain. Each
464
+ artifact carries a **public/private flag** that decides which of its two URLs
465
+ works: `<app>/public/artifacts/<slug>` for anyone, or
466
+ `<app>/private/artifacts/<slug>` behind the app's own login. **No URL carries
467
+ a token.** The plugin serves `public/<slug>` openly and `private/<slug>`,
468
+ `private/<slug>/meta`, `private/<slug>/share` only to callers presenting the
469
+ `ARTIFACTS_APP_SECRET` — which is what keeps private artifacts unreachable
470
+ from the open `/webhook/*` surface. Config: `appBaseUrl` (required). Catalog
471
+ scope, so it runs only on agents that opt in.
472
+ - **Artifact HTML is sandboxed and responsive by construction.** Every response
473
+ carries `Content-Security-Policy: sandbox` without `allow-same-origin` (agent
474
+ HTML on the app's origin can never touch its cookies or storage), plus
475
+ `Referrer-Policy: no-referrer`, `nosniff`, and an injected
476
+ `<meta name="viewport">` when the author omitted one.
477
+ - **`app/artifacts-routes/`** in the home template — drop-in Next.js routes for
478
+ the two paths above: a pass-through public route, and a protected page that
479
+ renders the artifact in a sandboxed iframe under the app's own public/private
480
+ toggle (the toggle is app chrome because a sandboxed page has an opaque
481
+ origin and could never authenticate). Includes `lib/artifacts.ts` with a
482
+ fail-closed `signedIn()` for the home to replace.
483
+ - **The `artifacts` seed ships a skill** — `publish-artifact` (authoring rules
484
+ for one self-contained, mobile-and-desktop-readable file; the starter
485
+ template; publishing, sharing, updating, taking down). First use of
486
+ `seed/skills/<plugin-id>/<slug>/`, now documented in `create-plugin`.
487
+
488
+ ### Changed
489
+
490
+ - **Deploy-time wiring for `artifacts`.** New `config` keys `ARTIFACTS_AGENT`
491
+ and `ARTIFACTS_SESSION_COOKIE` (both blank = feature off). When the agent is
492
+ set, `scripts/server.sh secrets` generates `ARTIFACTS_APP_SECRET` once and
493
+ writes it to **both** `harness/.secrets/secrets.json` and `app/.env.local`,
494
+ creates `agents/<agent>/plugins/artifacts/config.json` with
495
+ `appBaseUrl: https://$DOMAIN`, and thereby enables the plugin on that agent.
496
+ Existing homes get the refreshed `server.sh` + `config.example` from the
497
+ upgrade, but must add the keys to their own `config` for anything to happen.
498
+ - **`cognisphere-upgrade` 1.3.0** — `app/artifacts-routes/` joins the
499
+ harness-owned scaffold refresh (the one exception to "never refresh under
500
+ `app/`"), plus a new step 4b-i that diffs the home's *copies* of those routes
501
+ and reports drift instead of overwriting them.
502
+ - **`create-plugin` 1.2.0** — documents shipping a skill inside a plugin seed
503
+ (`seed/skills/<id>/<slug>/`), and its description now says when a plugin is
504
+ the right answer.
505
+ - **`create-skill` 1.2.0**, **`publish-harness` 1.1.0** — descriptions gained
506
+ situational triggers; `publish-harness` also covers the new-plugin case of
507
+ the shipped-artifact rule and deploy-time wiring notes.
508
+ - Docs: `docs/low-level/api.md` §10 (artifact routes + header contract),
509
+ `docs/low-level/plugins.md` (plugin list, plugin-shipped skills),
510
+ `docs/low-level/cli.md#server-deployment` (deploy-time wiring),
511
+ `docs/base-harness/README.md`, `app/README.md`.
512
+
513
+ ### Breaking changes
514
+
515
+ - New `artifacts` plugin — opt in per agent by creating the dir; it needs
516
+ `config.json` with `appBaseUrl` and the `ARTIFACTS_APP_SECRET` secret, or set
517
+ `ARTIFACTS_AGENT` in `config` and let `scripts/server.sh secrets` write all
518
+ three [affects: agents/*/plugins/artifacts/]
519
+ - Agents with the plugin enabled gain the seeded `scripts/artifacts/artifact`
520
+ CLI, the `plugin-artifacts.md` prompt fragment and the `publish-artifact`
521
+ skill on next start; all three are plugin-owned and must not be hand-edited
522
+ in the agent dir [affects: agents/*/scripts/artifacts/, agents/*/system_prompts/plugin-artifacts.md, agents/*/skills/artifacts/]
523
+
524
+ ## [0.8.20]
525
+
526
+ ### Changed
527
+
528
+ - **Memory is episodic; procedural guidance lives elsewhere.** The base
529
+ prompt's **Memory** section now states that `knowledge/memory.md` holds
530
+ events and facts only — a rule about *how to behave* belongs in
531
+ `system_prompts/1-agent.md` when it holds globally, or in the skill for the
532
+ procedure it governs when it only applies there. The seeded
533
+ `knowledge/memory.md` header carries the same rule.
534
+ - **`1-*` prompt files are the agent's to edit, with admin approval.**
535
+ Previously the base prompt routed every prompt change through the developer
536
+ agent (`nova`). Now only `0-*` and `plugin-<id>.md` files do; `1-*` files
537
+ the agent edits itself once the relevant admin has approved the change.
538
+
539
+ ### Breaking changes
540
+
541
+ - Memory section rewritten (episodic-only) and prompt-ownership rules changed
542
+ (`1-*` = self-edit with admin approval, not a `nova` request) [affects: agents/*/system_prompts/0-base_prompt.md]
543
+ - `knowledge/memory.md` header gained a "what belongs here" block — episodic
544
+ events and facts only, procedural rules go to `1-agent.md` or a skill [affects: agents/*/knowledge/memory.md]
545
+
546
+ ## [0.8.19]
547
+
548
+ ### Added
549
+
550
+ - **Chat pagination.** `GET /api/agents/:id/sessions/:threadId/:sessionId`
551
+ takes an optional `?limit=N` that returns only the newest N jsonl entries.
552
+ The file is tail-seeked — read backwards in 256 KiB chunks until N lines
553
+ are in hand — so opening a long-running thread costs the same as a short
554
+ one. The response gains `hasMore` (older rows exist above the window);
555
+ without `limit` the whole file is read and `hasMore` is `false`.
556
+ - **"Load 100 more" in the web chat.** Threads open at the newest 100
557
+ entries and page backwards on demand, preserving scroll position. The
558
+ window resets on thread/session switch, and a deep link
559
+ (`?thread=&session=&entry=`) drops the limit so the targeted entry is
560
+ always in range. The Raw JSONL tab shares the query and therefore shows
561
+ the same window.
562
+
563
+ ## [0.8.18]
564
+
565
+ ### Changed
566
+
567
+ - **Base prompt: reorganised, and workspace/memory layout reworked.**
568
+ `0-base_prompt.md` is reordered to follow the agent's actual reading path
569
+ (Cwd → System prompts → Plugins → Skills → Threads → Message metadata →
570
+ Communication model → Task threads → Workspace → Sessions → …), and the
571
+ `# Guidelines` grab-bag is gone — its content folded into **Workspace**
572
+ (persist immediately, daily notes) and **Communication model** (be
573
+ proactive).
574
+ - **New on-disk layout for notes, knowledge and memory:**
575
+
576
+ ```
577
+ workspace/
578
+ index.md
579
+ threads/<ThreadId>/{notes.md, files/, tasks/<task-slug>/notes.md}
580
+ daily_notes/YYYY-MM-DD.md
581
+ knowledge/
582
+ index.md, memory.md, files/
583
+ ```
584
+
585
+ - Task-thread notes moved from `workspace/taskThreads/<ThreadId>/tasks.md`
586
+ to `workspace/threads/<ThreadId>/tasks/<task-slug>/notes.md`; the parent
587
+ tracks its task threads in its own `notes.md → ## Tasks` section.
588
+ - Each thread dir gains a `files/` dir for files belonging to that thread.
589
+ - `workspace/memory/` is **removed**. Memory now lives in the cross-thread
590
+ `knowledge/` dir as a single `knowledge/memory.md`, with `knowledge/index.md`
591
+ indexing `knowledge/files/` (reference docs and long-term documents).
592
+ - **Memory is one grep-able file.** `knowledge/memory.md` holds sections
593
+ separated by `-----$-----$-----$-----`, each with `name`, `lastUpdated`
594
+ (`YYYY-MM-DD HH:MM:SS`) and a `description` covering what to remember, why,
595
+ where it came from, the reasoning, and how long it stays relevant. The agent
596
+ greps for the sections it needs and edits them in place instead of reading
597
+ the whole file.
598
+ - **Notes have a fixed shape.** Every `notes.md` (thread or task) is current
599
+ state, not a log: `## Context`, `## Tasks`, `## Decisions`, `## ToDos`,
600
+ `## Notes`, `## References` — every entry timestamped `YYYY-MM-DD HH:MM:SS`,
601
+ updated in place, with stale entries deleted.
602
+ - **Daily notes** now explicitly capture observations and learnings alongside
603
+ the situation/task/result summary.
604
+ - Base-agent seeds updated to match: new `knowledge/index.md` and
605
+ `knowledge/memory.md`, refreshed `workspace/index.md`.
606
+ - Docs updated: `docs/low-level/agents.md#persistent-layout` on-disk tree and the shipped
607
+ `docs/base-harness/README.md` agent-anatomy list.
608
+
609
+ ### Breaking changes
610
+
611
+ Existing harnesses must migrate their agents' on-disk files to the new layout —
612
+ the prompt no longer describes the old paths, so anything left behind is
613
+ invisible to the agent. Per agent dir:
614
+
615
+ - `0-base_prompt.md` reordered; `# Guidelines` removed; Workspace/Task-threads
616
+ sections rewritten for the new layout. Replace each fork's copy with the new
617
+ seed (harness-owned). [affects: agents/*/system_prompts/0-base_prompt.md]
618
+ - Move `workspace/memory/**` into a single `knowledge/memory.md`, one section
619
+ per memory in the new `name` / `lastUpdated` / `description` format,
620
+ separated by `-----$-----$-----$-----`; delete `workspace/memory/`. [affects: agents/*/workspace/memory/**]
621
+ - Move `workspace/taskThreads/<ThreadId>/tasks.md` content into the parent
622
+ thread's `workspace/threads/<ThreadId>/notes.md` under `## Tasks`, and any
623
+ per-task notes to `workspace/threads/<ThreadId>/tasks/<task-slug>/notes.md`;
624
+ delete `workspace/taskThreads/`. [affects: agents/*/workspace/taskThreads/**]
625
+ - Rewrite each `workspace/threads/<ThreadId>/notes.md` into the fixed sections
626
+ (`## Context`, `## Tasks`, `## Decisions`, `## ToDos`, `## Notes`,
627
+ `## References`) with timestamped entries; drop `summary.md` by folding it
628
+ into `## Context`. [affects: agents/*/workspace/threads/**]
629
+ - Seed `knowledge/index.md` and `knowledge/memory.md` if absent, and move
630
+ existing cross-thread reference docs under `knowledge/files/`. [affects: agents/*/knowledge/**]
631
+ - Refresh `workspace/index.md` from the new seed (its `## Memory` section is
632
+ gone; knowledge is indexed in `knowledge/index.md`). [affects: agents/*/workspace/index.md]
633
+
634
+ ## [0.8.17]
635
+
636
+ ### Changed
637
+
638
+ - **Base prompt: aggressive task-thread delegation is now a rule.** The
639
+ Task threads section opens with "You must delegate aggressively" and a
640
+ "should a task thread do this?" default-yes framing, and the Guidelines
641
+ checklist gained a matching bullet (bulk reads, broad searches, research,
642
+ and self-contained multi-step work belong in task threads).
643
+ - **Web UI fixes.** Tool-call card arguments no longer overflow the card
644
+ (long unbroken tokens now wrap), and empty thinking segments are no
645
+ longer rendered as collapsible blocks.
646
+
647
+ ### Breaking changes
648
+
649
+ - `0-base_prompt.md`'s Task threads and Guidelines sections now mandate
650
+ aggressive delegation to task threads. Replace each fork's copy with the
651
+ new seed (harness-owned). [affects: agents/*/system_prompts/0-base_prompt.md]
652
+
653
+ ## [0.8.16]
654
+
655
+ ### Changed
656
+
657
+ - **Skill-update notices now fire on every unseen version change, reverts
658
+ included.** 0.8.15's dedupe was keyed per (skill, new version), so a
659
+ revert back to the version the agent had originally read stayed silent
660
+ (1.2 → 1.3 → 1.2 sent only the 1.3 notice), leaving the agent believing
661
+ the withdrawn version was current. `skill-update-notice.ts` now tracks a
662
+ single "aware" version per skill — the later of the agent's own
663
+ read/edit/write and the last notice sent — and fires whenever the file's
664
+ current version differs from it, upgrades and reverts alike. Sending a
665
+ notice marks that version as seen, so nothing re-fires while the file
666
+ stays put. 0.8.15 sessions replay into the new model unchanged (read +
667
+ sent entries replay chronologically, latest wins). The notice text now
668
+ reads "changed after you last read it or were notified".
669
+ - The base prompt's `SystemMessage` bullet and the shipped
670
+ `docs/base-harness/skills.md` describe the new upgrade-and-revert
671
+ semantics (upgrade refreshes the doc wholesale).
672
+
673
+ ### Breaking changes
674
+
675
+ - `skill-update-notice.ts` notification semantics changed (fires on any
676
+ unseen version change, reverts included) — replace each fork's copy with
677
+ the shipped version. [affects: agents/*/extensions/skill-update-notice.ts]
678
+ - `0-base_prompt.md`'s `SystemMessage` bullet was reworded for the new
679
+ semantics. Replace each fork's copy with the new seed
680
+ (harness-owned). [affects: agents/*/system_prompts/0-base_prompt.md]
681
+
682
+ ## [0.8.15]
683
+
684
+ ### Changed
685
+
686
+ - **Skill-update notices close the prompt-vs-read recency gap.**
687
+ `<available_skills>` is rebuilt at every spawn, so it always advertises
688
+ the current skill version — but it sits at position 0 of the context,
689
+ before any `SKILL.md` read in history; agents reasoned by context order,
690
+ trusted the (later) read, and concluded the prompt was stale instead of
691
+ re-reading the updated skill. Two-part fix: the base prompt's Skills
692
+ section now explains the recency inversion (the prompt is regenerated
693
+ per spawn, so on a mismatch the *file* changed after the read) and what
694
+ to do (act per the skill's `CHANGELOG.md`, or re-read `SKILL.md`); and a
695
+ new seeded pi extension `skill-update-notice.ts` records the frontmatter
696
+ version of every `SKILL.md` the agent reads (or edits/writes) as custom
697
+ session entries, and when the file's current version no longer matches,
698
+ injects a one-time-per-(skill, version) standalone `<harness-metadata>`
699
+ notice — `SystemMessage: Skill "<name>" changed after you last read it
700
+ (vX -> vY)` plus the newest changelog entry — checked at
701
+ `before_agent_start` (spawn-gap bumps, lands before the batch's first
702
+ LLM call) and each `turn_start` (mid-run bumps, next steer seam). State
703
+ replays from session entries, so the once-per-version dedupe survives
704
+ the fresh-pi-per-batch process model. The base prompt's Message metadata
705
+ section documents the new `SystemMessage` field: a notice from the
706
+ harness itself, to be acted on as platform instructions.
707
+ - **context-meta checkpoints are now indexed and pre-call.** One
708
+ standalone checkpoint message before *every* LLM call, after all of that
709
+ call's inputs are in place: `Checkpoint: <n>` (monotonic per-call
710
+ counter, seeded across process respawns from session replay) +
711
+ `CheckpointTokens: +<delta>` (context growth since the previous
712
+ checkpoint: the previous response, provider-reported and exact, plus the
713
+ new input after it — tool results / incoming message — estimated at
714
+ chars/4 and ~1200 tokens per image). Every checkpoint re-anchors on
715
+ provider-reported usage, so estimation error is bounded to one step and
716
+ spans sum accurately. Checkpoints are emitted only when the next call is
717
+ provably imminent (`before_agent_start` return for a run's first call;
718
+ the last expected toolResult's `message_end` as a steer mid-run), which
719
+ deletes the old deferred/`agent_settled` flush machinery and its
720
+ empty-LLM-loop hazard. `CheckpointTokens: reset` now marks any
721
+ unknowable delta (compaction, unknown fill). The ephemeral per-call
722
+ `Model`/`ContextUsage` injection is unchanged.
723
+ - **Daily notes: one entry per thread per day.** The base prompt's
724
+ end-of-task daily-note rule now says to extend the day's existing entry
725
+ for the ThreadId instead of appending a second one.
726
+ - Shipped `docs/base-harness/skills.md` documents the recency rule and the
727
+ skill-update notice mechanism (upgrade refreshes it wholesale).
728
+
729
+ ### Breaking changes
730
+
731
+ - New seeded agent extension `skill-update-notice.ts` — copy the shipped
732
+ file into each existing agent's `extensions/` dir. [affects: agents/*/extensions/skill-update-notice.ts]
733
+ - `context-meta.ts` was rewritten (per-call indexed checkpoints) — replace
734
+ each fork's copy with the shipped version. [affects: agents/*/extensions/context-meta.ts]
735
+ - `0-base_prompt.md` gained the skills recency guidance, the
736
+ `SystemMessage` metadata field, the rewritten Checkpoint-messages
737
+ bullet, and the one-entry-per-thread daily-notes rule. Replace each
738
+ fork's copy with the new seed (harness-owned). [affects: agents/*/system_prompts/0-base_prompt.md]
739
+
740
+ ## [0.8.14]
741
+
742
+ ### Changed
743
+
744
+ - **End-of-task daily-note summaries** — the base prompt's Guidelines now
745
+ require agents to append a brief summary to
746
+ `workspace/daily_notes/YYYY-MM-DD.md` at the end of each task, tagged with
747
+ the ThreadId: a few sentences covering the situation, the task, what was
748
+ done, the result, and any learnings — brief prose, no headed sections.
749
+
750
+ ### Breaking changes
751
+
752
+ - `0-base_prompt.md` Guidelines gained the end-of-task daily-notes summary
753
+ rule [affects: agents/*/system_prompts/0-base_prompt.md]
754
+
755
+ ## [0.8.13]
756
+
757
+ ### Changed
758
+
759
+ - **`create-skill` installed in every agent** — `agent new` now installs the
760
+ shipped `create-skill` skill into every agent's own `skills/agent/` dir
761
+ (previously dev-agent only; the dev agent still gets the full set). The
762
+ base prompt's "Maintaining skills" section now states the rule explicitly:
763
+ every piece of procedural memory must land as a skill — create a new one
764
+ or update an existing one — following the installed `create-skill` skill.
765
+ - **Skill description spec** — a skill's description must carry four parts:
766
+ summary, what's included (the procedures/topics/scripts/artifacts covered,
767
+ so an agent can spot a partially relevant skill), when to use it, and the
768
+ version; `metadata` carries `author` + `version`. Taught in the base
769
+ prompt, the shipped `docs/base-harness/skills.md`, and `create-skill`
770
+ (bumped to v1.1.0).
771
+
772
+ ### Breaking changes
773
+
774
+ - `0-base_prompt.md`'s "Maintaining skills" section was rewritten: procedural
775
+ memory must always land as a new or updated skill (via the installed
776
+ `create-skill` skill), and skill descriptions must carry summary +
777
+ what's-included + when-to-use + version. Replace each fork's copy with the
778
+ new base file (harness-owned). [affects: agents/*/system_prompts/0-base_prompt.md]
779
+ - Every agent now carries the `create-skill` skill. Copy the shipped
780
+ `create-skill` skill directory into each existing agent's
781
+ `skills/agent/create-skill/`. [affects: agents/*/skills/agent/create-skill/**]
782
+
783
+ ## [0.8.12]
784
+
785
+ ### Changed
786
+
787
+ - **Deployment-owned deploy hooks (`scripts/app/`)** — the scaffolded deploy
788
+ scripts are harness-owned and refreshed on upgrade, so app-specific deploy
789
+ logic no longer gets edited into them. Each script now sources an optional
790
+ deployment-owned hook: `server.sh` `gen_secrets` → `scripts/app/secrets.sh`
791
+ (after the stock secrets), `server.sh` → `scripts/app/server.sh` (after every
792
+ stock action except `harness`/`dev`/`logs`, same positional args — app
793
+ lifecycle work), `setup-server.sh` → `scripts/app/setup-server.sh`
794
+ (end, as root), `aws/setup.sh` → `scripts/app/aws-setup.sh` and
795
+ `contabo/setup.sh` → `scripts/app/contabo-setup.sh` (end of provisioning).
796
+ Hooks are sourced with the deploy `config` + the caller's resolved vars in
797
+ scope. Extra deploy params go in the deployment-owned root `config`,
798
+ documented in a deployment-owned `scripts/app/config.example` (the root
799
+ `config.example` stays harness-owned). Only `scripts/app/README.md` (the
800
+ contract) ships with the template. `cognisphere-upgrade` bumped to v1.2.0
801
+ to teach the scaffold refresh this ownership split.
802
+
803
+ - **pi upgraded to 0.84.1** (`@earendil-works/pi-ai` +
804
+ `@earendil-works/pi-coding-agent`, from 0.81.1). No harness code
805
+ changes were required: the RPC event contract the harness consumes
806
+ (`agent_start`, `agent_end`, `message_start`, extension `setStatus`
807
+ reports), the session JSONL format (`CURRENT_SESSION_VERSION` still
808
+ 3), the `pi --mode rpc` flag set, and the `ExtensionAPI` /
809
+ `ModelRuntime` surfaces the harness uses are all unchanged or
810
+ additive. pi 0.84.0's `message_update` breaking change (deltas only,
811
+ no cumulative `message`) does not affect us — the harness never reads
812
+ `message_update`. `ModelRuntime.reloadConfig()` was removed upstream;
813
+ the harness never called it.
814
+ - `core/models-catalog.ts`: refreshed the mirrored `KnownProvider` union
815
+ to pi-ai 0.84.1 (adds `baseten`, `qwen-token-plan-individual`, and the
816
+ `ant-ling` / `radius` / `nvidia` / `zai-coding-cn` / `qwen-token-plan`
817
+ / `qwen-token-plan-cn` ids that had drifted in since 0.81.1). Catalog
818
+ entries themselves are unchanged — new providers stay unlisted in the
819
+ Models page until an entry is added.
820
+ - **System-prompt file ownership is now an explicit contract**, taught in
821
+ the base prompt (new "System prompts" section) and documented in
822
+ `docs/low-level/agents.md#persistent-layout` and the shipped `docs/base-harness/README.md`:
823
+ `0-*` files are harness-owned (replaced by the seed on upgrade;
824
+ `0.1-agent-directory.md` excepted), `plugin-<id>.md` is plugin-owned
825
+ (reseeded on every agent start — edits are clobbered), and `1-agent.md`
826
+ is deployment-owned: identity/persona/behaviour only. Any deliberate
827
+ override of a harness- or plugin-owned prompt file must be documented in
828
+ the home's `docs/harness/`; undocumented divergence is drift.
829
+ - **Skills are the agent's procedural memory, and are versioned.** The base
830
+ prompt's new "Skills" section tells agents to keep every step-by-step
831
+ procedure (SOP, runbook) as a skill — never inlined in prompt files,
832
+ `knowledge/`, or workspace notes — with the version stated in the skill's
833
+ description (the only metadata pi injects into the prompt) and in
834
+ `SKILL.md`'s `metadata.version`, plus a per-skill `CHANGELOG.md`. Skills
835
+ are self-contained — helper scripts in the skill's `scripts/`, supporting
836
+ files in `artifacts/`, referenced by skill-relative paths. Agents
837
+ re-read a skill whose advertised version differs from the copy they last
838
+ read, so version bumps propagate procedure changes to long-running
839
+ agents, and task-thread briefs name the skill (and version) to follow
840
+ instead of restating its steps. Shipped skills (`cognisphere-upgrade` v1.1.0, `create-plugin`
841
+ v1.1.0) follow the convention; the `cognisphere-upgrade` skill now also
842
+ migrates procedural content out of prompts/SOPs into versioned skills
843
+ when an upgrade window touches an agent's prompts.
844
+ - **New shipped skill `create-skill` (v1.0.0)** — the authoring/updating
845
+ procedure for versioned agent skills: scaffold `SKILL.md` + per-skill
846
+ `CHANGELOG.md` + `scripts/`/`artifacts/`, semver bump rules, SOP
847
+ migration, and pi's frontmatter constraints. Installed like the other
848
+ cognisphere skills — into the home's `.claude/skills/` + `.agents/skills/`
849
+ by `init`, and into the developer agent's own `skills/agent/` — so the
850
+ dev agent carries the skill-authoring procedure as a skill itself.
851
+ Existing homes pick it up via the upgrade's scaffold refresh; existing
852
+ dev agents by copying it into `agents/nova/skills/agent/create-skill/`.
853
+ - `cognisphere agent new` seeds a starter `system_prompts/1-agent.md`
854
+ (persona skeleton) so every agent dir carries the same prompt layout.
855
+
856
+ ### Breaking changes
857
+
858
+ - The developer-agent persona file was renamed for layout consistency:
859
+ `system_prompts/1-dev-agent.md` → `system_prompts/1-agent.md`. Rename the
860
+ fork's file (contents unchanged). [affects: agents/nova/system_prompts/*]
861
+ - `0-base_prompt.md` gained the "Skills" and "System prompts" sections and
862
+ moved procedures out of `knowledge/SOPs/`. Replace each fork's copy with
863
+ the new seed (local edits in a `0-*` file move to `1-agent.md`). [affects: agents/*/system_prompts/0-base_prompt.md]
864
+ - Procedural memory must live in versioned skills: for every agent, re-read
865
+ its `system_prompts/*.md` and `knowledge/` (incl. `knowledge/SOPs/`) and
866
+ migrate each step-by-step procedure into
867
+ `skills/agent/<slug>/SKILL.md` (version in description +
868
+ `metadata.version`, per-skill `CHANGELOG.md`, helper scripts in the
869
+ skill's `scripts/`, supporting files in `artifacts/`), updating
870
+ `1-agent.md` to reference the skill instead of restating it. [affects: agents/*]
871
+
872
+ ## [0.8.11]
873
+
874
+ ### Changed
875
+
876
+ - **Model overrides in `.secrets/models.json` now configure pi itself.**
877
+ New `core/pi-models-sync.ts` mirrors the store's `modelOverrides` into
878
+ pi's own models.json (`~/.pi/agent/models.json`, or
879
+ `$PI_CODING_AGENT_DIR/models.json`) at server boot, on every agent
880
+ start, and after `PUT /api/models` — so spawned pi children resolve the
881
+ overridden `contextWindow`/`maxTokens` natively (model registry,
882
+ in-context ContextUsage telemetry, and pi's compaction thresholds).
883
+ Ownership: for providers present in the harness store, the
884
+ `modelOverrides` key of pi's models.json is harness-owned (replaced
885
+ wholesale, removed when the store has none); all other fields and
886
+ providers in that file are preserved, and a corrupt file is skipped,
887
+ never clobbered.
888
+ - **Pi-as-configured is now the single source of truth for context
889
+ windows.** The API's reporting (`lastContext` in `/api/agents/usage`
890
+ and the threads list) resolves context windows via pi models.json
891
+ (`modelOverrides`, then custom model entries) with pi-ai's built-in
892
+ catalog as fallback, instead of consulting `.secrets/models.json`
893
+ directly — the dashboard and the agent's in-context telemetry can no
894
+ longer disagree, and hand-written custom providers in pi's models.json
895
+ now report correct context windows too.
896
+
897
+ ## [0.8.10]
898
+
899
+ ### Changed
900
+
901
+ - **`extensions/context-meta.ts`: turn-ending checkpoints now land right
902
+ after the final response.** Instead of deferring to the next inbound
903
+ message (which placed the checkpoint after the next user message), the
904
+ deferred emit fires on `agent_settled` — the agent is idle there, so
905
+ `sendMessage` appends the checkpoint directly to the session without
906
+ triggering a turn or an LLM call. Tool-use responses keep the immediate
907
+ steer emit (checkpoint after that response's tool results). Inbound-flush
908
+ and seed-time catch-up remain as fallbacks.
909
+
910
+ ### Breaking changes
911
+
912
+ - Seeded file `extensions/context-meta.ts` changed (turn-ending checkpoint
913
+ placement via agent_settled). Copy it from the new seed into existing
914
+ agents. [affects: agents/*/extensions/*]
915
+
916
+ ## [0.8.9]
917
+
918
+ ### Fixed
919
+
920
+ - **`extensions/context-meta.ts`: infinite invocation loop after
921
+ turn-ending responses (0.8.8 regression — upgrade off 0.8.8
922
+ immediately).** A checkpoint message queued via `sendMessage` lands in
923
+ pi's pending-message queue, and the agent loop keeps running while any
924
+ pending message exists — so a checkpoint emitted right after a response
925
+ with no tool calls kept provoking empty LLM calls forever, one paid call
926
+ per cycle. Checkpoints are now sent immediately only when the response
927
+ has tool calls (the loop continues anyway); for a turn-ending response
928
+ the emit is deferred to the next inbound message, with the existing
929
+ seed-time catch-up covering process exit. Per-step granularity and the
930
+ gapless trail are unchanged.
931
+
932
+ ### Breaking changes
933
+
934
+ - Seeded file `extensions/context-meta.ts` changed (checkpoint emission no
935
+ longer extends the agent loop). Copy it from the new seed into existing
936
+ agents. [affects: agents/*/extensions/*]
937
+
938
+ ## [0.8.8]
939
+
940
+ ### Changed
941
+
942
+ - **`extensions/context-meta.ts`: checkpoints are now standalone messages
943
+ instead of stamps on neighboring messages.** After each assistant
944
+ response the extension injects a custom message
945
+ (`customType: "context-meta.checkpoint"`) carrying
946
+ `CheckpointTokens: +<n>` and a self-describing `Covers:` line, delivered
947
+ at the first provider-legal seam (after the response's tool calls,
948
+ before the next LLM call). Standalone messages are prune-safe: a future
949
+ context cleaner can remove a span and its checkpoint by identity,
950
+ instead of stranding a stamp fused into a kept message that describes
951
+ deleted content. A checkpoint covers everything up through the nearest
952
+ assistant response above it; seeding emits a catch-up checkpoint on
953
+ spawn if the previous batch exited with one still queued, keeping the
954
+ trail gapless across batches. User messages and tool results are no
955
+ longer stamped.
956
+ - Base system prompt: `CheckpointTokens` moved out of the incoming-message
957
+ metadata fields into the telemetry section — documents the standalone
958
+ checkpoint messages, their coverage rule, and that they are informational
959
+ only (never act on or reply to them).
960
+
961
+ ### Breaking changes
962
+
963
+ - Seeded file `extensions/context-meta.ts` changed (standalone checkpoint
964
+ messages replace per-message stamps). Copy it from the new seed into
965
+ existing agents. [affects: agents/*/extensions/*]
966
+ - Message-metadata section of the seeded base system prompt changed
967
+ (checkpoint messages documented as standalone telemetry, FYI-only; field
968
+ removed from the block example). Graft into existing agents'
969
+ prompts. [affects: agents/*/system_prompts/0-base_prompt.md]
970
+
971
+ ## [0.8.7]
972
+
973
+ ### Changed
974
+
975
+ - **`extensions/context-meta.ts`: checkpoint stamps now span batch
976
+ boundaries.** On spawn the extension replays the stamping state machine
977
+ over the persisted session instead of only seeding a baseline, so a
978
+ batch that ended on an assistant response leaves its pending checkpoint
979
+ recoverable — the next batch's first message carries it (the previous
980
+ batch's final step). Only a thread's very first message has no
981
+ `CheckpointTokens` stamp.
982
+
983
+ ### Breaking changes
984
+
985
+ - Seeded file `extensions/context-meta.ts` changed (cross-batch checkpoint
986
+ seeding). Copy it from the new seed into existing agents. [affects: agents/*/extensions/*]
987
+
988
+ ## [0.8.6]
989
+
990
+ ### Added
991
+
992
+ - **New seeded pi extension `extensions/context-meta.ts`: context-window
993
+ telemetry for the agent.** Two signals:
994
+ - `CheckpointTokens: +<n>` — persistent per-step stamps. After each
995
+ assistant response, the first following user message / tool result is
996
+ stamped with the exact context growth of the completed step, computed
997
+ from consecutive provider-reported usage totals (no estimation).
998
+ Deltas are per-step, never cumulative, so the trail stays truthful
999
+ across compaction; a compaction stamps `CheckpointTokens: reset`.
1000
+ Summing a span of stamps tells the agent what pruning that span would
1001
+ free. Seeded from the session JSONL on spawn, so deltas stay exact
1002
+ across batch boundaries.
1003
+ - `Model:` + `ContextUsage: <tokens>/<context window>` — ephemeral,
1004
+ injected into each LLM call's last outgoing message via the `context`
1005
+ hook; never persisted, so exactly one fresh copy exists per call.
1006
+
1007
+ ### Changed
1008
+
1009
+ - Base system prompt: `<harness-metadata>` docs gain the `CheckpointTokens`
1010
+ field and a note on the latest-message `Model`/`ContextUsage` telemetry,
1011
+ with guidance to delegate/wrap up under context pressure.
1012
+
1013
+ ### Breaking changes
1014
+
1015
+ - New seeded file `extensions/context-meta.ts`. Copy it from the new seed
1016
+ into existing agents. [affects: agents/*/extensions/*]
1017
+ - Message-metadata section of the seeded base system prompt changed
1018
+ (`CheckpointTokens` field, `Model`/`ContextUsage` telemetry note). Graft
1019
+ into existing agents' prompts. [affects: agents/*/system_prompts/0-base_prompt.md]
1020
+
1021
+ ## [0.8.5]
1022
+
1023
+ ### Changed
1024
+
1025
+ - **Task-thread ids are now `<ThreadId>-§-[TASK]-§-<task-slug>`** (parent
1026
+ thread id, literal `[TASK]` marker, kebab-case task slug, joined by
1027
+ `-§-`) instead of the ambiguous `<ThreadId>-<task-slug>`. Prompts and
1028
+ the session-reader help teach the new form; thread ids remain opaque to
1029
+ the queue/runner, so no data migration — existing old-format task
1030
+ threads keep working, they just render as ordinary threads in the UI.
1031
+ - **The admin web UI groups task threads under their parent thread.** The
1032
+ thread list no longer shows task threads as top-level rows; each parent
1033
+ gets a `tasks (N)` dropdown listing them by task slug (select/delete),
1034
+ the mobile picker indents them under the parent, and search matches a
1035
+ parent by its task threads. Task threads with a missing parent fall
1036
+ back to the top-level list.
1037
+
1038
+ ### Breaking changes
1039
+
1040
+ - Task-thread delegation section rewritten for the new
1041
+ `<ThreadId>-§-[TASK]-§-<task-slug>` id format. [affects: agents/*/system_prompts/0-base_prompt.md]
1042
+ - Task-thread spawn note updated to the new id format. [affects: agents/*/system_prompts/plugin-agent-messaging.md]
1043
+ - `--help` text: task-thread session dir example updated to the new id
1044
+ format. [affects: agents/*/scripts/agent/session-reader]
1045
+
1046
+ ## [0.8.4]
1047
+
1048
+ ### Changed
1049
+
1050
+ - **The upgrade skill's scaffold refresh now audits local edits first and
1051
+ guarantees they survive.** Step 4 is audit → copy → re-apply: diff every
1052
+ scaffold area against the installed package before copying, use the home's
1053
+ git history to separate local edits from upstream changes, list every
1054
+ local edit in the summary, then re-apply them on top of the fresh copies —
1055
+ so the approval diff shows upstream changes plus intact local edits. A
1056
+ local edit is dropped only with explicit operator approval; when a
1057
+ difference can't be classified, the skill stops and asks.
1058
+
1059
+ ## [0.8.3]
1060
+
1061
+ ### Changed
1062
+
1063
+ - **The upgrade skill now refreshes every harness-owned scaffold file on
1064
+ upgrade** — `scripts/`, `config.example`, `docs/base-harness/`, and
1065
+ `.claude/skills/` are re-copied wholesale from the installed package as
1066
+ part of the reviewed migration diff, so scaffold fixes reach existing
1067
+ homes even when a release didn't list them as breaking changes. User-owned
1068
+ files (`app/`, `docs/harness/`, `docs/app/`, `CLAUDE.md`, `config`, and
1069
+ the harness data dir) are never touched by the refresh.
1070
+ - **The publish preflight gates shipped-artifact changes.** Changes since the
1071
+ last release to files forked into agent dirs (`src/agents/**`,
1072
+ `src/plugins/*/seed/**`) fail preflight unless the version's CHANGELOG
1073
+ section carries a `### Breaking changes` block; changed scaffold/skill
1074
+ files are listed as a reminder to note them under `### Changed`.
1075
+ - Shipped docs updated to match (`docs/base-harness/skills.md`).
1076
+
1077
+ ## [0.8.2]
1078
+
1079
+ ### Fixed
1080
+
1081
+ - **The runner now exports `HARNESS_BASE_URL` (= `serverBaseUrl`) to every
1082
+ agent process.** The seeded `agent-msg/send` reads
1083
+ `${HARNESS_BASE_URL:-http://127.0.0.1:3142}`, but nothing ever set the
1084
+ variable — the runner didn't export it and the deploy scripts only define
1085
+ `HARNESS_PORT`, which the script never reads. So on any non-default port
1086
+ (`PORT` / `cognisphere serve --port`), agent-messaging silently posted to
1087
+ the wrong origin. The fallback in the seed is unchanged and now only
1088
+ covers running the script outside a runner-spawned process.
1089
+
1090
+ ## [0.8.1]
1091
+
1092
+ ### Fixed
1093
+
1094
+ - **Base prompt no longer tells agents to pass `-o json` to ddgs.** That flag
1095
+ doesn't print to stdout — it writes the results to a file in the cwd (e.g.
1096
+ `text_<query>_<timestamp>.json`), so piping to `jq` got empty input and
1097
+ agent dirs silently accumulated result files. The prompt now says to read
1098
+ the default stdout table directly and warns against `-o json`/`-o csv`.
1099
+ - **Plugin requests route to `nova`, not the operator.** The communication
1100
+ model section still said to ask the operator (via the admin plugin) to
1101
+ install or write missing plugins, contradicting 0.8.0's ownership model
1102
+ (§Platform code changes). It now forwards those requests to the developer
1103
+ agent via agent-messaging, keeping the operator for what genuinely needs
1104
+ them (secrets, harness restarts).
1105
+ - **`session-reader --help` documented a session layout 0.8.0 deleted.** The
1106
+ `sessions/<ThreadId>/subagents/<subAgentId>/` path example is now
1107
+ `sessions/<ThreadId>-<task-slug>/` — task-thread sessions are ordinary
1108
+ threads.
1109
+ - **Wrapper headers (`agent-browser`, `ddgs`, `markitdown`) no longer cite the
1110
+ removed `pi -p` sub-agent CLI** as their reason to exist. The wrappers stay
1111
+ (the PATH/venv rationale holds); the header comments and `--help` text now
1112
+ state it without referencing sub-agents.
1113
+
1114
+ ### Breaking changes
1115
+
1116
+ - Base prompt corrections (ddgs output flags, plugin-request routing) —
1117
+ replace the fork's copy with the new seed, re-applying any local
1118
+ edits. [affects: agents/*/system_prompts/0-base_prompt.md]
1119
+ - session-reader help updated for the task-thread session layout —
1120
+ re-seed. [affects: agents/*/scripts/agent/session-reader]
1121
+ - Wrapper rationale comments dropped the `pi -p` reference — re-seed (no
1122
+ behavior change). [affects: agents/*/scripts/agent/agent-browser, agents/*/scripts/agent/ddgs, agents/*/scripts/agent/markitdown]
1123
+
1124
+ ## [0.8.0]
1125
+
1126
+ ### Changed
1127
+
1128
+ - **Sub-agents are now task threads.** The `pi -p` sub-agent CLI is gone;
1129
+ delegation runs through the core agent-messaging plugin instead. An agent
1130
+ spawns a task by messaging **itself** on a new thread id
1131
+ `<parentThreadId>-<task-slug>`; the task thread runs with the full agent
1132
+ prompt in its own context window and **must report back** to the parent
1133
+ thread (named explicitly in the brief) via `scripts/agent-msg/send` when
1134
+ done. Delegation is asynchronous — the parent ends its turn and is woken by
1135
+ the report; follow-ups and status checks are messages to the same task
1136
+ thread. Task-thread status is declared **in the brief**, never inferred from
1137
+ the sender (self-messages also arrive for other reasons).
1138
+ - **One agent prompt.** `0-base_prompt.md` and `0.1-main-agent.md` merged into
1139
+ a single `0-base_prompt.md` covering identity, tools, workspace, threads,
1140
+ plugins, communication, task threads, app home, and the dev-agent hand-off.
1141
+ Ownership is now explicit: each agent owns its own agent dir (scripts,
1142
+ skills, workspace, knowledge); platform code **and software installs** go to
1143
+ the developer agent.
1144
+ - **agent-messaging is a core plugin** (`CORE_PLUGIN_IDS`) — auto-installed
1145
+ and seeded on every agent alongside admin and scheduler; `cognisphere
1146
+ plugin add agent-messaging` is refused. Messaging a thread id that doesn't
1147
+ exist yet starts a fresh thread (that's how task threads spawn).
1148
+ - **The developer agent is always `nova`.** `cognisphere init` creates it
1149
+ under that fixed id (`--dev-agent` flag removed), `agent new` refuses the
1150
+ name for any other agent, and the prompt templates reference `nova`
1151
+ literally — the `{{DevAgentId}}`/`{{DevAgentName}}` baking (and the
1152
+ `bakeDevAgentName`/`findDevAgentId` CLI machinery) is gone. Telegram is no
1153
+ longer auto-enabled on it; human channels are opt-in (other agents reach it
1154
+ via agent-messaging).
1155
+ - **Web console:** agent messages are hyperlinked — an incoming
1156
+ `agent_message` links to the sender's thread (`From`/`FromThread`), and an
1157
+ `agent-msg/send` tool call links to the destination agent thread
1158
+ (`$PI_AGENT_ID` resolves to the current agent). Thread-only deep links
1159
+ (`?thread=`) now work without a session id.
1160
+ - Base template and dev overlay moved to `src/agents/base-agent/` and
1161
+ `src/agents/nova/` inside the package (was `src/base-agent/`,
1162
+ `src/dev-agent/`). No harness-side effect; `files` already ships `src/`.
1163
+
1164
+ ### Removed
1165
+
1166
+ - `subagentModel` from `agent.json` and the `PI_SUBAGENT_PROVIDER` /
1167
+ `PI_SUBAGENT_MODEL` / `PI_SUBAGENT_THINKING` env vars — task threads run on
1168
+ the agent's own model (per-thread overrides still apply).
1169
+ - The `subagents` array from `GET /api/agents/:id/sessions/:threadId/usage`
1170
+ (and the legacy `sessions/<threadId>/subagents/*/` scanning behind it). The
1171
+ response is now `{ threadId, main }`; task-thread usage shows up as
1172
+ ordinary threads.
1173
+
1174
+ ### Breaking changes
1175
+
1176
+ - Sub-agent CLI removed — delete the seeded wrapper and role prompt from every
1177
+ agent fork. [affects: agents/*/scripts/agent/subagent]
1178
+ - Sub-agent role prompt removed with it. [affects: agents/*/scripts/agent/sub-agent-prompt.md]
1179
+ - `0.1-main-agent.md` merged into `0-base_prompt.md` — replace the fork's
1180
+ `0-base_prompt.md` with the new seed (re-apply any local edits) and delete
1181
+ `0.1-main-agent.md`. [affects: agents/*/system_prompts/]
1182
+ - Agent-directory roster renamed — rename the file to
1183
+ `0.1-agent-directory.md` (contents unchanged; the manager only regenerates
1184
+ the new name when absent, so an un-renamed copy would duplicate the
1185
+ roster). [affects: agents/*/system_prompts/0.3-agent-directory.md]
1186
+ - `subagentModel` no longer read — remove the key where present. [affects: agents/*/agent.json]
1187
+ - agent-messaging became a core plugin — the per-agent enable dir is
1188
+ redundant (remove), and a forked copy now shadows the bundled core plugin
1189
+ (remove unless the fork is intentional). [affects: agents/*/plugins/agent-messaging, plugins/agent-messaging]
1190
+ - Developer agent id frozen to `nova` — rename the existing dev agent's dir
1191
+ (the one whose `agent.json` has `devAgent: true`, e.g. `dory`) to `nova`,
1192
+ and update any references to the old id (other agents' roster fragments,
1193
+ `allowMessageFrom` lists, workspace notes). New prompt seeds address the
1194
+ dev agent as `nova` literally. [affects: agents/*]
1195
+
1196
+ ## [0.7.2]
1197
+
1198
+ ### Fixed
1199
+
1200
+ - **`spawn E2BIG` on every batch once `system_prompts/` crossed 128 KiB.** The
1201
+ runner passed the whole assembled system prompt as a single `--system-prompt`
1202
+ argv value. Linux caps **one** argv/env string at `MAX_ARG_STRLEN` = 131 072
1203
+ bytes — a per-string limit, independent of the ~2 MB `ARG_MAX` total — so a
1204
+ prompt tree that grew past 128 KiB killed `spawn("pi", …)` outright. Because
1205
+ `assembleSystemPrompt` hands every thread the same files, this took *all* of
1206
+ an agent's threads down at once, with `E2BIG` and no partial failure to
1207
+ narrow it down.
1208
+
1209
+ The runner now writes the assembled prompt to
1210
+ `sessions/<threadId>/.system-prompt.md` (rewritten on every spawn) and passes
1211
+ **that path** to `--system-prompt`. pi's `resolvePromptInput` already reads a
1212
+ flag value as a file when it names an existing path, so this needs no pi-side
1213
+ change, and files have no length ceiling. An env var would not have worked —
1214
+ same per-string cap.
1215
+
1216
+ `scripts/agent/subagent` had the identical exposure (it concatenated
1217
+ `0-base_prompt.md` + `sub-agent-prompt.md` into one `--system-prompt` string,
1218
+ so sub-agents were on course to fail the same way at the same threshold). It
1219
+ now passes the two files as paths — `--system-prompt <base>
1220
+ --append-system-prompt <role>` — which pi composes as
1221
+ `<system-prompt>\n\n<append>`, byte-identical to the concatenation it
1222
+ replaces.
1223
+
1224
+ ### Changed
1225
+
1226
+ - **The developer agent now gets the `agent-messaging` plugin by default**, on
1227
+ top of telegram. It owns the home's platform code and every other agent's
1228
+ prompt tells it to route code and doc changes there — but until now nothing
1229
+ gave those agents a way to actually send it one; the request had to go
1230
+ through a human on Telegram. `cognisphere init` and
1231
+ `cognisphere agent new <name> --dev` both enable it. The inbox default is
1232
+ unchanged (`allowMessageFrom: ["*"]`, i.e. any in-harness agent).
1233
+
1234
+ ### Breaking changes
1235
+
1236
+ - Existing developer agents don't have the `agent-messaging` plugin enabled;
1237
+ create the (empty) plugin dir to install the bundled copy with its default
1238
+ config. [affects: agents/*/plugins/agent-messaging/]
1239
+ - `scripts/agent/subagent` passes the sub-agent system prompt as two file
1240
+ paths instead of one concatenated string (operator edits survive — merge
1241
+ rather than overwrite). [affects: agents/*/scripts/agent/subagent]
1242
+
1243
+ ## [0.7.1]
1244
+
1245
+ ### Added
1246
+
1247
+ - **gws routing on the Gmail thread id** — `scripts/gws/routes add` takes a
1248
+ new `--gmail-thread-id RE` (rule field `gmailThreadId`), matched as an
1249
+ **anchored**, case-insensitive regex against the raw Gmail thread id — a
1250
+ plain id is an exact match, `a|b` a set. This is the precise way to park
1251
+ replies: a reply always stays in the Gmail thread of the message it
1252
+ answers, so routing on that id captures the follow-ups to one mail and
1253
+ nothing else, where `--from`/`--subject` also catch unrelated mail. A rule
1254
+ still needs at least one of `--from` / `--subject` / `--gmail-thread-id`,
1255
+ and when several are given all must match; first matching rule wins.
1256
+
1257
+ ### Breaking changes
1258
+
1259
+ *(Nothing breaks — rules without `gmailThreadId` behave exactly as before.)*
1260
+
1261
+ - `scripts/gws/routes` gained the `--gmail-thread-id` flag, and
1262
+ `system_prompts/plugin-gws.md`'s "Routing rules" section documents it
1263
+ (operator edits survive — merge rather than overwrite). [affects: agents/*/scripts/gws/routes, agents/*/system_prompts/plugin-gws.md]
1264
+
1265
+ ## [0.7.0]
1266
+
1267
+ ### Added
1268
+
1269
+ - **Telegram thread-routing rules** — `plugins/telegram/state/routes.json`,
1270
+ managed by the seeded `scripts/telegram/routes` CLI (`add | list |
1271
+ remove`), mirrors the gws routing added in 0.6.0. A rule maps a chat id to
1272
+ a thread id of the agent's choosing, overriding the agent's
1273
+ `threadIdStrategy`: `routes add --name ops --thread-id ops-room --chat
1274
+ '-100.*'`. `--chat` is an **anchored**, case-insensitive regex matched
1275
+ against the chat id — a plain id is an exact match, `.*` is a wildcard,
1276
+ `123|456` a set. First matching rule wins; the plugin re-reads the file on
1277
+ every batch of updates, so a new rule takes effect immediately. `/reset`
1278
+ in a routed chat resets the routed thread.
1279
+
1280
+ ### Changed
1281
+
1282
+ - **`PluginInstanceContext.resetThread` takes an optional second argument**
1283
+ — `resetThread(channelId, threadIdOverride?)`. Plugins that route a
1284
+ channel to a custom thread pass the same override they gave `notify`, so
1285
+ the reset hits the thread the messages actually landed in. Omitted → the
1286
+ previous `threadIdStrategy` mapping, unchanged.
1287
+
1288
+ ### Breaking changes
1289
+
1290
+ *(Nothing breaks — the routing CLI is a new on-disk artifact an existing
1291
+ home syncs to adopt; agents without `routes.json` behave exactly as before.)*
1292
+
1293
+ - New seeded script `scripts/telegram/routes` and a "Routing rules" section
1294
+ in `system_prompts/plugin-telegram.md` (operator edits survive — merge
1295
+ rather than overwrite). [affects: agents/*/scripts/telegram/routes, agents/*/system_prompts/plugin-telegram.md]
1296
+
1297
+ ## [0.6.2]
1298
+
1299
+ ### Changed
1300
+
1301
+ - **Base agent knows about the app home.** `0.1-main-agent.md` gained a
1302
+ `# The app home` section pointing every agent at the repo above its agent
1303
+ dir: `../../../app/` (the user-facing frontend users see in a browser),
1304
+ `../../../docs/` (`base-harness/` platform reference, `harness/` this
1305
+ deployment's agents/plugins, `app/` the frontend), plus `harness/` and
1306
+ `scripts/`. The `# Platform code changes` hand-off now covers the app and
1307
+ the docs explicitly — read freely, route every change to the developer
1308
+ agent, report stale docs there.
1309
+ - **Developer agent's `agent.json.description`** (what the agent-directory
1310
+ roster shows other agents) now names the frontend app and the docs duty:
1311
+ "…owns and modifies this deployment's platform code — agent
1312
+ prompts/scripts, forked plugins, the user-facing frontend app, deploy
1313
+ scripts — and keeps docs/harness + docs/app current."
1314
+
1315
+ ### Breaking changes
1316
+
1317
+ *(Nothing breaks — both are on-disk artifacts an existing home must sync to
1318
+ adopt; old copies keep working untouched.)*
1319
+
1320
+ - `system_prompts/0.1-main-agent.md` gained the app-home + docs sections
1321
+ (operator edits survive — merge rather than overwrite; `{{DevAgentId}}` /
1322
+ `{{DevAgentName}}` are baked at fork time, so substitute the dev agent's
1323
+ actual id when hand-merging). [affects: agents/*/system_prompts/0.1-main-agent.md]
1324
+ - The developer agent's `agent.json.description` is only written at
1325
+ `agent new --dev` time; existing homes keep the old one-liner until
1326
+ edited. [affects: agents/*/agent.json]
1327
+
1328
+ ## [0.6.1]
1329
+
1330
+ ### Changed
1331
+
1332
+ - **Default HTTP port is now `3142`** (was `7331`) — `PORT` / `cognisphere
1333
+ serve --port` still override it. Updated everywhere the old default was
1334
+ baked in: `config.ts`, the CLI's `DEFAULT_PORT`, the web dev-server proxy
1335
+ target, the scaffold's `HARNESS_PORT` default, the seeded `agent-msg/send`
1336
+ fallback base URL, and the docs.
1337
+
1338
+ ### Breaking changes
1339
+
1340
+ - Existing homes pin `HARNESS_PORT=7331` in their `config`, so they keep
1341
+ serving on 7331 — but the re-seeded `scripts/agent-msg/send` now falls back
1342
+ to `127.0.0.1:3142`, which breaks agent-to-agent messaging. Either set
1343
+ `HARNESS_PORT=3142` in `config` (then re-run `scripts/setup-server.sh` to
1344
+ regenerate the systemd unit + nginx vhost, and restart), or keep 7331 and
1345
+ export `HARNESS_BASE_URL=http://127.0.0.1:7331` into the harness
1346
+ environment. [affects: config, scripts/setup-server.sh]
1347
+
1348
+ ## [0.6.0]
1349
+
1350
+ ### Added
1351
+
1352
+ - **gws thread routing.** The `gws` plugin now reads routing rules from
1353
+ `plugins/gws/state/routes.json` on every poll; the first rule whose
1354
+ `from` / `subject` patterns match an inbound thread replaces the default
1355
+ harness thread id (`<Subject>[<gmailThreadId>]`) with the rule's own
1356
+ `threadId`. Patterns are case-insensitive, unanchored regexes, so a plain
1357
+ string is a substring match. Lets an agent mail someone from a thread and
1358
+ have the reply land back in that same thread instead of opening a new one.
1359
+ - **`scripts/gws/routes` CLI** (seeded with the plugin): `add|list|remove`,
1360
+ atomic writes, rules take effect within one poll interval. A rule with
1361
+ neither `--from` nor `--subject` is rejected — it would capture every
1362
+ inbound email. Documented in the plugin's system prompt; existing homes
1363
+ pick both up automatically (the gws seed is re-copied on plugin start).
1364
+
1365
+ ## [0.5.1]
1366
+
1367
+ ### Added
1368
+
1369
+ - **Per-unit restart.** `scripts/server.sh` `start`/`stop`/`restart` now take an
1370
+ optional `app`|`harness` target to bounce a single systemd unit; omit it for
1371
+ both (the deploy loop is unchanged). `restart app` builds and restarts only
1372
+ the app unit — applying an app-only change without touching the harness.
1373
+ - **Developer agent ships app changes itself.** The dev-agent prompt now tells
1374
+ it to apply `app/` changes live via `sudo ./scripts/server.sh restart app`
1375
+ (its own session survives, since the app is a separate unit), and to leave
1376
+ harness restarts to the operator — restarting the harness would kill its own
1377
+ turn mid-run; the interrupted turn is requeued and swept back in on boot.
1378
+
1379
+ ### Breaking changes
1380
+
1381
+ *(No behavior breaks — both entries are on-disk artifacts an existing home must
1382
+ sync to adopt the feature; old copies keep working untouched.)*
1383
+
1384
+ - `scripts/server.sh` gained the optional `app`|`harness` restart target. [affects: scripts/server.sh]
1385
+ - The developer agent's `1-dev-agent.md` prompt gained the app-restart
1386
+ instructions (operator edits survive — re-seed or merge if customised). [affects: agents/*/system_prompts/1-dev-agent.md]
1387
+
1388
+ ## [0.5.0]
1389
+
1390
+ ### Added
1391
+
1392
+ - **Agent directory**: each agent now carries an `agent.json.description`
1393
+ (one-line role blurb). On start the harness seeds
1394
+ `system_prompts/0.3-agent-directory.md` — a roster of the *other* agents
1395
+ (id + description, how to message them) — if the file is absent, so operator
1396
+ edits survive. Single-agent harnesses skip it until a second agent exists.
1397
+ - **`PI_THREAD_ID`** is exported to the pi child's env (alongside
1398
+ `PI_AGENT_ID`), so seeded scripts know the current thread without being told.
1399
+
1400
+ ### Changed
1401
+
1402
+ - **agent-messaging identity is env-sourced, not caller-supplied.** The seeded
1403
+ `agent-msg/send` CLI now fills `from_agent`/`from_thread_id` from
1404
+ `$PI_AGENT_ID`/`$PI_THREAD_ID` — the `--from-agent`/`--from-thread-id` flags
1405
+ are gone. Agents can no longer typo or spoof their own reply address.
1406
+ - **agent-messaging inbox now authenticates.** `POST /webhook/<agent>/agent-messaging/api/send`
1407
+ requires the shared `COGNISPHERE_WEBHOOK_SECRET` (generated at boot unless
1408
+ pinned via env; inherited by every agent's env) as an `X-Webhook-Secret`
1409
+ header (`401` otherwise). Sender authorisation moved to a per-inbox
1410
+ `allowMessageFrom` plugin config (default `["*"]`; a sender not listed gets
1411
+ `403`), replacing the `PluginInstanceContext.allowsMessageFrom` method.
1412
+
1413
+ ### Breaking changes
1414
+
1415
+ - `agent.json.devAgentAccess` removed. It is now ignored; the `0.2-dev-agent.md`
1416
+ hand-off fragment is included for **every** agent, and messaging permission
1417
+ to the developer agent is governed solely by the dev agent's
1418
+ `allowMessageFrom`. Agents previously set to `devAgentAccess: false` will now
1419
+ see the dev-agent fragment and (unless restricted via `allowMessageFrom`) be
1420
+ able to message the developer agent. Remove the dead field; to restrict the
1421
+ dev inbox, set `allowMessageFrom` on its `agent-messaging` config. [affects: agents/*/agent.json, agents/*/plugins/agent-messaging/config.json]
1422
+ - Add a `description` to each `agent.json` so the agent-directory roster reads
1423
+ well (optional but recommended; absent ⇒ the agent is listed id-only). [affects: agents/*/agent.json]
1424
+
1425
+ ## [0.4.4]
1426
+
1427
+ ### Added
1428
+
1429
+ - **Developer agent**: `packages/harness/src/dev-agent/` is a persona
1430
+ overlay on the base template. `cognisphere agent new <name> --dev` forks the
1431
+ base + overlay, installs the cognisphere skills (`cognisphere-upgrade`,
1432
+ `create-plugin`) into the agent's own `skills/agent/`, and enables the
1433
+ telegram plugin (the dev agent's only channel); `cognisphere init`
1434
+ pre-creates the developer agent in every home (`--dev-agent <name>`,
1435
+ default `dory`). The chosen name is baked at create time into the
1436
+ `{{DevAgentId}}`/`{{DevAgentName}}` placeholders of `0.2-dev-agent.md`
1437
+ (every fork) and `1-dev-agent.md` (the dev fork). The developer agent
1438
+ owns and modifies the home's code (agents, user plugins, the app — never
1439
+ the installed harness library) and keeps `docs/harness/` + `docs/app/`
1440
+ current.
1441
+ - **Plugin-driven thread reset**: `PluginInstanceContext.resetThread(channelId)`
1442
+ deletes the thread's queue rows, session binding, and session files (refusing
1443
+ while a batch is in-flight), so the next message starts a fresh pi session.
1444
+ The telegram plugin intercepts a `/reset` message (never delivered to the
1445
+ agent) and calls it, replying with a confirmation.
1446
+ - **App-home docs + guidelines**: `home-template/` now ships `CLAUDE.md`
1447
+ (init copies it to `AGENT.md` too) and a `docs/` tree —
1448
+ `docs/base-harness/` (shipped user reference for the harness library +
1449
+ `skills.md`; init copies the package `CHANGELOG.md` in; refreshed by the
1450
+ upgrade skill), `docs/harness/` and `docs/app/` (deployment-owned, updated
1451
+ by the developer agent after every code change).
1452
+ - Base template: new `system_prompts/0.2-dev-agent.md` fragment — a
1453
+ **Platform code changes** section telling every non-developer agent to pass
1454
+ code-change requests to `dory`.
1455
+ - **Per-agent developer-agent access**: `agent.json.devAgentAccess` (default
1456
+ true). When false, the `0.2-dev-agent.md` fragment is omitted from the
1457
+ agent's system prompt and the developer agent's agent-messaging inbox
1458
+ rejects that agent's messages (403). `agent new --dev` stamps
1459
+ `devAgent: true` so the agent-messaging plugin knows which inbox to guard.
1460
+
1461
+ ### Changed
1462
+
1463
+ - Web build fix: dropped stale `manualChunks` entries (`framer-motion`,
1464
+ `remark-breaks`) left behind after those deps were removed — they broke
1465
+ `vite build` (and therefore `prepack`) under current Rollup.
1466
+ - Internal refactors, no intended behavior change: provider-credential
1467
+ handling extracted to `src/api/credentials.ts`; the AWS/Contabo setup
1468
+ scripts now share `scripts/lib/remote-bootstrap.sh`; assorted CLI, logger,
1469
+ and web-console cleanups.
1470
+
1471
+ ### Breaking changes
1472
+
1473
+ - base template: new system_prompts/0.2-dev-agent.md fragment (route code-change requests to the developer agent; omitted when agent.json devAgentAccess=false) — copy it into each agent and replace the `{{DevAgentId}}`/`{{DevAgentName}}` placeholders with the dev agent's id/name [affects: agents/*]
1474
+ - app home: new CLAUDE.md + AGENT.md + docs/{base-harness,harness,app}/ — copy from the package's home-template/, then copy the package CHANGELOG.md to docs/base-harness/CHANGELOG.md [affects: <home root>]
1475
+ - app home: create the developer agent with `cognisphere agent new <name> --dev` (conventional name: dory), then set secrets.json → <name>.telegram.TELEGRAM_BOT_TOKEN and a model provider [affects: agents/]
1476
+
1477
+ ## [0.4.3]
1478
+
1479
+ ### Changed
1480
+
1481
+ - **pi upgraded to 0.81.1** (`@earendil-works/pi-ai` +
1482
+ `@earendil-works/pi-coding-agent`, from 0.80.6). pi 0.80.8 removed the
1483
+ `AuthStorage` export the harness used for OAuth subscription login; the
1484
+ harness now drives login/logout through pi-coding-agent's `ModelRuntime`
1485
+ (one shared lazy instance) and reads stored credentials via
1486
+ `readStoredCredential`. Behavior parity: same routes, same polled
1487
+ status shapes, tokens still in pi's own `<piAgentDir>/auth.json`.
1488
+ Internally the login interaction moved to pi-ai's `AuthInteraction`
1489
+ (`prompt`/`notify`): select cancellation now rejects the prompt, and
1490
+ per-prompt abort signals (manual-code paste raced against the callback
1491
+ server) clear the pending waiter state.
1492
+
1493
+ ## [0.4.2]
1494
+
1495
+ ### Added
1496
+
1497
+ - **Contabo deploy target**: `scripts/contabo/setup.sh` + `config.example`
1498
+ (`cntb`-driven provision: object storage + backup bucket, SSH-key secret,
1499
+ Cloud VPS, `~/.ssh/config` entry, `ufw` in the remote bootstrap since
1500
+ Contabo has no security groups). Re-runnable; the first run places a paid
1501
+ monthly order. Prints the four `BACKUP_*` values for the root `config`.
1502
+ - `scripts/aws/backup.sh` now works against any S3-compatible store: new
1503
+ `BACKUP_S3_ENDPOINT` / `BACKUP_S3_ACCESS_KEY` / `BACKUP_S3_SECRET_KEY` keys
1504
+ in the root `config.example` (blank = AWS CLI chain / IAM role, as before).
1505
+
1506
+ ### Changed
1507
+
1508
+ - `scripts/server.sh start` is now the same as `restart` (secrets + build +
1509
+ `systemctl restart`, which also starts stopped units) — previously `start`
1510
+ on a running server was a silent no-op.
1511
+ - `scripts/setup-server.sh` retires units/nginx site/backup cron left behind
1512
+ by a previous `APP_NAME` (matched by `WorkingDirectory`) before writing the
1513
+ new ones, so renaming the app can't leave two instances fighting over the
1514
+ ports.
1515
+ - The `[0.4.0]` section below gained a breaking-change entry documenting the
1516
+ session-cwd migration gap (pi session JSONLs store the absolute harness
1517
+ path) and its rewrite recipe.
1518
+
1519
+ ### Breaking changes
1520
+
1521
+ - The scaffolded lifecycle scripts changed (`server.sh`, `setup-server.sh`,
1522
+ `aws/backup.sh`, root `config.example`). Existing app homes keep their
1523
+ copies; re-copy `scripts/` and graft the new `BACKUP_S3_*` keys into
1524
+ `config` to pick up the fixes. [affects: the app home's scripts/ + config.example (not the harness data dir)]
1525
+
1526
+ ## [0.4.1]
1527
+
1528
+ ### Changed
1529
+
1530
+ - The `Timestamp` field in every `<harness-metadata>` block now includes the
1531
+ day of week (e.g. `Fri 2026-04-17 14:30:05 IST`), for both incoming
1532
+ messages and continuation nudges. Base main-agent prompt example updated.
1533
+
1534
+ ### Breaking changes
1535
+
1536
+ - Seeded base main-agent prompt changed (`Timestamp` example now shows the
1537
+ weekday). Existing agents keep their provisioned copies; re-copy or graft
1538
+ from the new seed. [affects: agents/*/system_prompts/0.1-main-agent.md]
1539
+
1540
+ ## [0.4.0]
1541
+
1542
+ ### Changed
1543
+
1544
+ - **`cognisphere init <name>` now scaffolds an app home**, not a bare harness
1545
+ data dir: a pnpm workspace with the harness data dir at `harness/`, a
1546
+ user-facing app placeholder at `app/`, lifecycle scripts under `scripts/`
1547
+ (`setup-server.sh`, `server.sh`, `build.sh`), per-platform provisioning +
1548
+ backup under `scripts/<platform>/` (`scripts/aws/setup.sh`,
1549
+ `scripts/aws/backup.sh`, `scripts/aws/config.example`), and
1550
+ `config.example` at the root. AWS is
1551
+ the only supported deploy target for now (GWS and similar later). The agent
1552
+ skills are copied into the home root's `.claude/skills/` + `.agents/skills/`
1553
+ (not into `harness/`).
1554
+ - The CLI accepts either the harness data dir or the app home as cwd
1555
+ (`./harness` is resolved automatically).
1556
+ - The scaffolded `.npmrc` no longer embeds the `_authToken` line — pnpm
1557
+ refuses env-var credentials from a committed project `.npmrc`; the token
1558
+ belongs in the user's `~/.npmrc` (`scripts/setup-server.sh` writes it on a
1559
+ deployed box).
1560
+
1561
+ ### Removed
1562
+
1563
+ - **`cognisphere up` / `logs` / `status`** (the `cognisphere@<id>` systemd
1564
+ user service). Deployment is the scaffolded `scripts/` now:
1565
+ `sudo ./scripts/setup-server.sh` once, then
1566
+ `git pull && sudo ./scripts/server.sh restart`.
1567
+ - The `cognisphere-deploy` agent skill (superseded by the scaffolded deploy
1568
+ scripts).
1569
+
1570
+ ### Breaking changes
1571
+
1572
+ - Existing harness data dirs keep working as-is (the runtime layout is
1573
+ unchanged), but deployments that used `cognisphere up` must move to the
1574
+ scripted model: create a new app home with `cognisphere init`, move the old
1575
+ harness dir's contents into its `harness/`, then `cp config.example config`,
1576
+ edit, and run `sudo ./scripts/setup-server.sh`. Remove the old
1577
+ `cognisphere@<id>` systemd user unit. [affects: the whole harness dir]
1578
+ - **Moving/renaming the harness dir breaks resumption of existing pi
1579
+ sessions.** Every pi session JSONL records the absolute working directory
1580
+ it was created in (`"cwd": …` in its header line); on resume pi validates
1581
+ that path and exits 1 if it no longer exists (`Stored session working
1582
+ directory does not exist`), so every pre-migration thread fails on its next
1583
+ message while new threads work fine. After moving the old harness contents
1584
+ to the new path, rewrite the stored cwd in place (stop the harness first):
1585
+
1586
+ ```
1587
+ grep -rl '"cwd":"<OLD_HARNESS_PATH>' harness/agents/*/sessions/ \
1588
+ | xargs sed -i 's#<OLD_HARNESS_PATH>#<NEW_HARNESS_PATH>#g'
1589
+ ```
1590
+
1591
+ where the paths are the absolute old/new locations of the harness data dir
1592
+ (e.g. `/home/ubuntu/myapp/lps-harness` → `/home/ubuntu/myapp/harness`). [affects: agents/*/sessions/**/*.jsonl]
1593
+
1594
+ ## [0.3.16]
1595
+
1596
+ ### Added
1597
+
1598
+ - Every `<harness-metadata>` block now carries a `ThreadId` common field
1599
+ (after `Channel`), so agents can pass the routing id to plugin CLIs
1600
+ (`--thread-id`) without guessing it. `ThreadId` joined the reserved
1601
+ metadata keys — plugin-contributed values under that key are dropped.
1602
+ - Base main-agent prompt documents `ThreadId`: what it is, that it equals
1603
+ `{{ThreadId}}`, and that it is distinct from plugin-side ids (Telegram
1604
+ chat id, Gmail thread id).
1605
+
1606
+ ### Changed
1607
+
1608
+ - **agent-messaging: `POST …/api/send` now rejects requests missing
1609
+ `from_agent` or `from_thread_id` (400).** The seeded `agent-msg/send` CLI
1610
+ already required both, so only direct HTTP callers are affected.
1611
+ - agent-messaging: the `[AGENT MESSAGE] from …` header prepended to the
1612
+ delivered text is gone — the text is now the sender's message verbatim.
1613
+ Sender identity travels only in metadata (`From`, `FromThread`, optional
1614
+ `Subject`); the redundant `EventType`, `to`, and `thread` metadata keys
1615
+ were dropped. The seed prompt documents the metadata fields and the
1616
+ reply recipe.
1617
+ - telegram: dropped the redundant `ChatId` metadata key (always identical
1618
+ to the common `Channel` field). Seed prompt now points at `Channel`.
1619
+ - gws: dropped the redundant `GmailThreadId` (identical to `Channel`) and
1620
+ `ReceivedAtUtc` (same instant as `ReceivedAt`) metadata keys. Seed
1621
+ prompt updated accordingly, including its stale `ThreadId` bullet.
1622
+ - `create-plugin` agent skill: new "Event & metadata conventions" section
1623
+ (reserved/common fields, PascalCase rendering, when to emit `EventType`,
1624
+ identity-in-metadata vs content-in-text, seed-prompt sync rule) and a
1625
+ pnpm ≥ 10 `allowBuilds`/`better-sqlite3` gotcha.
1626
+
1627
+ ### Breaking changes
1628
+
1629
+ - Seeded base main-agent prompt changed (`ThreadId` documented in the
1630
+ message-metadata section). Existing agents keep their provisioned
1631
+ copies; re-copy or graft from the new seed. [affects: agents/*/system_prompts/0.1-main-agent.md]
1632
+
1633
+ ## [0.3.15]
1634
+
1635
+ ### Added
1636
+
1637
+ - New `create-plugin` agent skill: guides authoring a user-scope plugin in a
1638
+ harness's `plugins/<id>/` (contract, seed layout, per-agent enable/config,
1639
+ secrets, verification), with a tested hello-plugin template.
1640
+ - The package now bundles the harness-facing agent skills
1641
+ (`cognisphere-deploy`, `cognisphere-upgrade`, `create-plugin`) under
1642
+ `skills/` (prepack), and `cognisphere init` copies them into the new
1643
+ harness dir's `.claude/skills/` and `.agents/skills/` so agents working
1644
+ inside the harness discover them.
1645
+
1646
+ ### Breaking changes
1647
+
1648
+ - Existing harness dirs predate the bundled agent skills; copy them in: `cp -R node_modules/@cognisphere-sh/cognisphere-harness/skills/. .claude/skills/ && cp -R node_modules/@cognisphere-sh/cognisphere-harness/skills/. .agents/skills/` [affects: .claude/skills/]
1649
+
1650
+ ## [0.3.14]
1651
+
1652
+ ### Fixed
1653
+
1654
+ - gws and telegram seed prompts moved from `seed/system_prompt.md` (copied
1655
+ to the agent dir root, where `assembleSystemPrompt` never reads) to
1656
+ `seed/system_prompts/plugin-<id>.md` — the layout every other plugin uses.
1657
+ Until now, neither plugin's system-prompt fragment was ever included in
1658
+ the agent's assembled prompt. The fragments load automatically on next
1659
+ agent start (seeds are re-copied every start).
1660
+ - gws helper files (`format-email.ts`, `format-email-lib.mjs`,
1661
+ `format-email-lib.d.mts`) moved from loose `seed/scripts/` into the
1662
+ namespaced `seed/scripts/gws/`; the seeded `scripts/gws/format-email` CLI
1663
+ now imports the lib from its own directory.
1664
+
1665
+ ### Breaking changes
1666
+
1667
+ - gws/telegram seed prompt renamed `system_prompt.md` → `system_prompts/plugin-<id>.md`; delete the stale, never-read `system_prompt.md` at the agent dir root [affects: agents/*/system_prompt.md]
1668
+ - gws helper lib namespaced under `scripts/gws/`; delete the stale loose copies `format-email.ts`, `format-email-lib.mjs`, `format-email-lib.d.mts` directly under `scripts/` [affects: agents/*/scripts/format-email*]
1669
+
1670
+ ## [0.3.13]
1671
+
1672
+ ### Added
1673
+
1674
+ - New seeded pi extension `extensions/bash-guard.ts`: every agent `bash`
1675
+ command now runs under `set -u`, so a `$...` inside double quotes (e.g.
1676
+ `--text "costs $100"`, where bash silently expanded `$1` to nothing and
1677
+ sent "costs 00") fails loudly with an `unbound variable` error instead of
1678
+ silently corrupting CLI arguments. On that error, a quoting hint is
1679
+ appended to the tool result so the agent self-corrects. Agents can opt
1680
+ out per-command with `set +u`.
1681
+
1682
+ ### Changed
1683
+
1684
+ - Base system prompt: bash tool guidelines now tell agents to single-quote
1685
+ literal text arguments (or use a file / quoted heredoc `<<'EOF'`), and
1686
+ document that commands run under `set -u`.
1687
+
1688
+ ### Breaking changes
1689
+
1690
+ - New seeded file `extensions/bash-guard.ts`. Copy it from the new seed
1691
+ into existing agents. [affects: agents/*/extensions/*]
1692
+ - Bash tool guidelines section of the seeded base system prompt changed
1693
+ (single-quoting rule, `set -u` note). Graft into existing agents'
1694
+ `system_prompt.md`. [affects: agents/*/system_prompt.md]
1695
+
1696
+ ## [0.3.12]
1697
+
1698
+ ### Changed
1699
+
1700
+ - `telegram/telegram-cli`: `send-message`, `edit-message`, and `send-file`
1701
+ captions now auto-convert standard markdown (`**bold**`, `*italic*`,
1702
+ `` `code` ``, ``` blocks, links, headers, bullets) to Telegram HTML when
1703
+ no `--parse-mode` is passed; markdown tables render as column-aligned
1704
+ monospace `<pre>` blocks (Telegram has no table markup). If Telegram
1705
+ rejects the generated HTML, the message is automatically resent as plain
1706
+ text, so formatting can never drop a message. Explicit `--parse-mode`
1707
+ keeps the previous raw behavior.
1708
+ - Telegram seed prompt: agents are told to write plain markdown and not
1709
+ pass `--parse-mode`; removed the stale `--parse-mode Markdown` example.
1710
+
1711
+ ### Breaking changes
1712
+
1713
+ - Seeded `scripts/telegram/telegram-cli` changed (markdown→HTML
1714
+ auto-formatting). Existing agents keep their provisioned copies; re-copy
1715
+ from the new seed to pick it up. [affects: agents/*/scripts/telegram/*]
1716
+ - Telegram section of seeded system prompts changed (markdown guidance,
1717
+ removed `--parse-mode Markdown` example). Graft into existing agents'
1718
+ `system_prompt.md`. [affects: agents/*/system_prompt.md]
1719
+
1720
+ ## [0.3.11]
1721
+
1722
+ ### Changed
1723
+
1724
+ - Every seeded script now answers `-h`/`--help`: base-agent
1725
+ `scripts/agent/{subagent,agent-browser,ddgs,markitdown}` and plugin seeds
1726
+ `scheduler/scheduler-cli` (also bare `help`), `telegram/telegram-cli`
1727
+ (also bare `help`), and `agent-msg/send`. The three thin wrappers print a
1728
+ wrapper note (what they resolve, env knobs) and then forward to the
1729
+ underlying CLI's own help; `--help` exits 0 even when the underlying
1730
+ binary isn't installed yet. `session-reader` and `gws/format-email`
1731
+ already had `--help` and are unchanged.
1732
+ - Fixed: `scheduler-cli --help` (or any invocation from outside the agent
1733
+ dir) no longer aborts before printing — the state-file init ran before
1734
+ command parsing and `set -e` killed the script when
1735
+ `plugins/scheduler/state/` didn't exist.
1736
+
1737
+ ### Breaking changes
1738
+
1739
+ - Seeded scripts under `scripts/` changed (`--help` support). Existing
1740
+ agents keep their provisioned copies; graft the edits or re-copy from the
1741
+ new seeds to pick them up. [affects: agents/*/scripts/*]
1742
+
1743
+ ## [0.3.10]
1744
+
1745
+ ### Added
1746
+
1747
+ - Optional per-provider `modelOverrides` in `.secrets/models.json`
1748
+ (`{ "<modelId>": { "contextWindow"?, "maxTokens"? } }`), layered over
1749
+ pi-ai's built-in catalog and used for context-window reporting
1750
+ (`lastContext.contextWindow` in the threads-list and usage endpoints —
1751
+ an override wins over the registry). Accepted and returned by
1752
+ `PUT/GET /api/models` (`null` per model deletes the entry). Existing
1753
+ configs without the field are unchanged.
1754
+
1755
+ ## [0.3.9]
1756
+
1757
+ ### Changed
1758
+
1759
+ - Base-agent template prompts: per-thread notes move to
1760
+ `workspace/threads/<ThreadId>/` (bare ThreadId as dir name), new
1761
+ `workspace/daily_notes/YYYY-MM-DD.md` convention, cross-thread knowledge
1762
+ relocated from `workspace/knowledge/` to agent-root `knowledge/`, and
1763
+ `session-reader` documented as directly executable (invoking it via `bash`
1764
+ fails — it's a Node script).
1765
+
1766
+ ### Breaking changes
1767
+
1768
+ - Base template `system_prompts/0-base_prompt.md` and `0.1-main-agent.md`
1769
+ changed (workspace layout + knowledge dir + session-reader invocation).
1770
+ Existing agents keep their forked copies; graft the edits if you want the
1771
+ new conventions. [affects: agents/*/system_prompts/*]
1772
+
1773
+ ## [0.3.8]
1774
+
1775
+ ### Added
1776
+
1777
+ - New built-in `agent-messaging` plugin (opt-in): inter-/intra-agent messaging.
1778
+ Each enabled agent gets an HTTP inbox at
1779
+ `/webhook/<agent>/agent-messaging/api/send` and a seeded
1780
+ `scripts/agent-msg/send` CLI; a received note wakes the target agent on the
1781
+ target thread (`silent` delivers for awareness only).
1782
+
1783
+ ### Changed
1784
+
1785
+ - Upgraded `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent` from
1786
+ `^0.78.0` to `^0.80.6` (switched the static catalog read to
1787
+ `getBuiltinModel` from `@earendil-works/pi-ai/providers/all`).
1788
+ - Plugin seed provisioning now re-asserts `chmod 755` on every file under the
1789
+ agent's `scripts/` after copying a plugin's `seed/` tree. Seeds land after
1790
+ `bootstrap.sh`'s exec-bit repair pass, so a seeded script that lost its exec
1791
+ bit would otherwise stay broken until the next restart.
1792
+
1793
+ ## [0.3.6]
1794
+
1795
+ ### Changed
1796
+
1797
+ - gws plugin: `requireAgentInTo: false` now delivers messages the agent isn't
1798
+ addressed to (Cc/Bcc/none) **in full and wakes the agent**, instead of the
1799
+ previous header-only silent delivery. Backlog mode is unaffected.
1800
+
1801
+ ## [0.3.5]
1802
+
1803
+ ### Fixed
1804
+
1805
+ - Agents were missing tools at runtime because the per-agent bootstrap silently
1806
+ failed to install its dependencies. `bootstrap.sh` now:
1807
+ - re-asserts `+x` on every shebang script under `scripts/` (a dropped exec bit
1808
+ otherwise surfaces as a bare "Permission denied" mid-task);
1809
+ - prechecks `ensurepip` and recreates an incomplete `.venv` (Ubuntu 26.04 /
1810
+ Python 3.14 ships without `python3-venv`, so `python -m venv` left a
1811
+ pip-less venv and `markitdown`/`ddgs` never installed);
1812
+ - points the npm global prefix at `~/.npm-global` so `npm install -g` of `pi`
1813
+ and `agent-browser` doesn't `EACCES` when bootstrap runs as the non-root app
1814
+ user, and downloads the Chrome build `agent-browser` drives.
1815
+ - `bootstrap/requirements.txt`: pin `markitdown` to the document/audio backends
1816
+ (`[pdf,docx,pptx,xlsx,xls,outlook,audio-transcription]`) instead of `[all]`,
1817
+ which is uninstallable on Python 3.14 (it hard-pins `youtube-transcript-api`).
1818
+ - `scripts/agent/agent-browser`: default `AGENT_BROWSER_ARGS=--no-sandbox`
1819
+ (overridable) so Chrome starts on hosts where unprivileged user namespaces are
1820
+ restricted (Ubuntu 23.10+ AppArmor default, containers, VMs).
1821
+
1822
+ ### Breaking changes
1823
+
1824
+ - Bootstrap rewritten for reliable dependency install (exec-bit repair, venv
1825
+ ensurepip precheck + recreate, user-writable npm prefix, agent-browser Chrome
1826
+ download). [affects: agents/*/bootstrap/bootstrap.sh]
1827
+ - `markitdown` extras pinned instead of `[all]` for Python 3.14 compatibility.
1828
+ [affects: agents/*/bootstrap/requirements.txt]
1829
+ - `agent-browser` wrapper defaults to `--no-sandbox`.
1830
+ [affects: agents/*/scripts/agent/agent-browser]
1831
+
1832
+ ## [0.3.4]
1833
+
1834
+ ### Added
1835
+
1836
+ - gws plugin: new `requireAgentInTo` config flag (default `true`, the previous
1837
+ behavior). When `false`, the latest message of a matching thread is delivered
1838
+ even when the agent's address is not in its `To` header — silently (no wake)
1839
+ unless the agent is in `To`. Ignored in backlog mode.
1840
+ - gws seeded CLI `scripts/gws/format-email`: new `--strip-quotes` flag drops
1841
+ quoted reply history from a body (most clients quote the whole conversation
1842
+ below each reply), printing only the message's own text.
1843
+ - gws seeded CLI: new `--list` mode accepts a Gmail *Thread* JSON (from
1844
+ `gws gmail users threads get`, `format: "metadata"` suffices) and prints
1845
+ per-message metadata (id, from, date, snippet) so agents can skim a thread
1846
+ cheaply and then fetch only the messages they need. The seeded
1847
+ `system_prompt.md` documents the explore-then-fetch workflow.
1848
+
1849
+ ### Changed
1850
+
1851
+ - gws plugin: the ingestion filter no longer re-checks the `UNREAD` label on a
1852
+ thread's latest message — unread filtering is delegated entirely to the
1853
+ configured `gmailQuery` (default `is:unread in:inbox`).
1854
+ - gws plugin: Gmail message decoding (body extraction, quote stripping,
1855
+ attachment fetch, timestamp formatting) is deduplicated into a single shared
1856
+ module, `seed/scripts/format-email-lib.mjs`, imported by both the plugin
1857
+ runtime and the seeded `scripts/gws/format-email` CLI (which previously
1858
+ carried its own copy of the logic).
1859
+
1860
+ ### Fixed
1861
+
1862
+ - gws seeded CLI: the documented `--timezone` flag was parsed but never used —
1863
+ the header block now includes the `TimeStamp:` line, matching the shape of
1864
+ `email_received` notifications as documented.
1865
+
1866
+ ## [0.3.3]
1867
+
1868
+ ### Fixed
1869
+
1870
+ - Sub-agents could receive a single task brief as dozens of phantom one-word
1871
+ messages. The `subagent` wrapper passed the brief as a positional argv entry,
1872
+ and `pi -p` treats every positional as a separate user turn. A literal
1873
+ unescaped quote inside the brief (e.g. a pasted email body like
1874
+ `Message: "Hi Chris, ..."`) let the shell word-split the single intended arg
1875
+ into many argv entries, each replayed as its own message. The wrapper now
1876
+ routes the brief to `pi` on **stdin** (`pi -p` reads its prompt from stdin
1877
+ when no positional message is given), so quoting inside the brief can no
1878
+ longer fan out into phantom turns. Flags still pass through argv verbatim and
1879
+ the caller interface is unchanged (`subagent "<brief>" --flags`).
1880
+
1881
+ ### Changed
1882
+
1883
+ - Base prompt now tells agents to keep `workspace/` for what must persist:
1884
+ write intermediate/throwaway files under `/tmp` (or delete them), and don't
1885
+ copy plugin inbox input files into `workspace/` unless they genuinely need to
1886
+ outlive the inbox.
1887
+
1888
+ ### Breaking changes
1889
+
1890
+ - `subagent` wrapper now passes the task brief to `pi` on stdin instead of as a
1891
+ positional argument. [affects: agents/*/scripts/agent/subagent]
1892
+ - Base prompt adds workspace-hygiene guidance (intermediate files to `/tmp`;
1893
+ don't copy inbox inputs into `workspace/` unless persisting).
1894
+ [affects: agents/*/system_prompts/0-base_prompt.md]
1895
+
1896
+ ## [0.3.2]
1897
+
1898
+ ### Fixed
1899
+
1900
+ - Sub-agents lost their system prompt on resume (`-c`/`--continue`). The
1901
+ `subagent` wrapper skipped re-injecting the base + sub-agent-role prompt on
1902
+ continue, assuming pi had persisted it — but pi never writes the system
1903
+ prompt to the session JSONL, so resumed sub-agents fell back to pi's default
1904
+ identity. The wrapper now concatenates `0-base_prompt.md` +
1905
+ `sub-agent-prompt.md` into a single `--system-prompt` value (replace, not
1906
+ `--append-system-prompt`, so pi's default doesn't leak in) and sets it on
1907
+ every call including `-c`. The task-specific brief now goes in the **message**
1908
+ (positional arg) instead of `--system-prompt`, so it lives in session history
1909
+ and survives re-invocation. The main-agent prompt was updated to match.
1910
+
1911
+ ### Breaking changes
1912
+
1913
+ - `subagent` wrapper rewrites system-prompt handling: concatenates base +
1914
+ sub-agent role into one `--system-prompt`, set on every call (incl. `-c`).
1915
+ [affects: agents/*/scripts/agent/subagent]
1916
+ - Main-agent prompt now instructs putting the sub-agent task brief in the
1917
+ message, never passing `--system-prompt`.
1918
+ [affects: agents/*/system_prompts/0.1-main-agent.md]
1919
+
1920
+ ## [0.3.1]
1921
+
1922
+ ### Added
1923
+
1924
+ - On first start the server prompts for an admin username/password when
1925
+ `.secrets/users.json` is missing or still holds the `admin/changeme`
1926
+ placeholder and stdin is a TTY, writing the file `0600`. Under systemd (no
1927
+ TTY) it logs a warning and falls back to the placeholder so boot still
1928
+ succeeds. (`ensureCredentials` in `api/auth.ts`, wired in `core/main.ts`.)
1929
+
1930
+ ## [0.3.0]
1931
+
1932
+ ### Changed
1933
+
1934
+ - **Base-agent system prompt split into three role-scoped parts** to remove the
1935
+ duplication that arose when sub-agents were handed a hand-copied harness
1936
+ prompt:
1937
+ - `0-base_prompt.md` is now the **shared base** — the operating manual (tools,
1938
+ files, workspace, sessions, web, browser) common to every agent. It no
1939
+ longer carries agent identity or main-agent-only framing.
1940
+ - `0.1-main-agent.md` (new) holds the **main-agent-only** role: threads,
1941
+ plugins, message metadata, the communication model, and the guide on how to
1942
+ spawn sub-agents (merged in from the old `0.1-subagents.md`).
1943
+ - `scripts/agent/sub-agent-prompt.md` (new) holds the **sub-agent-only** role
1944
+ ("stdout is your return value", include all relevant info, ask when the
1945
+ brief is ambiguous, stay scoped). It lives outside `system_prompts/` so it
1946
+ never leaks into the main agent's concatenated prompt.
1947
+ - The `scripts/agent/subagent` wrapper now appends the base prompt + sub-agent
1948
+ prompt to every fresh sub-agent via `--append-system-prompt` (skipped on
1949
+ `-c`/`--continue`). Sub-agents get the same harness context as the main agent
1950
+ on top of the parent's task brief, so the parent's `--system-prompt` only
1951
+ needs to carry the task-specific brief.
1952
+ - Agent identity (`AgentId`, `AgentName`) moved out of the base prompt into the
1953
+ hand-written `1-agent.md` persona. The only remaining sed-baked `{{var}}`
1954
+ (`Timezone`) is now baked into `0.1-main-agent.md`.
1955
+
1956
+ ### Breaking changes
1957
+
1958
+ - Base prompt repurposed and identity removed: `0-base_prompt.md` is now the
1959
+ shared base context only; agent identity moves to the `1-agent.md` persona.
1960
+ [affects: agents/*/system_prompts/0-base_prompt.md, agents/*/system_prompts/1-agent.md]
1961
+ - New main-agent-only prompt; `0.1-subagents.md` removed (its content merged in).
1962
+ [affects: agents/*/system_prompts/0.1-main-agent.md, agents/*/system_prompts/0.1-subagents.md]
1963
+ - New sub-agent-only role prompt, appended to sub-agents by the wrapper.
1964
+ [affects: agents/*/scripts/agent/sub-agent-prompt.md]
1965
+ - `subagent` wrapper updated to append the base + sub-agent prompts on fresh spawns.
1966
+ [affects: agents/*/scripts/agent/subagent]
1967
+
1968
+ ## [0.2.1]
1969
+
1970
+ ### Fixed
1971
+
1972
+ - Core plugins (`admin`, `scheduler`) are now always started on every agent,
1973
+ unioned with any user-installed plugins — previously a freshly scaffolded
1974
+ agent loaded no plugins at all (the operator-chat `admin` channel included),
1975
+ since the base-agent template ships no `plugins/` dir. Single source of truth
1976
+ is `CORE_PLUGIN_IDS` in `core/plugin-registry.ts`.
1977
+ - `bootstrap.sh` now runs automatically on every agent start (`runBootstrap`
1978
+ in `startAgent`, before the runner spawns) — provisions system deps + the
1979
+ per-agent `.venv` so the runner can activate it. Idempotent, awaited, and
1980
+ failure-tolerant (logged, never sinks the agent); no-op when the agent ships
1981
+ no `bootstrap/bootstrap.sh`. Cost: first boot blocks on `pip install`.
1982
+ - Plugin `seed/` provisioning: on plugin start, a plugin's `seed/` tree is
1983
+ recursively copied into the agent dir (mirrors the agent layout —
1984
+ `system_prompts/plugin-<id>.md`, `scripts/<id>/…`), so the agent actually
1985
+ receives each plugin's system-prompt fragment and helper CLIs (e.g. the
1986
+ scheduler's `scheduler-cli`). Previously the seed content was never copied,
1987
+ so those prompts/scripts never reached the agent.
1988
+ - `cognisphere init` now pre-approves `better-sqlite3` in the scaffolded
1989
+ `package.json` (`pnpm.onlyBuiltDependencies`), so `pnpm install` builds its
1990
+ native addon instead of silently skipping it (which crashed agent boot with
1991
+ "Could not locate the bindings file").
1992
+
1993
+ ## [0.2.0]
1994
+
1995
+ ### Added
1996
+
1997
+ - **`cognisphere` CLI** (`packages/harness/src/cli/`, bin shim `bin/cognisphere.mjs`):
1998
+ `init`, `agent new`, `plugin add`, `dev`, `serve`, `up`/`logs`/`status`
1999
+ (systemd user services), and `upgrade`. `dev` runs the backend (watch) and,
2000
+ in the monorepo, the Vite dev server (HMR) together (`--port`/`--web-port`/
2001
+ `--no-web`); `serve` takes `--port` and `--headless` (mount no web UI —
2002
+ backend-only deploy, via `COGNISPHERE_HEADLESS`). See
2003
+ [CLI reference](docs/low-level/cli.md#cli).
2004
+ - **Publishable package.** `@cognisphere-sh/cognisphere-harness` ships a `bin`, a
2005
+ `files` allowlist, `publishConfig` (GitHub Packages), and a `prepack` step that
2006
+ bundles the built web UI (`dist-web/`) and the root `CHANGELOG.md` into the
2007
+ package. `tsx` is now a runtime dependency.
2008
+ - **`harness.json.version`** — the data/migration version stamp, written by
2009
+ `cognisphere init` and surfaced over `GET /api/harness`. Additive and optional;
2010
+ existing harnesses read it as `""`.
2011
+ - **Upgrade & deploy skills** (`.claude/skills/cognisphere-{upgrade,deploy}/`).
2012
+
2013
+ ### Changed
2014
+
2015
+ - Repository restructured into a pnpm workspace with two packages:
2016
+ `packages/harness` (`@cognisphere-sh/cognisphere-harness` — backend; all
2017
+ TypeScript source under `src/` (`core/`, `api/`, `cli/`, `plugins/`,
2018
+ `base-agent/`), with `bin/` + `scripts/` at the package root) and
2019
+ `packages/web` (the React UI). Tooling moved to pnpm; `pnpm check` runs
2020
+ typecheck + lint across both packages. No on-disk harness artifacts are
2021
+ affected — this is a source-layout change only.
2022
+
2023
+ ## [0.1.0]
2024
+
2025
+ - Initial version.