johns-harness 2026.9.23 → 2026.9.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +6 -5
- package/dist/compact-B247y5Qt.js +1 -0
- package/dist/pi-embedded-C6ITuRXf.js +1 -0
- package/dist/pi-embedded-DoQsYfIY.js +1 -0
- package/dist/plugin-sdk/dispatch-BP0viZiL.js +1 -0
- package/dist/plugin-sdk/dispatch-CQsjmw7g.js +1 -0
- package/dist/plugin-sdk/dispatch-Cerq29sy.js +1 -0
- package/dist/plugin-sdk/dispatch-Cndjtt0g.js +1 -0
- package/dist/plugin-sdk/dispatch-UogiJYul.js +1 -0
- package/dist/plugin-sdk/reply-DbZnH8-h.js +1 -0
- package/dist/reply-C5LKjXcC.js +1 -0
- package/docs/MR-MEMORY-DOCTOR-SAFETY.md +31 -0
- package/docs/PATCHES.md +75 -3
- package/package.json +2 -1
- package/scripts/check-packed-artifact.mjs +148 -0
- package/skills/activity-logging/SKILL.md +96 -0
- package/skills/arch-viz/SKILL.md +94 -0
- package/skills/code-ops/SKILL.md +121 -0
- package/skills/cold-outreach/SKILL.md +99 -0
- package/skills/content-story/SKILL.md +77 -0
- package/skills/dashboard/SKILL.md +129 -0
- package/skills/gcp-logs/SKILL.md +83 -0
- package/skills/outlook/SKILL.md +139 -0
- package/skills/plan-archival/SKILL.md +84 -0
- package/skills/todos/SKILL.md +111 -0
- package/skills/web-research/SKILL.md +153 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026.9.25
|
|
4
|
+
|
|
5
|
+
- Family 72: eleven generic skills from the author's workspace ship as bundled skills (`code-ops`, `web-research`, `plan-archival`, `todos`, `dashboard`, `arch-viz`, `content-story`, `cold-outreach`, `gcp-logs`, `activity-logging`, `outlook`), converted to fully generic wording first: no owner names, paths, repos, accounts, or products. They load by description match like every other bundled skill (none is always-on), workspace copies override them, and `enabled: false` and `allowBundled` still apply. `RULES.md` lists all of them.
|
|
6
|
+
- The Family 71 packed-artifact gate now also proves all eleven bundled generic skills are inside every tarball, and verifier checks 72.1 through 72.5 enforce presence, frontmatter, the generic wording contract, and no em dashes.
|
|
7
|
+
- Roll back with `npm i -g johns-harness@2026.9.24`.
|
|
8
|
+
|
|
9
|
+
## 2026.9.24
|
|
10
|
+
|
|
11
|
+
- Family 71: native-first Jiti plugin loading (Family 68) is now standard on `latest`. The `extended` dist-tag moves to this same version, so both lines converge at 2026.9.24. Node loads already-built JavaScript plugin code natively first and keeps Babel only for TypeScript plugin entries; `JITI_TRY_NATIVE` is no longer needed and is harmless if set.
|
|
12
|
+
- New packed-artifact gate `scripts/check-packed-artifact.mjs` inspects the real `npm pack` output (and registry tarballs) and fails closed unless all ten plugin-loader copies carry the Family 68 option. Releases 2026.9.22 and 2026.9.23 were cut from the pre-68 base, so their tarballs lacked it while main carried it; this gate makes that impossible to repeat.
|
|
13
|
+
- Roll back with `npm i -g johns-harness@2026.9.23`.
|
|
14
|
+
|
|
3
15
|
## 2026.9.23
|
|
4
16
|
|
|
5
17
|
- Family 70: ship the `orchestrator` skill as a bundled, always-eligible skill so every harness install loads the delegation and briefing protocol implicitly (pass the user's words through when they are clear, expand when they are vague, keep briefings brief). Workspace overrides, `enabled: false` and `allowBundled` still apply. `RULES.md` points at the bundled copy.
|
|
@@ -8,6 +20,11 @@
|
|
|
8
20
|
|
|
9
21
|
- Family 69: enforce the latest DeepSeek Flash/Pro, Muse and Gemini Lite alias targets across all 14 shipped copies; document `/model deepseek` and retain Family 68 on the separate `extended` release line.
|
|
10
22
|
|
|
23
|
+
## 2026.9.21-extended.1
|
|
24
|
+
|
|
25
|
+
- Family 68: bake `tryNative: true` into every plugin-loader `createJiti` options object so Node loads already-built JavaScript natively first and keeps Babel only as fallback for TypeScript plugin entries. This is the Path-1 1 GiB cold-start fix; Telegram, WhatsApp and memory stay enabled.
|
|
26
|
+
- Published on the `extended` dist-tag only. `latest` remains `2026.9.20`.
|
|
27
|
+
|
|
11
28
|
## 2026.9.20
|
|
12
29
|
|
|
13
30
|
- Family 67: native DeepSeek V4.1 Flash/V4 Pro catalog, environment auth, aliases, model-specific effort mapping and tool/reasoning replay through the supported Chat Completions transport.
|
package/README.md
CHANGED
|
@@ -85,8 +85,8 @@ node johnness.mjs --help
|
|
|
85
85
|
### Verify
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
npm test #
|
|
89
|
-
bash scripts/verify-patches.sh #
|
|
88
|
+
npm test # 914 tests against the installed dependency tree
|
|
89
|
+
bash scripts/verify-patches.sh # 458 checks across every patch family
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
## Launch a swarm with one command
|
|
@@ -132,7 +132,7 @@ Coding agents today run as isolated processes. Two agents on the same repository
|
|
|
132
132
|
- **Memory built for production.** Tiered recall that traces from consolidated reflections down to the verbatim record, surviving compaction and shared across the swarm. Installed and enabled by default.
|
|
133
133
|
- **Production authority per commit.** Promotion is granted to an exact SHA, never to a branch name, so one worker's authorization never covers another worker's commits.
|
|
134
134
|
- **An append-only action log.** Agents record every consequential action to `ACTION_LOG.md` and read it before acting.
|
|
135
|
-
- **A fixed runtime surface.** The core does not grow on a schedule. New mechanisms enter only to solve a demonstrated production failure, one narrow, tested, reversible patch at a time:
|
|
135
|
+
- **A fixed runtime surface.** The core does not grow on a schedule. New mechanisms enter only to solve a demonstrated production failure, one narrow, tested, reversible patch at a time: 72 patch families, each with a regression test and a rollback path.
|
|
136
136
|
- **Reliability with a definition.** Bounded retries, explicit failure states, exact-once continuation, context-pressure recovery, durable delivery, and supervised gateway recovery.
|
|
137
137
|
- **Coding first, phone optional.** Direct the work at a high level from a chat channel while agents plan, implement, test, coordinate, and stage releases unattended.
|
|
138
138
|
- **Local voice.** Optional native Whisper transcription of inbound audio, entirely on your machine. Off by default. [Setup](docs/NATIVE-WHISPER-MUSE.md).
|
|
@@ -199,7 +199,7 @@ The log is a [`RULES.md`](RULES.md) workspace convention enforced through the ac
|
|
|
199
199
|
|
|
200
200
|
## Patch families
|
|
201
201
|
|
|
202
|
-
The runtime carries
|
|
202
|
+
The runtime carries 72 patch families plus the 65.1 safe-update amendment. Each is a production fix applied at the source with a regression test, a durable patch marker, and a rollback path. A verifier runs 458 checks against the package tree and installed dependencies, and 914 tests run against the installed dependency tree.
|
|
203
203
|
|
|
204
204
|
Every family follows the same six steps: reproduce the failure, trace the exact runtime path, make the smallest source-level change that restores the invariant, add a regression test and a patch marker, run the verifier, and retain rollback artifacts. The full index: [`docs/PATCHES.md`](docs/PATCHES.md).
|
|
205
205
|
|
|
@@ -213,11 +213,12 @@ Every family follows the same six steps: reproduce the failure, trace the exact
|
|
|
213
213
|
| `--dev` | Dev profile under `~/.johnness-dev` with its own gateway port and shifted derived ports |
|
|
214
214
|
| Rules | [`RULES.md`](RULES.md) ships 19 operating-policy sections injected on every call. Fill in the placeholders; keep long procedures in skills. |
|
|
215
215
|
| Orchestrator skill | Bundled and loaded implicitly on every install. Decide whether to pass the user's words through or expand them, then keep the briefing brief. Override with a workspace `skills/orchestrator/SKILL.md`. |
|
|
216
|
+
| Bundled generic skills | Eleven generic skills ship in `skills/` and load by description match: `code-ops`, `web-research`, `plan-archival`, `todos`, `dashboard`, `arch-viz`, `content-story`, `cold-outreach`, `gcp-logs`, `activity-logging`, `outlook`. Workspace copies override; `enabled: false` and `allowBundled` still apply. |
|
|
216
217
|
|
|
217
218
|
## Documentation
|
|
218
219
|
|
|
219
220
|
- [`docs/index.md`](docs/index.md): runtime docs, from gateway and channels to plugins, nodes, and CLI reference.
|
|
220
|
-
- [`docs/PATCHES.md`](docs/PATCHES.md): the
|
|
221
|
+
- [`docs/PATCHES.md`](docs/PATCHES.md): the 72 patch families, one record each.
|
|
221
222
|
- [`docs/NATIVE-WHISPER-MUSE.md`](docs/NATIVE-WHISPER-MUSE.md): local Whisper transcription setup.
|
|
222
223
|
- [`RULES.md`](RULES.md): the default operating rules, including Rule Zero on production authorization.
|
|
223
224
|
|
package/dist/compact-B247y5Qt.js
CHANGED
|
@@ -92823,6 +92823,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
92823
92823
|
...resolvePluginSdkScopedAliasMap()
|
|
92824
92824
|
};
|
|
92825
92825
|
jitiLoader = createJiti(import.meta.url, {
|
|
92826
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
92826
92827
|
interopDefault: true,
|
|
92827
92828
|
extensions: [
|
|
92828
92829
|
".ts",
|
|
@@ -91543,6 +91543,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
91543
91543
|
...resolvePluginSdkScopedAliasMap()
|
|
91544
91544
|
};
|
|
91545
91545
|
jitiLoader = createJiti(import.meta.url, {
|
|
91546
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
91546
91547
|
interopDefault: true,
|
|
91547
91548
|
extensions: [
|
|
91548
91549
|
".ts",
|
|
@@ -91533,6 +91533,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
91533
91533
|
...resolvePluginSdkScopedAliasMap()
|
|
91534
91534
|
};
|
|
91535
91535
|
jitiLoader = createJiti(import.meta.url, {
|
|
91536
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
91536
91537
|
interopDefault: true,
|
|
91537
91538
|
extensions: [
|
|
91538
91539
|
".ts",
|
|
@@ -59018,6 +59018,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
59018
59018
|
...resolvePluginSdkScopedAliasMap()
|
|
59019
59019
|
};
|
|
59020
59020
|
jitiLoader = createJiti(import.meta.url, {
|
|
59021
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
59021
59022
|
interopDefault: true,
|
|
59022
59023
|
extensions: [
|
|
59023
59024
|
".ts",
|
|
@@ -59018,6 +59018,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
59018
59018
|
...resolvePluginSdkScopedAliasMap()
|
|
59019
59019
|
};
|
|
59020
59020
|
jitiLoader = createJiti(import.meta.url, {
|
|
59021
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
59021
59022
|
interopDefault: true,
|
|
59022
59023
|
extensions: [
|
|
59023
59024
|
".ts",
|
|
@@ -59420,6 +59420,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
59420
59420
|
...resolvePluginSdkScopedAliasMap()
|
|
59421
59421
|
};
|
|
59422
59422
|
jitiLoader = createJiti(import.meta.url, {
|
|
59423
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
59423
59424
|
interopDefault: true,
|
|
59424
59425
|
extensions: [
|
|
59425
59426
|
".ts",
|
|
@@ -59059,6 +59059,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
59059
59059
|
...resolvePluginSdkScopedAliasMap()
|
|
59060
59060
|
};
|
|
59061
59061
|
jitiLoader = createJiti(import.meta.url, {
|
|
59062
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
59062
59063
|
interopDefault: true,
|
|
59063
59064
|
extensions: [
|
|
59064
59065
|
".ts",
|
|
@@ -59018,6 +59018,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
59018
59018
|
...resolvePluginSdkScopedAliasMap()
|
|
59019
59019
|
};
|
|
59020
59020
|
jitiLoader = createJiti(import.meta.url, {
|
|
59021
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
59021
59022
|
interopDefault: true,
|
|
59022
59023
|
extensions: [
|
|
59023
59024
|
".ts",
|
|
@@ -63115,6 +63115,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
63115
63115
|
...resolvePluginSdkScopedAliasMap()
|
|
63116
63116
|
};
|
|
63117
63117
|
jitiLoader = createJiti(import.meta.url, {
|
|
63118
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
63118
63119
|
interopDefault: true,
|
|
63119
63120
|
extensions: [
|
|
63120
63121
|
".ts",
|
package/dist/reply-C5LKjXcC.js
CHANGED
|
@@ -55779,6 +55779,7 @@ function loadJohnnessPlugins(options = {}) {
|
|
|
55779
55779
|
...resolvePluginSdkScopedAliasMap()
|
|
55780
55780
|
};
|
|
55781
55781
|
jitiLoader = createJiti(import.meta.url, {
|
|
55782
|
+
tryNative: true, // JOHNNESS_PATCH_JITI_TRY_NATIVE_68
|
|
55782
55783
|
interopDefault: true,
|
|
55783
55784
|
extensions: [
|
|
55784
55785
|
".ts",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# MemoryRouter doctor reconciliation safety
|
|
2
|
+
|
|
3
|
+
Verified on John's Harness 2026.9.23 for the mr-memory 3.13.3 read-only boot change.
|
|
4
|
+
|
|
5
|
+
## Finding: no runtime patch needed
|
|
6
|
+
|
|
7
|
+
`doctor --fix` does **not** prune or disable `plugins.entries.mr-memory` in the current harness. Removing mr-memory's old boot-time config rewrite does not remove a required harness safeguard.
|
|
8
|
+
|
|
9
|
+
- Both `dist/doctor-config-flow-*.js` variants run `loadAndMaybeMigrateDoctorConfig` and `stripUnknownConfigKeys` against the host schema. The plugin entries schema is a string-keyed record, and a plugin's `config` is itself an open record. An entry is not an unknown schema property merely because its ID is not a built-in channel.
|
|
10
|
+
- Plugin-aware validation obtains IDs and schemas from the manifest registry. The harness ships `extensions/mr-memory/johnness.plugin.json`, so mr-memory is known even without a separately installed external copy.
|
|
11
|
+
- `validateConfigObjectWithPlugins` treats an unavailable plugin entry as a warning, not an instruction to delete its configuration. It validates an installed plugin's own config using its manifest.
|
|
12
|
+
- `applyPluginAutoEnable` can enable eligible plugins; it does not disable mr-memory. Explicitly disabled entries remain disabled. Doctor should not override an intentional user opt-out.
|
|
13
|
+
- Patch 59's mr-memory installation adapter remains useful for native namespace adoption, but doctor safety does not depend on plugin entrypoint execution or that plugin writing config at startup.
|
|
14
|
+
|
|
15
|
+
## Regression evidence
|
|
16
|
+
|
|
17
|
+
`node --test tests/mr-memory-doctor.test.mjs`
|
|
18
|
+
|
|
19
|
+
Eight isolated tests execute both real bundled doctor config flows, then the real host config writer and validator, twice each. They cover enabled and intentionally disabled memory, with and without an installed external mr-memory manifest. The external plugin entrypoint deliberately throws if loaded: no test can pass because boot-time self-healing put a removed entry back.
|
|
20
|
+
|
|
21
|
+
Each fixture includes an invalid top-level key, forcing the actual `--fix` unknown-key reconciliation path. Tests assert that this key is removed while mr-memory's complete configuration (fixture key, per-agent keys, density, endpoint), enabled state, allowlist and memory slot survive. Native search stays disabled, native memory flush stays enabled, unrelated plugin entries survive, the persisted config validates, and the second doctor pass is idempotent.
|
|
22
|
+
|
|
23
|
+
Child processes have isolated HOME/state/config/temp paths. Node's permission model grants filesystem writes only inside the disposable fixture directory and denies child processes. No live gateway, service, fleet config, or real credentials are used.
|
|
24
|
+
|
|
25
|
+
Additional release-artifact verification:
|
|
26
|
+
|
|
27
|
+
- The two doctor entrypoint bundles, two config-flow bundles, and two config/validation bundles in the published `johns-harness@2026.9.23` tarball are byte-identical to the tested checkout.
|
|
28
|
+
- A fresh Docker container installed the published harness tarball, then the exact candidate `mr-memory@3.13.3` tarball through `johnness plugins install`. With a fixture key and an invalid top-level property, two complete `johnness doctor --fix --non-interactive` runs preserved the full mr-memory entry and memory slot, kept native search disabled and memory flush enabled, and removed only the invalid property. No `.openclaw/openclaw.json` was created. The run ended `HARNESS_DOCTOR_CLI_MEMORY_PRESERVED`.
|
|
29
|
+
- Full checkout test suite: **900 pass, 0 fail** (including the eight new tests). Patch verifier: **440 pass, 0 fail**.
|
|
30
|
+
|
|
31
|
+
Because no real gap was found, there is no new patch family and no 2026.9.24 runtime release for this investigation. `latest` and `extended` are unchanged.
|
package/docs/PATCHES.md
CHANGED
|
@@ -17,7 +17,7 @@ they predate ~2026-06-06).
|
|
|
17
17
|
|
|
18
18
|
## Index
|
|
19
19
|
|
|
20
|
-
Family 01 is retired. Families 02 through 41, 43 through
|
|
20
|
+
Family 01 is retired. Families 02 through 41, 43 through 72, including the 65.1 amendment, are live on `main`; the `latest` and `extended` release lines converged at 2026.9.24. Family 42 is omitted; native Codex OAuth ownership is Family 58.
|
|
21
21
|
|
|
22
22
|
1. **01, announce queue TTL, retired:** Removed the five-minute age filter that could discard delayed sub-agent completion announcements. [Details](#01--announce-ttl-retired-2026-07-30)
|
|
23
23
|
2. **02, failover rotation:** Returns model selection to the highest-priority profile after its cooldown ends. [Details](#02--failover-rotation-undocumented)
|
|
@@ -95,6 +95,10 @@ Family 01 is retired. Families 02 through 41, 43 through 67, 69 and 70, includin
|
|
|
95
95
|
|
|
96
96
|
70. **70, bundled orchestrator skill:** The delegation and briefing protocol ships as an always-eligible bundled skill; every install loads it implicitly and a workspace copy still overrides it. [Details](#family-70-bundled-orchestrator-skill)
|
|
97
97
|
|
|
98
|
+
71. **71, native-first Jiti standard on latest:** The Family 68 native-first loader option ships on every artifact, the `latest` and `extended` lines converge, and a packed-artifact gate proves the tarball carries it. [Details](#family-71-native-first-jiti-standard-on-latest)
|
|
99
|
+
|
|
100
|
+
72. **72, bundled generic skills:** Eleven workspace skills (code operations, research, todos, dashboard, planning, content, outreach, logs, and more) ship as generic bundled skills that load by description match, with no owner names or personal paths. [Details](#family-72-bundled-generic-skills)
|
|
101
|
+
|
|
98
102
|
---
|
|
99
103
|
|
|
100
104
|
## 01 - announce-ttl (RETIRED 2026-07-30)
|
|
@@ -2567,7 +2571,21 @@ The 65.1 updater budgets fresh installs from the old dependency size. A very ful
|
|
|
2567
2571
|
|
|
2568
2572
|
## Family 67: native DeepSeek and current provider catalog
|
|
2569
2573
|
|
|
2570
|
-
Verified September 13, 2026 against official provider catalogs and harmless live API probes. Adds DeepSeek V4.1 Flash/V4 Pro via the existing supported Chat Completions adapter, Gemini Flash-Lite, current prices and Claude xhigh mappings. Preserves all legacy IDs, configured selection, deliberate context budgets and provider-default omission. [Full source/evidence/limits](PROVIDER-CATALOG.md). Canonical adapters live in the version-checked pi-ai overlay; `patch-provider-catalog.py --check` validates exact registry/auth/alias/adapter snapshots without network or secrets. Historical reconstruction retains exact byte comparisons through the Family 67 helper.
|
|
2574
|
+
Verified September 13, 2026 against official provider catalogs and harmless live API probes. Adds DeepSeek V4.1 Flash/V4 Pro via the existing supported Chat Completions adapter, Gemini Flash-Lite, current prices and Claude xhigh mappings. Preserves all legacy IDs, configured selection, deliberate context budgets and provider-default omission. [Full source/evidence/limits](PROVIDER-CATALOG.md). Canonical adapters live in the version-checked pi-ai overlay; `patch-provider-catalog.py --check` validates exact registry/auth/alias/adapter snapshots without network or secrets. Historical reconstruction retains exact byte comparisons through the Family 67 helper. Family 68 later adds one native-Jiti options line in the ten loader copies; Family 67 hash checks compare the Family-67 surface (that line stripped) so the reviewed catalog snapshot stays fail-closed.
|
|
2575
|
+
|
|
2576
|
+
## 68 Native-first Jiti plugin load
|
|
2577
|
+
|
|
2578
|
+
**Marker:** `JOHNNESS_PATCH_JITI_TRY_NATIVE_68`
|
|
2579
|
+
**Release:** `johns-harness@2026.9.21-extended.1` (`extended` dist-tag; `latest` stays `2026.9.20`)
|
|
2580
|
+
**Patcher:** `scripts/patch-jiti-try-native.py [root] [--check] [--present-only]`. Plans all ten plugin-loader copies before writing, rejects missing/ambiguous `createJiti` anchors, and is byte-idempotent.
|
|
2581
|
+
|
|
2582
|
+
Jiti 2.x defaults `tryNative` on only for Bun. On Node the plugin loader Babel-transforms already-built JavaScript, including Telegram's pull of `dist/plugin-sdk/dispatch-Cerq29sy.js` (~3.84M chars). Family 68 bakes `tryNative: true` into every live `createJiti(import.meta.url, { interopDefault, extensions, alias })` options object used by the plugin loader. Existing options stay. Babel fallback remains for TypeScript plugin entries. Telegram, WhatsApp, and memory are not disabled.
|
|
2583
|
+
|
|
2584
|
+
Isolated 1 GiB lab (env-only predecessor): three cold VM/cache starts plus one warm restart, peak RSS 312–327 MiB, health plus mock tool turn passed. This family makes that behavior the shipped default instead of an operator env flag.
|
|
2585
|
+
|
|
2586
|
+
**Tests:** `tests/jiti-try-native.test.mjs` covers presence of the option in all ten copies, `--check` cleanliness, idempotent replay, and fail-closed preflight. Historical family reconstructions apply Family 68 after Family 67 so byte-exact comparisons keep working. Verifier checks the marker, `tryNative: true`, and exact read-only replay.
|
|
2587
|
+
|
|
2588
|
+
Roll back the package with `npm i -g johns-harness@2026.9.20`. This extended release does not move `latest`.
|
|
2571
2589
|
|
|
2572
2590
|
## Family 69: DeepSeek alias contract
|
|
2573
2591
|
|
|
@@ -2577,7 +2595,7 @@ Release: `johns-harness@2026.9.22` (`latest`). Extends the release gate, not the
|
|
|
2577
2595
|
All 14 alias copies must match these exact targets, agree with each other, and resolve every shipped alias in the catalog.
|
|
2578
2596
|
Verifier checks 69.1 and 69.2 enforce the contract and exactly one DeepSeek Flash alias per copy.
|
|
2579
2597
|
Future catalog releases must move the matching contract targets; user-configured aliases still win.
|
|
2580
|
-
Family 68 remains on the `extended` release line and is not included in this `latest` artifact.
|
|
2598
|
+
Family 68 remains on the `extended` release line and is not included in this `latest` artifact. (Superseded by Family 71: from `2026.9.24` Family 68 ships on `latest` as well.)
|
|
2581
2599
|
|
|
2582
2600
|
## Family 70: bundled orchestrator skill
|
|
2583
2601
|
|
|
@@ -2586,3 +2604,57 @@ The skill is the delegation protocol: orchestrate rather than work; pass the use
|
|
|
2586
2604
|
It is marked `always: true` so no bin, env or config gate hides it. The ordinary precedence still applies: a workspace `skills/orchestrator` or managed copy overrides it, `skills.entries.orchestrator.enabled: false` turns it off, and an `allowBundled` allowlist that omits it is respected.
|
|
2587
2605
|
`RULES.md` section 5 and its skill table point at the bundled skill. No runtime code changes. Verifier checks 70.1 through 70.5 cover presence, the always flag, the briefing rule, the generic wording and the RULES pointer; `tests/orchestrator-skill.test.mjs` proves every skills chunk loads it from an empty workspace, into the prompt snapshot, and that the override and disable paths still work.
|
|
2588
2606
|
Family 68 remains on the `extended` release line and is not included in this `latest` artifact.
|
|
2607
|
+
|
|
2608
|
+
## Family 71: native-first Jiti standard on latest
|
|
2609
|
+
|
|
2610
|
+
**Marker:** `JOHNNESS_PATCH_NATIVE_JITI_STANDARD_71` (gate and tests; the runtime change is Family 68's own marker in the ten loader copies)
|
|
2611
|
+
**Release:** `johns-harness@2026.9.24`. Published as `latest` and the `extended` dist-tag is moved to the same version, so the two lines converge here.
|
|
2612
|
+
**Gate:** `scripts/check-packed-artifact.mjs [root] | --tarball <file.tgz> [--expect-version <v>]`
|
|
2613
|
+
|
|
2614
|
+
What had been excluding Family 68 from `latest`: not a build step or a strip pass, a branch point. Releases `2026.9.22` and `2026.9.23` were cut from `6427b26` (the pre-68 base of `2026.9.20`), packed and published from that tree, and only then no-ff merged into main. Main carried Family 68 the whole time; the tarballs never did. Every check ran against a working tree, so nothing could notice that the artifact differed from the tree.
|
|
2615
|
+
|
|
2616
|
+
Family 71 closes that gap from the artifact side. The gate runs `npm pack --ignore-scripts`, extracts the tarball, and fails closed unless every one of the ten plugin-loader copies inside it carries exactly one `JOHNNESS_PATCH_JITI_TRY_NATIVE_68` marker and exactly one `tryNative: true`, the tarball version equals the tree version, and no loader copy is missing. The same module inspects a tarball fetched from the registry, which is how the published artifact is proven after `npm publish`. On an installed target the verifier applies the same ten-copy rule to the installed tree.
|
|
2617
|
+
|
|
2618
|
+
Effect: Node loads already-built JavaScript plugin code natively first on every install, with Babel kept only as the fallback for TypeScript plugin entries. Measured on the fleet before this release: gateway RSS 464 MB and 446 MB on `latest` (2026.9.23 and 2026.9.19) against 355 MB on `extended`; isolated 1 GiB lab peak RSS 312 to 327 MiB. The `JITI_TRY_NATIVE=1` environment variable is no longer needed and is harmless if still set. Telegram, WhatsApp and memory stay enabled.
|
|
2619
|
+
|
|
2620
|
+
Family 67 hash checks continue to compare the Family-67 surface with the Family 68 line stripped, unchanged from `2026.9.21-extended.1`; no further adjustment was needed because the loader bytes on main were already the released bytes.
|
|
2621
|
+
|
|
2622
|
+
**Tests:** `tests/native-jiti-standard.test.mjs` proves the gate passes a complete tarball, fails a tarball packed without Family 68 (the 2026.9.22 and 2026.9.23 shape), fails when one copy lacks the option or is absent, fails on a version mismatch, exits non-zero from the CLI, and that the real `npm pack` output of this tree carries the marker in all ten copies. Verifier checks 71.1 through 71.3 cover the shipped gate, the packed or installed artifact, and the absence of a separate extended pin in `package.json`.
|
|
2623
|
+
|
|
2624
|
+
Roll back with `npm i -g johns-harness@2026.9.23` (no native-first Jiti) or `npm i -g johns-harness@2026.9.21-extended.1` (Family 68 without Families 69 and 70).
|
|
2625
|
+
|
|
2626
|
+
## Family 72: bundled generic skills
|
|
2627
|
+
|
|
2628
|
+
**Release:** `johns-harness@2026.9.25`. Published as `latest` and the `extended` dist-tag moves to it (the two lines converged at 2026.9.24).
|
|
2629
|
+
|
|
2630
|
+
Eleven skills from the author's personal workspace ship as bundled skills in `skills/<name>/SKILL.md`, made fully generic first: no owner names, no personal paths, repos, accounts, or products. Every one loads by description match like the other bundled skills (none is `always`-on, unlike the Family 70 orchestrator), a workspace or managed copy overrides it, `skills.entries.<name>.enabled: false` turns it off, and an `allowBundled` allowlist that omits it is respected.
|
|
2631
|
+
|
|
2632
|
+
Shipped skills: `code-ops` (learnings protocol, config tracing, publishing safety), `web-research` (never give up deep research method), `plan-archival` (move finished plans to plans/archive and memory/completed-plans), `todos` (workspace memory/todos protocol), `dashboard` (command center updated after every action), `arch-viz` (sub-agent generated architecture visualization), `content-story` (Story, Concept, Drop framework), `cold-outreach` (Four Pillars cold DM framework), `gcp-logs` (Cloud Run log debugging via gcloud, placeholder service names), `activity-logging` (log outcomes, not tasks, plus the ACTION_LOG), `outlook` (outlook tool quick reference).
|
|
2633
|
+
|
|
2634
|
+
Decision table:
|
|
2635
|
+
|
|
2636
|
+
| Skill | Decision | Reason |
|
|
2637
|
+
|---|---|---|
|
|
2638
|
+
| code-ops | ship, converted | generic protocol, anecdote generalized |
|
|
2639
|
+
| web-research | ship, converted | generic method, em dashes stripped |
|
|
2640
|
+
| plan-archival | ship, converted | personal paths replaced with workspace-relative |
|
|
2641
|
+
| todos | ship, converted | owner name and paths replaced |
|
|
2642
|
+
| dashboard | ship, converted | names, projects and paths scrubbed |
|
|
2643
|
+
| arch-viz | ship, converted | personal paths and projects scrubbed |
|
|
2644
|
+
| content-story | ship, converted | frontmatter added, em dashes stripped |
|
|
2645
|
+
| cold-outreach | ship, converted | frontmatter added, product names scrubbed |
|
|
2646
|
+
| gcp-logs | ship, converted | baked-in service names replaced with placeholders |
|
|
2647
|
+
| activity-logging | ship, converted | log names and paths made workspace-relative |
|
|
2648
|
+
| outlook | ship, converted | account domain scrubbed |
|
|
2649
|
+
| hq-ops | drop | personal repo and GitHub links |
|
|
2650
|
+
| brain-backup | drop | personal restic bucket and paths |
|
|
2651
|
+
| provider-stats | drop | personal auth profiles |
|
|
2652
|
+
| anthropic-sub-proxy | drop | specific deployed proxy setup |
|
|
2653
|
+
| reddit-posting | drop | product marketing workflow |
|
|
2654
|
+
| comms-identity, email-format, dri-reimbursement, johns-amex-login, insyte, willow, x-original-post, memoryrouter-listings, memoryrouter-seo | drop | owner-only skills |
|
|
2655
|
+
| hyperframes, hyperframes-cli, hyperframes-media, website-to-hyperframes, impeccable | exclude | third-party vendored skills |
|
|
2656
|
+
| orchestrator | already shipped | Family 70 |
|
|
2657
|
+
|
|
2658
|
+
Verifier checks 72.1 through 72.5 cover presence with frontmatter, the generic wording contract (no owner, product or personal names and no `always` flag), no em dashes, the RULES.md skill table, and the packed artifact (the Family 71 gate now also proves all eleven skills are inside the tarball). `tests/bundled-skills.test.mjs` proves every skills chunk loads all eleven from an empty workspace, a workspace copy overrides, `enabled: false` disables, and the `allowBundled` allowlist still wins. `RULES.md` section 5 lists every bundled skill.
|
|
2659
|
+
|
|
2660
|
+
Roll back with `npm i -g johns-harness@2026.9.24`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "johns-harness",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.25",
|
|
4
4
|
"description": "John's Harness: a production agent harness that runs autonomous coding agents as one cooperative swarm.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"scripts/postinstall.mjs",
|
|
43
43
|
"scripts/prepare-slim-bundles.mjs",
|
|
44
44
|
"scripts/strip-sourcemaps.mjs",
|
|
45
|
+
"scripts/check-packed-artifact.mjs",
|
|
45
46
|
"scripts/slim-bundles.json",
|
|
46
47
|
"!extensions/**/node_modules/.ignored*/**",
|
|
47
48
|
"!extensions/**/node_modules/.bin/**",
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// JOHNNESS_PATCH_NATIVE_JITI_STANDARD_71
|
|
3
|
+
// Family 71: native-first Jiti is standard on every artifact.
|
|
4
|
+
//
|
|
5
|
+
// Family 68 bakes `tryNative: true` into the ten plugin-loader copies. Releases 2026.9.22 and
|
|
6
|
+
// 2026.9.23 were branched from the pre-68 base and packed from that tree, so the `latest`
|
|
7
|
+
// tarballs shipped without it while the working tree on main carried it. Working-tree checks
|
|
8
|
+
// cannot catch that. This gate inspects the real packed artifact: it runs `npm pack` (or takes
|
|
9
|
+
// an existing tarball), extracts it, and fails closed unless every loader copy in the tarball
|
|
10
|
+
// carries exactly one Family 68 marker and exactly one `tryNative: true`, the tarball version
|
|
11
|
+
// matches the tree version, and no copy is missing.
|
|
12
|
+
//
|
|
13
|
+
// Family 72: the bundled generic skills are also part of the artifact contract. Every one of
|
|
14
|
+
// the Family 72 skills must be present in the tarball with a `name` and a `description` in its
|
|
15
|
+
// frontmatter. The same inspection runs on installed trees.
|
|
16
|
+
//
|
|
17
|
+
// Usage:
|
|
18
|
+
// node scripts/check-packed-artifact.mjs [package root] pack the tree, then inspect
|
|
19
|
+
// node scripts/check-packed-artifact.mjs --tarball <file.tgz> inspect a tarball (for example
|
|
20
|
+
// one fetched from the registry)
|
|
21
|
+
// --expect-version <v> require this package.json version inside the tarball
|
|
22
|
+
|
|
23
|
+
import fs from "node:fs";
|
|
24
|
+
import os from "node:os";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { execFileSync } from "node:child_process";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
|
|
29
|
+
export const MARKER_68 = "JOHNNESS_PATCH_JITI_TRY_NATIVE_68";
|
|
30
|
+
export const OPTION_68 = "tryNative: true";
|
|
31
|
+
// Mirrors ALL_FILES in scripts/patch-jiti-try-native.py.
|
|
32
|
+
export const LOADERS10 = [
|
|
33
|
+
"dist/compact-B247y5Qt.js",
|
|
34
|
+
"dist/pi-embedded-C6ITuRXf.js",
|
|
35
|
+
"dist/pi-embedded-DoQsYfIY.js",
|
|
36
|
+
"dist/plugin-sdk/dispatch-BP0viZiL.js",
|
|
37
|
+
"dist/plugin-sdk/dispatch-CQsjmw7g.js",
|
|
38
|
+
"dist/plugin-sdk/dispatch-Cerq29sy.js",
|
|
39
|
+
"dist/plugin-sdk/dispatch-Cndjtt0g.js",
|
|
40
|
+
"dist/plugin-sdk/dispatch-UogiJYul.js",
|
|
41
|
+
"dist/plugin-sdk/reply-DbZnH8-h.js",
|
|
42
|
+
"dist/reply-C5LKjXcC.js",
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const count = (text, needle) => text.split(needle).length - 1;
|
|
46
|
+
|
|
47
|
+
// Family 72: the generic skills shipped as bundled skills. Each must be inside the artifact
|
|
48
|
+
// with valid frontmatter (a `name:` and a `description:` line).
|
|
49
|
+
export const F72_SKILLS = [
|
|
50
|
+
"activity-logging",
|
|
51
|
+
"arch-viz",
|
|
52
|
+
"code-ops",
|
|
53
|
+
"cold-outreach",
|
|
54
|
+
"content-story",
|
|
55
|
+
"dashboard",
|
|
56
|
+
"gcp-logs",
|
|
57
|
+
"outlook",
|
|
58
|
+
"plan-archival",
|
|
59
|
+
"todos",
|
|
60
|
+
"web-research",
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/** Family 72: verify every bundled generic skill is present with frontmatter. Returns the count. */
|
|
64
|
+
export function inspectSkills72(pkgDir) {
|
|
65
|
+
const problems = [];
|
|
66
|
+
for (const name of F72_SKILLS) {
|
|
67
|
+
const file = path.join(pkgDir, "skills", name, "SKILL.md");
|
|
68
|
+
if (!fs.existsSync(file)) { problems.push(`${name}: skills/${name}/SKILL.md missing from artifact`); continue; }
|
|
69
|
+
const text = fs.readFileSync(file, "utf8");
|
|
70
|
+
if (!/^name: [a-z0-9-]+$/m.test(text)) problems.push(`${name}: frontmatter has no name line`);
|
|
71
|
+
if (!/^description: .+$/m.test(text)) problems.push(`${name}: frontmatter has no description line`);
|
|
72
|
+
}
|
|
73
|
+
if (problems.length) throw new Error(`Family 72: packed artifact is missing bundled generic skills:\n ${problems.join("\n ")}`);
|
|
74
|
+
return F72_SKILLS.length;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Inspect an extracted package directory (the `package/` folder of a tarball). Throws on any gap. */
|
|
78
|
+
export function inspectExtracted71(pkgDir, { expectVersion } = {}) {
|
|
79
|
+
const manifestPath = path.join(pkgDir, "package.json");
|
|
80
|
+
if (!fs.existsSync(manifestPath)) throw new Error(`Family 71: tarball has no package.json at ${manifestPath}`);
|
|
81
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
82
|
+
if (manifest.name !== "johns-harness") throw new Error(`Family 71: tarball is ${manifest.name}, expected johns-harness`);
|
|
83
|
+
if (expectVersion && manifest.version !== expectVersion) {
|
|
84
|
+
throw new Error(`Family 71: tarball version ${manifest.version} does not match expected ${expectVersion}`);
|
|
85
|
+
}
|
|
86
|
+
const problems = [];
|
|
87
|
+
let markers = 0;
|
|
88
|
+
for (const rel of LOADERS10) {
|
|
89
|
+
const file = path.join(pkgDir, rel);
|
|
90
|
+
if (!fs.existsSync(file)) { problems.push(`${rel}: missing from artifact`); continue; }
|
|
91
|
+
const text = fs.readFileSync(file, "utf8");
|
|
92
|
+
const m = count(text, MARKER_68);
|
|
93
|
+
const o = count(text, OPTION_68);
|
|
94
|
+
if (m !== 1) problems.push(`${rel}: ${m} Family 68 markers (expected 1)`);
|
|
95
|
+
if (o !== 1) problems.push(`${rel}: ${o} tryNative: true (expected 1)`);
|
|
96
|
+
if (m === 1 && o === 1) markers += 1;
|
|
97
|
+
}
|
|
98
|
+
if (problems.length) throw new Error(`Family 71: packed artifact lacks native-first Jiti:\n ${problems.join("\n ")}`);
|
|
99
|
+
const skills = inspectSkills72(pkgDir);
|
|
100
|
+
return { version: manifest.version, loaders: LOADERS10.length, markers, skills };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Extract a tarball into a temp dir and inspect it. */
|
|
104
|
+
export function inspectTarball71(tarball, options = {}) {
|
|
105
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "johnness-f71-"));
|
|
106
|
+
try {
|
|
107
|
+
execFileSync("tar", ["-xzf", path.resolve(tarball), "-C", tmp], { stdio: ["ignore", "pipe", "pipe"] });
|
|
108
|
+
return { tarball: path.resolve(tarball), ...inspectExtracted71(path.join(tmp, "package"), options) };
|
|
109
|
+
} finally {
|
|
110
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Pack the tree with npm (scripts ignored; same method as the Family 66 Linux gate) and inspect the result. */
|
|
115
|
+
export function packAndInspect71(root) {
|
|
116
|
+
const tree = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
117
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "johnness-f71-pack-"));
|
|
118
|
+
try {
|
|
119
|
+
const pack = JSON.parse(execFileSync("npm", ["pack", "--json", "--ignore-scripts", "--pack-destination", tmp], {
|
|
120
|
+
cwd: root, encoding: "utf8", maxBuffer: 20e6, stdio: ["ignore", "pipe", "pipe"],
|
|
121
|
+
}))[0];
|
|
122
|
+
const result = inspectTarball71(path.join(tmp, pack.filename), { expectVersion: tree.version });
|
|
123
|
+
return { ...result, tarball: pack.filename, bytes: pack.size, entries: pack.entryCount };
|
|
124
|
+
} finally {
|
|
125
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
130
|
+
const args = process.argv.slice(2);
|
|
131
|
+
const flag = (name) => { const i = args.indexOf(name); return i >= 0 ? args[i + 1] : undefined; };
|
|
132
|
+
const tarball = flag("--tarball");
|
|
133
|
+
const expectVersion = flag("--expect-version");
|
|
134
|
+
try {
|
|
135
|
+
let result;
|
|
136
|
+
if (tarball) {
|
|
137
|
+
result = inspectTarball71(tarball, { expectVersion });
|
|
138
|
+
} else {
|
|
139
|
+
const positional = args.filter((a, i) => !a.startsWith("--") && args[i - 1] !== "--tarball" && args[i - 1] !== "--expect-version");
|
|
140
|
+
const root = path.resolve(positional[0] || path.join(path.dirname(fileURLToPath(import.meta.url)), ".."));
|
|
141
|
+
result = packAndInspect71(root);
|
|
142
|
+
}
|
|
143
|
+
console.log(`Family 71: ${result.markers}/${result.loaders} loader copies carry native-first Jiti in ${path.basename(result.tarball)} (version ${result.version}); Family 72: ${result.skills} bundled generic skills present`);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error(error.message);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: activity-logging
|
|
3
|
+
description: Activity and action logging to the workspace. Load when logging work outcomes or recording actions to ACTION_LOG.md.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Activity & Action Logging
|
|
7
|
+
|
|
8
|
+
## Activity Logging: Log Outcomes, Not Tasks
|
|
9
|
+
|
|
10
|
+
### What to Log
|
|
11
|
+
- Features built or meaningfully improved
|
|
12
|
+
- Process/rule changes with real impact
|
|
13
|
+
- Decisions that matter
|
|
14
|
+
- Problems encountered and how they were resolved (if interesting)
|
|
15
|
+
|
|
16
|
+
### What NOT to Log
|
|
17
|
+
- Fixing your own mistakes (type errors, build failures, typos)
|
|
18
|
+
- Minor tweaks or implementation details
|
|
19
|
+
- Each tiny step of a larger task: consolidate into one entry
|
|
20
|
+
- Routine maintenance
|
|
21
|
+
|
|
22
|
+
### How to Decide
|
|
23
|
+
Ask: *"Would the user care about this in a weekly review?"*
|
|
24
|
+
- If it's an **outcome** that delivered value, log it
|
|
25
|
+
- If it's **busywork** or cleanup, skip it
|
|
26
|
+
- If multiple items are related, **consolidate** into one entry
|
|
27
|
+
|
|
28
|
+
### Format
|
|
29
|
+
- **Bold the specific outcome**: then explain what/how/why
|
|
30
|
+
- Entry should make sense in 3 months without extra context
|
|
31
|
+
- Ask: *"What can the user or I do now that we couldn't before?"*
|
|
32
|
+
- Bad: "Improved chart system"
|
|
33
|
+
- Good: "Pie charts now show percentages on slices: added data labels, mobile scroll, theme colors"
|
|
34
|
+
|
|
35
|
+
### Process
|
|
36
|
+
1. Update today's log: `memory/logs/YYYY-MM-DD.md`
|
|
37
|
+
2. Mirror on the dashboard if one exists
|
|
38
|
+
3. Push to git:
|
|
39
|
+
```bash
|
|
40
|
+
cd <workspace>
|
|
41
|
+
git add -A && git commit -m "Update log" && git push
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Action Log (Real-Time Action Tracking)
|
|
47
|
+
|
|
48
|
+
**Log every action as it happens.**
|
|
49
|
+
|
|
50
|
+
### Location
|
|
51
|
+
`ACTION_LOG.md` in the workspace root
|
|
52
|
+
|
|
53
|
+
### What to Log
|
|
54
|
+
Every action you take: simple one-liner titles:
|
|
55
|
+
- Spawned sub-agent for X
|
|
56
|
+
- Generated image for Y
|
|
57
|
+
- Fixed Z in repo
|
|
58
|
+
- Created skill for W
|
|
59
|
+
- Sent message to user about V
|
|
60
|
+
|
|
61
|
+
### Format
|
|
62
|
+
```markdown
|
|
63
|
+
## YYYY-MM-DD
|
|
64
|
+
|
|
65
|
+
- Action 1
|
|
66
|
+
- Action 2
|
|
67
|
+
- Action 3
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Rules
|
|
71
|
+
1. **Log immediately**: after completing any action, add a one-liner
|
|
72
|
+
2. **Keep it simple**: title-level, not detailed
|
|
73
|
+
3. **New date section**: start each day with a new `## YYYY-MM-DD` header
|
|
74
|
+
4. **Don't overthink**: if you did something, log it
|
|
75
|
+
|
|
76
|
+
### Daily Recap (Scheduled Job)
|
|
77
|
+
A daily scheduled job can create `memory/YYYY-MM-DD.md` from:
|
|
78
|
+
1. **Conversation history**: the full journey of what was discussed, decided, built
|
|
79
|
+
2. **Action Log**: the action entries
|
|
80
|
+
|
|
81
|
+
Format:
|
|
82
|
+
```markdown
|
|
83
|
+
# YYYY-MM-DD: [Creative title capturing the day's vibe]
|
|
84
|
+
|
|
85
|
+
## The Story
|
|
86
|
+
[2-4 paragraph narrative, journal entry style, captures the day's energy]
|
|
87
|
+
|
|
88
|
+
## Key Accomplishments
|
|
89
|
+
- Major wins and shipped items
|
|
90
|
+
- Decisions made
|
|
91
|
+
|
|
92
|
+
## Actions Log
|
|
93
|
+
[Actions from ACTION_LOG.md]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This captures the journey over time: both the story AND the specifics.
|