@hasna/loops 0.4.28 → 0.4.29
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 +84 -1
- package/README.md +226 -49
- package/dist/api/index.d.ts +20 -19
- package/dist/api/index.js +6846 -1087
- package/dist/cli/index.js +2471 -885
- package/dist/cli/safe-error-context.d.ts +1 -0
- package/dist/daemon/daemon.d.ts +1 -0
- package/dist/daemon/index.js +1786 -493
- package/dist/generated/storage-kit/index.d.ts +1 -1
- package/dist/generated/storage-kit/mode.d.ts +6 -12
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4778 -1016
- package/dist/lib/advancement.d.ts +52 -0
- package/dist/lib/agent-adapter.d.ts +20 -2
- package/dist/lib/auth/route-policy.d.ts +14 -0
- package/dist/lib/auth/tenant-auth.d.ts +38 -0
- package/dist/lib/cloud/mode.d.ts +2 -8
- package/dist/lib/cloud/storage.d.ts +1 -2
- package/dist/lib/cloud/transport.d.ts +4 -18
- package/dist/lib/errors.d.ts +43 -1
- package/dist/lib/format.d.ts +2 -2
- package/dist/lib/goal/runner.d.ts +36 -3
- package/dist/lib/health.d.ts +1 -1
- package/dist/lib/labels.d.ts +4 -0
- package/dist/lib/loop-status.d.ts +4 -0
- package/dist/lib/migration.d.ts +4 -17
- package/dist/lib/mode.d.ts +2 -5
- package/dist/lib/mode.js +27 -36
- package/dist/lib/route/index.d.ts +2 -2
- package/dist/lib/route/throttle.d.ts +7 -0
- package/dist/lib/route/types.d.ts +3 -0
- package/dist/lib/run-completion.d.ts +18 -0
- package/dist/lib/scheduler.d.ts +5 -11
- package/dist/lib/storage/contract.d.ts +15 -1
- package/dist/lib/storage/index.d.ts +1 -1
- package/dist/lib/storage/index.js +3864 -457
- package/dist/lib/storage/pg-executor.d.ts +10 -5
- package/dist/lib/storage/postgres-loop-storage.d.ts +50 -24
- package/dist/lib/storage/postgres-schema.d.ts +8 -0
- package/dist/lib/storage/postgres-schema.js +1323 -1
- package/dist/lib/storage/postgres.d.ts +3 -1
- package/dist/lib/storage/postgres.js +1353 -27
- package/dist/lib/storage/provider-credentials.d.ts +84 -0
- package/dist/lib/storage/shared-database-transfer.d.ts +136 -0
- package/dist/lib/storage/sqlite.d.ts +15 -2
- package/dist/lib/storage/sqlite.js +1299 -217
- package/dist/lib/storage/tenant-backfill-s3.d.ts +53 -0
- package/dist/lib/storage/tenant-backfill.d.ts +40 -0
- package/dist/lib/store/index.d.ts +11 -8
- package/dist/lib/store.d.ts +52 -7
- package/dist/lib/store.js +1266 -217
- package/dist/lib/templates.d.ts +11 -0
- package/dist/lib/workflow-events.d.ts +6 -0
- package/dist/lib/workflow-provenance.d.ts +8 -0
- package/dist/lib/workflow-runner.d.ts +52 -4
- package/dist/mcp/index.js +1961 -651
- package/dist/runner/index.d.ts +20 -2
- package/dist/runner/index.js +2113 -177
- package/dist/sdk/http.d.ts +211 -3
- package/dist/sdk/http.js +301 -0
- package/dist/sdk/index.d.ts +7 -2
- package/dist/sdk/index.js +1959 -711
- package/dist/serve/index.d.ts +14 -0
- package/dist/serve/index.js +12323 -1743
- package/dist/types.d.ts +64 -3
- package/docs/AUTOMATION_RUNTIME_DESIGN.md +32 -32
- package/docs/CUTOVER-RUNBOOK.md +158 -31
- package/docs/DEPLOYMENT_MODES.md +78 -56
- package/docs/RUNTIME_BOUNDARY.md +26 -26
- package/docs/SHARED-DATABASE-TRANSFER.md +95 -0
- package/docs/SHARED_KIT_EXTRACTION_INVENTORY.md +631 -0
- package/docs/TRANSCRIPT_LOOP_PATTERNS.md +3 -3
- package/docs/UNIFIED_PRODUCT_CONTRACT.md +365 -0
- package/docs/USAGE.md +143 -52
- package/docs/workflows/transcript-feedback-to-loops.json +2 -2
- package/package.json +7 -3
- package/dist/lib/storage/pg-runner-claim.d.ts +0 -40
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
# Shared Kit Extraction Inventory
|
|
2
|
+
|
|
3
|
+
Date: 2026-07-07
|
|
4
|
+
|
|
5
|
+
Task: `8fd378e0-909c-4d13-8c7d-16b950591c2f`
|
|
6
|
+
|
|
7
|
+
This is a report-only inventory for the P5 shared-kits workstream. It does not
|
|
8
|
+
publish packages, edit Bun release-age exclusions, migrate consumers, or change
|
|
9
|
+
runtime code.
|
|
10
|
+
|
|
11
|
+
Current-status correction (2026-07-20): the cross-repo observations below
|
|
12
|
+
remain the 2026-07-07 inventory. OpenLoops state normalization landed through
|
|
13
|
+
PR #81 at commit `0acb5e79` and merge commit `6d1e9536`. The current strict
|
|
14
|
+
storage kit is version `0.5.2`, established through PR #93 at commit
|
|
15
|
+
`1456b852`, and its validation command is `bun run check:contracts`. PR #84 is
|
|
16
|
+
not current normalization evidence and has its own disposition.
|
|
17
|
+
|
|
18
|
+
## Summary
|
|
19
|
+
|
|
20
|
+
The strongest extraction candidate is the generated Hasna storage kit. It is
|
|
21
|
+
already a bounded kit, it is stamped into multiple repositories by
|
|
22
|
+
`@hasna/contracts vendor-kit`, and the inspected repos show repeated hashes
|
|
23
|
+
across version cohorts. It should be normalized and extracted before less
|
|
24
|
+
stable runtime, CLI, event, or logging helpers.
|
|
25
|
+
|
|
26
|
+
The CLI, local path/config, logging/redaction, retention, and event surfaces are
|
|
27
|
+
real duplication, but they are not equally ready. Some already have an owning
|
|
28
|
+
package (`@hasna/events`, `@hasna/logs`, `@hasna/contracts`). Others have
|
|
29
|
+
repo-specific behavior that would make a broad extraction risky without a
|
|
30
|
+
human package-boundary decision.
|
|
31
|
+
|
|
32
|
+
Recommended first automation slice:
|
|
33
|
+
|
|
34
|
+
1. Treat OpenLoops normalization as complete: version `0.5.1` state
|
|
35
|
+
normalization landed through PR #81 at commit `0acb5e79` and merge commit
|
|
36
|
+
`6d1e9536`; the current strict storage kit is version `0.5.2`, established
|
|
37
|
+
through PR #93 at commit `1456b852`. Validate it with
|
|
38
|
+
`bun run check:contracts`.
|
|
39
|
+
2. After human approval of package ownership/name, extract the generated kit
|
|
40
|
+
into a shared package or stable `@hasna/contracts` subpath.
|
|
41
|
+
3. Migrate consumers one repo cohort at a time, preserving their local storage
|
|
42
|
+
semantics.
|
|
43
|
+
|
|
44
|
+
## Repos And Files Inspected
|
|
45
|
+
|
|
46
|
+
Primary repo, writeable worktree:
|
|
47
|
+
|
|
48
|
+
- `open-loops/package.json`
|
|
49
|
+
- `open-loops/docs/AUTOMATION_RUNTIME_DESIGN.md`
|
|
50
|
+
- `open-loops/docs/DEPLOYMENT_MODES.md`
|
|
51
|
+
- `open-loops/docs/RUNTIME_BOUNDARY.md`
|
|
52
|
+
- `open-loops/docs/USAGE.md`
|
|
53
|
+
- `open-loops/src/cli/index.ts`
|
|
54
|
+
- `open-loops/src/api/index.ts`
|
|
55
|
+
- `open-loops/src/serve/index.ts`
|
|
56
|
+
- `open-loops/src/runner/index.ts`
|
|
57
|
+
- `open-loops/src/daemon/index.ts`
|
|
58
|
+
- `open-loops/src/daemon/daemon.ts`
|
|
59
|
+
- `open-loops/src/daemon/install.ts`
|
|
60
|
+
- `open-loops/src/lib/mode.ts`
|
|
61
|
+
- `open-loops/src/lib/paths.ts`
|
|
62
|
+
- `open-loops/src/lib/env.ts`
|
|
63
|
+
- `open-loops/src/lib/storage/contract.ts`
|
|
64
|
+
- `open-loops/src/lib/storage/sqlite.ts`
|
|
65
|
+
- `open-loops/src/lib/storage/postgres.ts`
|
|
66
|
+
- `open-loops/src/lib/storage/postgres-schema.ts`
|
|
67
|
+
- `open-loops/src/lib/hygiene.ts`
|
|
68
|
+
- `open-loops/src/lib/run-artifacts.ts`
|
|
69
|
+
- `open-loops/src/lib/run-receipts.ts`
|
|
70
|
+
- `open-loops/src/lib/cloud/mode.ts`
|
|
71
|
+
- `open-loops/src/lib/cloud/resolve.ts`
|
|
72
|
+
- `open-loops/src/lib/cloud/storage.ts`
|
|
73
|
+
- `open-loops/src/lib/cloud/transport.ts`
|
|
74
|
+
- `open-loops/src/lib/route/options.ts`
|
|
75
|
+
- `open-loops/src/lib/route/route-event.ts`
|
|
76
|
+
- `open-loops/src/lib/route/todos-cli.ts`
|
|
77
|
+
- `open-loops/src/sdk/index.ts`
|
|
78
|
+
- `open-loops/src/generated/storage-kit/*`
|
|
79
|
+
|
|
80
|
+
Sibling repos inspected read-only:
|
|
81
|
+
|
|
82
|
+
- `open-todos/package.json`
|
|
83
|
+
- `open-todos/src/cli/index.tsx`
|
|
84
|
+
- `open-todos/src/cli/helpers.ts`
|
|
85
|
+
- `open-todos/src/cli/cloud-router.ts`
|
|
86
|
+
- `open-todos/src/db/database.ts`
|
|
87
|
+
- `open-todos/src/db/webhooks.ts`
|
|
88
|
+
- `open-todos/src/lib/event-hooks.ts`
|
|
89
|
+
- `open-todos/src/lib/shared-events.ts`
|
|
90
|
+
- `open-todos/src/lib/retention-cleanup.ts`
|
|
91
|
+
- `open-todos/src/storage/config.ts`
|
|
92
|
+
- `open-projects/package.json`
|
|
93
|
+
- `open-projects/src/cli/index.ts`
|
|
94
|
+
- `open-projects/src/cli/commands/storage.ts`
|
|
95
|
+
- `open-projects/src/db/database.ts`
|
|
96
|
+
- `open-projects/src/db/remote-storage.ts`
|
|
97
|
+
- `open-projects/src/db/storage-sync.ts`
|
|
98
|
+
- `open-projects/src/lib/project-store-paths.ts`
|
|
99
|
+
- `open-projects/src/generated/storage-kit/*`
|
|
100
|
+
- `open-conversations/package.json`
|
|
101
|
+
- `open-conversations/src/cli/index.tsx`
|
|
102
|
+
- `open-conversations/src/lib/cloud-store.ts`
|
|
103
|
+
- `open-conversations/src/lib/db.ts`
|
|
104
|
+
- `open-conversations/src/lib/webhooks.ts`
|
|
105
|
+
- `open-conversations/src/generated/storage-kit/*`
|
|
106
|
+
- `open-mementos/package.json`
|
|
107
|
+
- `open-mementos/src/cli/index.tsx`
|
|
108
|
+
- `open-mementos/src/db/database.ts`
|
|
109
|
+
- `open-mementos/src/lib/config.ts`
|
|
110
|
+
- `open-mementos/src/generated/storage-kit/*`
|
|
111
|
+
- `open-knowledge/package.json`
|
|
112
|
+
- `open-knowledge/src/cli.ts`
|
|
113
|
+
- `open-knowledge/src/cloud-store.ts`
|
|
114
|
+
- `open-knowledge/src/knowledge-db.ts`
|
|
115
|
+
- `open-knowledge/src/db/remote-storage.ts`
|
|
116
|
+
- `open-knowledge/src/generated/storage-kit/*`
|
|
117
|
+
- `open-machines/package.json`
|
|
118
|
+
- `open-machines/src/cli/index.ts`
|
|
119
|
+
- `open-machines/src/paths.ts`
|
|
120
|
+
- `open-machines/src/cloud/mode.ts`
|
|
121
|
+
- `open-machines/src/cloud/storage.ts`
|
|
122
|
+
- `open-machines/src/remote-storage.ts`
|
|
123
|
+
- `open-machines/src/generated/storage-kit/*`
|
|
124
|
+
- `open-accounts/package.json`
|
|
125
|
+
- `open-accounts/src/cli.ts`
|
|
126
|
+
- `open-accounts/src/lib/env.ts`
|
|
127
|
+
- `open-accounts/src/lib/events.ts`
|
|
128
|
+
- `open-accounts/src/storage.ts`
|
|
129
|
+
- `open-accounts/src/generated/storage-kit/*`
|
|
130
|
+
- `open-configs/package.json`
|
|
131
|
+
- `open-configs/src/cli/index.tsx`
|
|
132
|
+
- `open-configs/src/cli/storage.ts`
|
|
133
|
+
- `open-configs/src/lib/session-render.ts`
|
|
134
|
+
- `open-configs/src/storage.ts`
|
|
135
|
+
- `open-configs/src/generated/storage-kit/*`
|
|
136
|
+
- `open-logs/package.json`
|
|
137
|
+
- `open-logs/src/cli/index.ts`
|
|
138
|
+
- `open-logs/src/db/index.ts`
|
|
139
|
+
- `open-logs/src/lib/cloud-store.ts`
|
|
140
|
+
- `open-logs/src/lib/event-store.ts`
|
|
141
|
+
- `open-logs/src/lib/redaction.ts`
|
|
142
|
+
- `open-logs/src/lib/retention.ts`
|
|
143
|
+
- `open-logs/src/lib/rotate.ts`
|
|
144
|
+
- `open-logs/src/generated/storage-kit/*`
|
|
145
|
+
- `open-events/package.json`
|
|
146
|
+
- `open-events/src/cli/index.ts`
|
|
147
|
+
- `open-events/src/commander.ts`
|
|
148
|
+
- `open-events/src/index.ts`
|
|
149
|
+
- `open-events/src/storage.ts`
|
|
150
|
+
- `open-events/src/transports.ts`
|
|
151
|
+
- `open-codewith/package.json`
|
|
152
|
+
- `open-codewith/scripts/start-codewith-exec.sh`
|
|
153
|
+
- `open-codewith/scripts/run_tui_with_exec_server.sh`
|
|
154
|
+
- `open-codewith/scripts/test-remote-env.sh`
|
|
155
|
+
- `open-codewith/scripts/install/install.sh`
|
|
156
|
+
- `open-codewith/scripts/mock_responses_websocket_server.py`
|
|
157
|
+
|
|
158
|
+
## Concrete Duplication Evidence
|
|
159
|
+
|
|
160
|
+
### Generated Storage Kit
|
|
161
|
+
|
|
162
|
+
`src/generated/storage-kit/README.md` describes this as a generated fleet
|
|
163
|
+
storage kit from `@hasna/contracts vendor-kit`, with mode resolution, TLS,
|
|
164
|
+
pool, query, migrations, health, and no sync/cache behavior. The inspected
|
|
165
|
+
repos carry the same generated file set:
|
|
166
|
+
|
|
167
|
+
- `index.ts`
|
|
168
|
+
- `mode.ts`
|
|
169
|
+
- `pool.ts`
|
|
170
|
+
- `query.ts`
|
|
171
|
+
- `tls.ts`
|
|
172
|
+
- `health.ts`
|
|
173
|
+
- `migrations.ts`
|
|
174
|
+
- `.storage-kit-manifest.json`
|
|
175
|
+
- `README.md`
|
|
176
|
+
|
|
177
|
+
Observed manifest cohorts:
|
|
178
|
+
|
|
179
|
+
- `kitVersion: 0.4.0`: `open-loops`, `open-knowledge`
|
|
180
|
+
- `kitVersion: 0.4.1`: `open-projects`, `open-conversations`,
|
|
181
|
+
`open-mementos`, `open-accounts`
|
|
182
|
+
- `kitVersion: 0.4.2`: `open-machines`, `open-configs`, `open-logs`
|
|
183
|
+
|
|
184
|
+
Observed hash evidence:
|
|
185
|
+
|
|
186
|
+
- `open-projects`, `open-conversations`, `open-mementos`, and
|
|
187
|
+
`open-accounts` have identical hashes for all sampled generated storage kit
|
|
188
|
+
files at `kitVersion: 0.4.1`.
|
|
189
|
+
- `open-machines`, `open-configs`, and `open-logs` have identical hashes for
|
|
190
|
+
all sampled generated storage kit files at `kitVersion: 0.4.2`.
|
|
191
|
+
- `open-loops` and `open-knowledge` share the same `index.ts`, `mode.ts`,
|
|
192
|
+
`pool.ts`, `query.ts`, and `health.ts` hashes at `kitVersion: 0.4.0`; their
|
|
193
|
+
`tls.ts` and `migrations.ts` hashes differ from each other, so they need a
|
|
194
|
+
drift check before extraction.
|
|
195
|
+
- All inspected generated storage-kit `README.md` files use the same hash.
|
|
196
|
+
|
|
197
|
+
This is the best candidate because it is already generated, bounded, and
|
|
198
|
+
versioned. Extraction would reduce vendored drift and stop each repo from
|
|
199
|
+
carrying generated code in source.
|
|
200
|
+
|
|
201
|
+
### Local Storage And Path Resolution
|
|
202
|
+
|
|
203
|
+
The repos also duplicate local data directory and database path logic:
|
|
204
|
+
|
|
205
|
+
- `open-loops/src/lib/paths.ts` resolves `LOOPS_DATA_DIR` or
|
|
206
|
+
`~/.hasna/loops`, then derives `loops.db`, daemon PID/log paths, and startup
|
|
207
|
+
service paths.
|
|
208
|
+
- `open-todos/src/db/database.ts` resolves `HASNA_TODOS_DB_PATH`, nearest
|
|
209
|
+
`.hasna/todos/todos.db`, git-root `.hasna/todos/todos.db`, and finally
|
|
210
|
+
`~/.hasna/todos/todos.db`.
|
|
211
|
+
- `open-projects/src/db/database.ts` resolves `HASNA_PROJECTS_DB_PATH`, legacy
|
|
212
|
+
`HASNA_WORKSPACES_DB_PATH`, and `~/.hasna/projects/projects.db`, then enables
|
|
213
|
+
WAL and foreign keys.
|
|
214
|
+
- `open-projects/src/lib/project-store-paths.ts` resolves
|
|
215
|
+
`HASNA_PROJECTS_HOME` plus per-workspace `workspaces/<id>` and `data/<id>`
|
|
216
|
+
paths.
|
|
217
|
+
- `open-conversations/src/lib/db.ts` resolves `~/.hasna/conversations`,
|
|
218
|
+
migrates from `~/.conversations`, and honors `HASNA_CONVERSATIONS_DB_PATH`
|
|
219
|
+
and `CONVERSATIONS_DB_PATH`.
|
|
220
|
+
- `open-logs/src/db/index.ts` resolves `HASNA_LOGS_DATA_DIR` or
|
|
221
|
+
`LOGS_DATA_DIR`, migrates from `~/.logs`, enforces `0700`/`0600`, and enables
|
|
222
|
+
WAL/foreign keys with busy retries.
|
|
223
|
+
- `open-events/src/storage.ts` resolves `HASNA_EVENTS_DIR`,
|
|
224
|
+
`HASNA_EVENTS_HOME`, or `~/.hasna/events`, then creates the directory with
|
|
225
|
+
private mode.
|
|
226
|
+
|
|
227
|
+
There is duplication, but local path behavior differs enough by app that it
|
|
228
|
+
should be a small helper inside a broader storage/runtime kit, not a standalone
|
|
229
|
+
package first.
|
|
230
|
+
|
|
231
|
+
### Cloud Client And Storage Sync
|
|
232
|
+
|
|
233
|
+
The generated storage kit deliberately excludes sync/cache logic, but several
|
|
234
|
+
repos re-implement adjacent cloud transport or remote storage wrappers:
|
|
235
|
+
|
|
236
|
+
- `open-loops/src/lib/cloud/transport.ts` resolves client mode and cloud HTTP
|
|
237
|
+
transport from `HASNA_<APP>_STORAGE_MODE`, API URL, and API key variables.
|
|
238
|
+
- `open-conversations/src/lib/cloud-store.ts` uses
|
|
239
|
+
`@hasna/contracts/client/storage` and adds app-specific implied
|
|
240
|
+
`self_hosted` mode when API URL and API key are present.
|
|
241
|
+
- `open-logs/src/lib/cloud-store.ts` follows the same implied self-hosted
|
|
242
|
+
pattern and wraps a cloud store for logs resources.
|
|
243
|
+
- `open-projects/src/db/remote-storage.ts` implements a local `PgAdapterAsync`
|
|
244
|
+
with placeholder translation, undefined-to-null conversion, and TLS
|
|
245
|
+
detection.
|
|
246
|
+
- `open-projects/src/db/storage-sync.ts`, `open-logs/src/lib/storage-sync.ts`,
|
|
247
|
+
and equivalent storage exports expose similar status, push, pull, sync,
|
|
248
|
+
canonical RDS, and table-selection concepts.
|
|
249
|
+
|
|
250
|
+
This is a second-order candidate after the generated storage kit. A premature
|
|
251
|
+
sync extraction would mix very different app data models.
|
|
252
|
+
|
|
253
|
+
### CLI Scaffolding
|
|
254
|
+
|
|
255
|
+
The inspected repos duplicate Commander setup, JSON detection, package-version
|
|
256
|
+
lookup, printing helpers, and numeric option parsing:
|
|
257
|
+
|
|
258
|
+
- `open-loops/src/cli/index.ts` has `new Command()`, global `-j/--json`,
|
|
259
|
+
`print`, `reportCliError`, `runAction`, deployment status printing, and many
|
|
260
|
+
repeated option parser helpers.
|
|
261
|
+
- `open-todos/src/cli/index.tsx` has a top-level Commander app, global
|
|
262
|
+
`--project`, `--json`, `--agent`, and `--session`, dynamic command module
|
|
263
|
+
registration, and optional event command fallback logic.
|
|
264
|
+
- `open-todos/src/cli/helpers.ts` has `printJson`; many todo command modules
|
|
265
|
+
also define local parse helpers.
|
|
266
|
+
- `open-projects/src/cli/index.ts` duplicates package-version lookup,
|
|
267
|
+
Commander setup, JSON env toggles, and prompt-mode argument routing.
|
|
268
|
+
- `open-projects/src/cli/commands/storage.ts`,
|
|
269
|
+
`open-configs/src/cli/storage.ts`, and `open-machines/src/cli/index.ts`
|
|
270
|
+
duplicate storage command shapes and JSON printing.
|
|
271
|
+
- `open-events/src/cli/index.ts` is a hand-rolled parser rather than Commander,
|
|
272
|
+
while `open-events/src/commander.ts` provides a reusable Commander
|
|
273
|
+
registration helper for events/channels.
|
|
274
|
+
|
|
275
|
+
This is a real candidate, but not first. The repos differ between Ink CLIs,
|
|
276
|
+
plain Commander CLIs, hand-rolled CLIs, prompt-mode CLIs, and safety-gated
|
|
277
|
+
mutation CLIs. A package boundary needs human approval and a compatibility
|
|
278
|
+
matrix before migration.
|
|
279
|
+
|
|
280
|
+
### Event And Webhook Functionality
|
|
281
|
+
|
|
282
|
+
`@hasna/events` already exists and is partially adopted:
|
|
283
|
+
|
|
284
|
+
- `open-events/src/index.ts`, `src/transports.ts`, `src/storage.ts`, and
|
|
285
|
+
`src/commander.ts` define the shared EventsClient, storage, transports, and
|
|
286
|
+
Commander registration helper.
|
|
287
|
+
- `open-projects/src/cli/index.ts`,
|
|
288
|
+
`open-conversations/src/cli/index.tsx`, `open-accounts/src/cli.ts`, and
|
|
289
|
+
`open-configs/src/cli/index.tsx` call `registerEventsCommands`.
|
|
290
|
+
- `open-todos/src/lib/shared-events.ts` uses `EventsClient`, but
|
|
291
|
+
`open-todos/src/lib/event-hooks.ts` and `open-todos/src/db/webhooks.ts`
|
|
292
|
+
still retain local event-hook and webhook implementations.
|
|
293
|
+
- `open-conversations/src/lib/webhooks.ts` keeps config-backed app-specific
|
|
294
|
+
webhook dispatch.
|
|
295
|
+
- `open-machines/src/cli/index.ts`, `src/commands/runtime.ts`,
|
|
296
|
+
`src/commands/serve.ts`, and `src/mcp/server.ts` directly use
|
|
297
|
+
`EventsClient` while preserving machine-specific mutation approval gates.
|
|
298
|
+
- `open-loops/src/lib/route/route-event.ts` imports `EventEnvelope` and owns
|
|
299
|
+
route-specific event-to-workflow behavior; `open-loops/src/cli/index.ts`
|
|
300
|
+
exposes deprecated `events` aliases for route commands, not generic events.
|
|
301
|
+
|
|
302
|
+
The correct package proposal is not a new event kit. It is continued adoption
|
|
303
|
+
of `@hasna/events` plus explicit compatibility tasks for app-local webhook
|
|
304
|
+
features.
|
|
305
|
+
|
|
306
|
+
### Logging, Redaction, Retention, And Evidence
|
|
307
|
+
|
|
308
|
+
There are overlapping diagnostics patterns:
|
|
309
|
+
|
|
310
|
+
- `open-loops/src/daemon/daemon.ts` implements `daemonLogLine`,
|
|
311
|
+
`rotateDaemonLog`, default daemon stderr logging, and daemon lease/run logs.
|
|
312
|
+
- `open-loops/src/lib/run-artifacts.ts` writes workflow run manifests under
|
|
313
|
+
`runs/<project>/<subject>/<workflowRunId>/manifest.json` with staged temp
|
|
314
|
+
promotion.
|
|
315
|
+
- `open-loops/src/lib/run-receipts.ts` normalizes receipts, canonical JSON
|
|
316
|
+
digests, bounded stdout/stderr excerpts, evidence paths, and task/knowledge
|
|
317
|
+
IDs.
|
|
318
|
+
- `open-todos/src/lib/retention-cleanup.ts` owns local cleanup reports for old
|
|
319
|
+
comments, runs, verification evidence, and expired artifact files.
|
|
320
|
+
- `open-logs/src/lib/redaction.ts` owns richer log-entry redaction for tokens,
|
|
321
|
+
URL userinfo, secret assignments, auth flags, query params, emails, and more.
|
|
322
|
+
- `open-logs/src/lib/retention.ts` and `src/lib/rotate.ts` implement per-level
|
|
323
|
+
TTL and max-row log deletion.
|
|
324
|
+
- `open-codewith/scripts/start-codewith-exec.sh`,
|
|
325
|
+
`scripts/run_tui_with_exec_server.sh`, and `scripts/test-remote-env.sh`
|
|
326
|
+
provide shell cleanup/trap patterns; `scripts/mock_responses_websocket_server.py`
|
|
327
|
+
provides mock event streaming helpers. These were inspected as bounded
|
|
328
|
+
script surfaces, but they do not justify a shared Hasna TypeScript kit by
|
|
329
|
+
themselves.
|
|
330
|
+
|
|
331
|
+
This area is security-sensitive and overlaps with the existing `@hasna/logs`
|
|
332
|
+
package. Do not create a separate logging package without deciding whether
|
|
333
|
+
`@hasna/logs` owns redaction/rotation APIs for the fleet.
|
|
334
|
+
|
|
335
|
+
## Candidate Package Boundaries
|
|
336
|
+
|
|
337
|
+
### 1. `@hasna/storage-kit`
|
|
338
|
+
|
|
339
|
+
Status: highest-confidence candidate; package publish/name needs human
|
|
340
|
+
approval. OpenLoops normalization is complete: version `0.5.1` state
|
|
341
|
+
normalization landed through PR #81 at commit `0acb5e79` and merge commit
|
|
342
|
+
`6d1e9536`, and the current strict storage kit is version `0.5.2`, established
|
|
343
|
+
through PR #93 at commit `1456b852`. PR #84 is not current normalization
|
|
344
|
+
evidence and has its own disposition.
|
|
345
|
+
|
|
346
|
+
Responsibilities:
|
|
347
|
+
|
|
348
|
+
- Storage mode/env resolution for local vs cloud/self-hosted semantics.
|
|
349
|
+
- Postgres TLS handling that matches libpq `sslmode`.
|
|
350
|
+
- `pg.Pool` factory and typed query helpers.
|
|
351
|
+
- Migration ledger and checksum validation.
|
|
352
|
+
- Health and readiness probes.
|
|
353
|
+
- Optional app path helper for `~/.hasna/<app>/<app>.db` and app-specific env
|
|
354
|
+
key sets, once local path semantics are normalized.
|
|
355
|
+
|
|
356
|
+
Non-responsibilities:
|
|
357
|
+
|
|
358
|
+
- App schema definitions.
|
|
359
|
+
- App-specific local SQLite migrations.
|
|
360
|
+
- Bidirectional sync engines.
|
|
361
|
+
- HTTP API resource mapping.
|
|
362
|
+
- Runtime auth decisions.
|
|
363
|
+
- Release-age exclusion edits.
|
|
364
|
+
|
|
365
|
+
Migration order:
|
|
366
|
+
|
|
367
|
+
1. Keep `open-loops/src/generated/storage-kit` on the current strict
|
|
368
|
+
`@hasna/contracts` version `0.5.2` and verify it with
|
|
369
|
+
`bun run check:contracts`. The earlier version `0.5.1` state normalization
|
|
370
|
+
landed through PR #81 at commit `0acb5e79` and merge commit `6d1e9536`; PR
|
|
371
|
+
#93 commit `1456b852` established the current strict version.
|
|
372
|
+
2. Human approval: decide whether the importable boundary is a new
|
|
373
|
+
`@hasna/storage-kit` package or an `@hasna/contracts/storage-kit` subpath.
|
|
374
|
+
3. Move generator source into the approved package boundary and add package
|
|
375
|
+
metadata only after approval.
|
|
376
|
+
4. Migrate one consumer cohort at a time:
|
|
377
|
+
`open-loops` plus `open-knowledge` (`0.4.0` cohort),
|
|
378
|
+
`open-projects`/`open-conversations`/`open-mementos`/`open-accounts`
|
|
379
|
+
(`0.4.1` cohort), then
|
|
380
|
+
`open-machines`/`open-configs`/`open-logs` (`0.4.2` cohort).
|
|
381
|
+
5. Remove vendored generated files only after imports, type declarations, and
|
|
382
|
+
package pack contents are stable.
|
|
383
|
+
|
|
384
|
+
Validation:
|
|
385
|
+
|
|
386
|
+
- For the current OpenLoops checkout: `bun run check:contracts`.
|
|
387
|
+
- Per consumer: `bun run typecheck`, targeted storage tests, and package
|
|
388
|
+
boundary/no-cloud tests where present.
|
|
389
|
+
- For OpenLoops: `bun run typecheck`, `bun test src/lib/storage/*.test.ts`,
|
|
390
|
+
`bun run test:boundary`, and `bun run check:contracts`.
|
|
391
|
+
|
|
392
|
+
Blockers:
|
|
393
|
+
|
|
394
|
+
- Human approval for package name and ownership.
|
|
395
|
+
- Publish step and Bun release-age exclusion updates are out of scope until
|
|
396
|
+
approval.
|
|
397
|
+
- Consumers currently depend on different kit versions; extraction must handle
|
|
398
|
+
version skew explicitly.
|
|
399
|
+
|
|
400
|
+
### 2. `@hasna/app-runtime`
|
|
401
|
+
|
|
402
|
+
Status: medium-confidence candidate; not ready for immediate extraction.
|
|
403
|
+
|
|
404
|
+
Responsibilities:
|
|
405
|
+
|
|
406
|
+
- Resolve app home/data directories from `HASNA_<APP>_...` env keys.
|
|
407
|
+
- Create private directories and DB files with consistent permissions.
|
|
408
|
+
- Provide legacy-dotdir migration helpers.
|
|
409
|
+
- Normalize package-version lookup.
|
|
410
|
+
- Normalize executable PATH helpers for Bun/Node CLIs.
|
|
411
|
+
|
|
412
|
+
Evidence:
|
|
413
|
+
|
|
414
|
+
- `open-loops/src/lib/paths.ts`
|
|
415
|
+
- `open-loops/src/lib/env.ts`
|
|
416
|
+
- `open-todos/src/db/database.ts`
|
|
417
|
+
- `open-projects/src/db/database.ts`
|
|
418
|
+
- `open-projects/src/lib/project-store-paths.ts`
|
|
419
|
+
- `open-conversations/src/lib/db.ts`
|
|
420
|
+
- `open-logs/src/db/index.ts`
|
|
421
|
+
- `open-events/src/storage.ts`
|
|
422
|
+
|
|
423
|
+
Blockers:
|
|
424
|
+
|
|
425
|
+
- App semantics differ: project-local DBs, global DBs, legacy migration,
|
|
426
|
+
private permissions, launchd/systemd paths, and per-workspace stores are not
|
|
427
|
+
uniform.
|
|
428
|
+
- Should probably be a module inside the storage-kit boundary instead of a
|
|
429
|
+
separate package at first.
|
|
430
|
+
|
|
431
|
+
### 3. `@hasna/cli-kit`
|
|
432
|
+
|
|
433
|
+
Status: useful but requires human approval and a compatibility matrix.
|
|
434
|
+
|
|
435
|
+
Responsibilities:
|
|
436
|
+
|
|
437
|
+
- Commander registration helpers for global JSON, version, error envelopes,
|
|
438
|
+
option parsing, and consistent text/JSON output.
|
|
439
|
+
- Optional command module registration pattern.
|
|
440
|
+
- Shared storage command scaffolding where the underlying storage API matches.
|
|
441
|
+
- Shared validation helpers for positive integers, durations, and list flags.
|
|
442
|
+
|
|
443
|
+
Evidence:
|
|
444
|
+
|
|
445
|
+
- `open-loops/src/cli/index.ts`
|
|
446
|
+
- `open-todos/src/cli/index.tsx`
|
|
447
|
+
- `open-todos/src/cli/helpers.ts`
|
|
448
|
+
- `open-projects/src/cli/index.ts`
|
|
449
|
+
- `open-projects/src/cli/commands/storage.ts`
|
|
450
|
+
- `open-configs/src/cli/storage.ts`
|
|
451
|
+
- `open-machines/src/cli/index.ts`
|
|
452
|
+
- `open-events/src/commander.ts`
|
|
453
|
+
|
|
454
|
+
Blockers:
|
|
455
|
+
|
|
456
|
+
- CLI UX differs materially across apps.
|
|
457
|
+
- Some repos use Ink and React, some use plain Commander, and `open-events`
|
|
458
|
+
has both hand-rolled and Commander embedding surfaces.
|
|
459
|
+
- Extracting too early could create a heavy dependency for simple binaries.
|
|
460
|
+
|
|
461
|
+
### 4. Existing `@hasna/events` Adoption Kit
|
|
462
|
+
|
|
463
|
+
Status: no new package needed. Adoption tasks are partially automation-ready,
|
|
464
|
+
but each repo needs a compatibility check.
|
|
465
|
+
|
|
466
|
+
Responsibilities already owned by `@hasna/events`:
|
|
467
|
+
|
|
468
|
+
- Event envelopes.
|
|
469
|
+
- Local event/channel storage.
|
|
470
|
+
- Delivery transports.
|
|
471
|
+
- Filters and replay.
|
|
472
|
+
- Commander command registration through `@hasna/events/commander`.
|
|
473
|
+
|
|
474
|
+
Migration order:
|
|
475
|
+
|
|
476
|
+
1. Document app-local event features that `@hasna/events` does not cover yet.
|
|
477
|
+
2. Preserve `open-loops` route-event behavior separately; it is workflow route
|
|
478
|
+
admission, not generic event recording.
|
|
479
|
+
3. Migrate local webhook implementations only where `@hasna/events` can
|
|
480
|
+
preserve filtering, approval gates, and nonblocking dispatch behavior.
|
|
481
|
+
4. Retire compatibility aliases only with explicit deprecation docs/tests.
|
|
482
|
+
|
|
483
|
+
Blockers:
|
|
484
|
+
|
|
485
|
+
- `open-todos` and `open-conversations` have local webhook/event-hook behavior
|
|
486
|
+
that may not map 1:1 to `@hasna/events`.
|
|
487
|
+
- `open-machines` has mutation approval gates around shared event webhooks.
|
|
488
|
+
- `open-loops` currently uses `events` aliases for route operations, so a
|
|
489
|
+
generic events command group could conflict with existing operator workflows.
|
|
490
|
+
|
|
491
|
+
### 5. Existing `@hasna/logs` Or `@hasna/diagnostics-kit`
|
|
492
|
+
|
|
493
|
+
Status: approval-gated and security-sensitive.
|
|
494
|
+
|
|
495
|
+
Responsibilities to consider:
|
|
496
|
+
|
|
497
|
+
- Structured log line helpers.
|
|
498
|
+
- Log rotation.
|
|
499
|
+
- Redaction primitives.
|
|
500
|
+
- Bounded output/excerpt helpers.
|
|
501
|
+
- Retention report formats.
|
|
502
|
+
|
|
503
|
+
Evidence:
|
|
504
|
+
|
|
505
|
+
- `open-loops/src/daemon/daemon.ts`
|
|
506
|
+
- `open-loops/src/lib/run-receipts.ts`
|
|
507
|
+
- `open-todos/src/lib/retention-cleanup.ts`
|
|
508
|
+
- `open-logs/src/lib/redaction.ts`
|
|
509
|
+
- `open-logs/src/lib/retention.ts`
|
|
510
|
+
- `open-logs/src/lib/rotate.ts`
|
|
511
|
+
|
|
512
|
+
Blockers:
|
|
513
|
+
|
|
514
|
+
- `@hasna/logs` already exists and likely owns much of this domain.
|
|
515
|
+
- Redaction changes require security review and regression fixtures.
|
|
516
|
+
- Log retention is app-specific and should not be centralized until schemas are
|
|
517
|
+
aligned.
|
|
518
|
+
|
|
519
|
+
## Automation Readiness
|
|
520
|
+
|
|
521
|
+
Ready for automation now:
|
|
522
|
+
|
|
523
|
+
- OpenLoops generated storage-kit normalization is complete. Version `0.5.1`
|
|
524
|
+
state normalization landed through PR #81 at commit `0acb5e79` and merge
|
|
525
|
+
commit `6d1e9536`; PR #93 commit `1456b852` established the current strict
|
|
526
|
+
version `0.5.2`. PR #84 is not current normalization evidence and has its own
|
|
527
|
+
disposition. Do not auto-route a duplicate normalization task.
|
|
528
|
+
|
|
529
|
+
Ready after human approval:
|
|
530
|
+
|
|
531
|
+
- Create an importable storage-kit package/subpath.
|
|
532
|
+
- Migrate consumers from vendored generated storage-kit files to imports.
|
|
533
|
+
- Extract a CLI helper package.
|
|
534
|
+
- Define any new `@hasna/*` package name and publish plan.
|
|
535
|
+
|
|
536
|
+
Not ready yet:
|
|
537
|
+
|
|
538
|
+
- Logging/redaction centralization.
|
|
539
|
+
- Retention cleanup centralization.
|
|
540
|
+
- OpenLoops route-event migration.
|
|
541
|
+
- Broad local path/runtime extraction.
|
|
542
|
+
|
|
543
|
+
## Follow-Up Todo Plan
|
|
544
|
+
|
|
545
|
+
Created follow-up task:
|
|
546
|
+
|
|
547
|
+
1. OpenLoops storage-kit normalization.
|
|
548
|
+
Task: `2b166a36-1e7c-4882-be7f-610c4f478d39`
|
|
549
|
+
Fingerprint: `open-loops:p5:shared-kit:storage-kit:open-loops-normalize`
|
|
550
|
+
Dependency: this inventory task.
|
|
551
|
+
Historical output: PR #84 (`https://github.com/hasna/loops/pull/84`).
|
|
552
|
+
Current status: version `0.5.1` state normalization landed through PR #81
|
|
553
|
+
at commit `0acb5e79` and merge commit `6d1e9536`; PR #93 commit `1456b852`
|
|
554
|
+
established the current strict version `0.5.2`. PR #84 is not current
|
|
555
|
+
normalization evidence and has its own disposition.
|
|
556
|
+
|
|
557
|
+
Recommended follow-up tasks that were not created in this worker step:
|
|
558
|
+
|
|
559
|
+
2. Storage-kit package approval checkpoint.
|
|
560
|
+
Fingerprint: `open-loops:p5:shared-kit:storage-kit:approval`
|
|
561
|
+
Dependency: storage-kit normalization evidence.
|
|
562
|
+
Status: human approval required; do not auto-route until approved.
|
|
563
|
+
|
|
564
|
+
3. Events compatibility inventory for OpenLoops route aliases.
|
|
565
|
+
Fingerprint: `open-loops:p5:shared-kit:events:open-loops-compat`
|
|
566
|
+
Dependency: this inventory task and current `@hasna/events` behavior.
|
|
567
|
+
Status: automation-ready as a report/test inventory only; implementation
|
|
568
|
+
should wait until alias compatibility is proven.
|
|
569
|
+
|
|
570
|
+
4. CLI-kit compatibility matrix.
|
|
571
|
+
Fingerprint: `open-loops:p5:shared-kit:cli-kit:matrix`
|
|
572
|
+
Dependency: storage-kit normalization is not required, but human approval is
|
|
573
|
+
needed before package creation.
|
|
574
|
+
Status: report-only unless approved.
|
|
575
|
+
|
|
576
|
+
The first item has already run and must not be auto-routed again. The other
|
|
577
|
+
items remain documented until package ownership or compatibility decisions are
|
|
578
|
+
made.
|
|
579
|
+
|
|
580
|
+
## Validation Requirements For Later Implementation
|
|
581
|
+
|
|
582
|
+
For any follow-up that changes package metadata:
|
|
583
|
+
|
|
584
|
+
- `git diff --check`
|
|
585
|
+
- `bun install --frozen-lockfile` only when lockfile changes require it
|
|
586
|
+
- `bun run typecheck`
|
|
587
|
+
- `bun test`
|
|
588
|
+
- `bun run test:boundary` where present
|
|
589
|
+
- `bun pm pack --dry-run` before publishable package changes
|
|
590
|
+
- Staged secrets scan before commit
|
|
591
|
+
|
|
592
|
+
For storage-kit consumer migrations:
|
|
593
|
+
|
|
594
|
+
- Verify generated-kit or import boundary check.
|
|
595
|
+
- Run per-repo storage tests.
|
|
596
|
+
- Run any local/cloud/no-cloud boundary tests.
|
|
597
|
+
- Validate package export maps and declaration files.
|
|
598
|
+
- Do not remove vendored files until import paths work from a packed package or
|
|
599
|
+
approved workspace dependency.
|
|
600
|
+
|
|
601
|
+
For event adoption:
|
|
602
|
+
|
|
603
|
+
- Verify CLI help and JSON output for `events`/`channels` commands.
|
|
604
|
+
- Preserve local webhook filtering, nonblocking behavior, and approval gates.
|
|
605
|
+
- Add regression tests for legacy aliases before retiring them.
|
|
606
|
+
|
|
607
|
+
For logging/redaction:
|
|
608
|
+
|
|
609
|
+
- Add canary tests for tokens, URL userinfo, auth headers, query params, and
|
|
610
|
+
secret-looking assignment strings.
|
|
611
|
+
- Confirm no raw secrets appear in task comments, logs, receipts, event
|
|
612
|
+
envelopes, or API responses.
|
|
613
|
+
|
|
614
|
+
## Human Approval And Publishing Blockers
|
|
615
|
+
|
|
616
|
+
- New package names require approval before package metadata, npm publish, or
|
|
617
|
+
Bun release-age exclusion edits.
|
|
618
|
+
- `@hasna/storage-kit` vs `@hasna/contracts/storage-kit` is an ownership
|
|
619
|
+
decision.
|
|
620
|
+
- `@hasna/cli-kit` must not centralize repo-specific prompt-mode or Ink UI
|
|
621
|
+
behavior without a compatibility matrix.
|
|
622
|
+
- `@hasna/logs` ownership must be resolved before creating diagnostics or
|
|
623
|
+
redaction packages.
|
|
624
|
+
- No consumer migration should be routed until the package boundary and package
|
|
625
|
+
source of truth are approved.
|
|
626
|
+
|
|
627
|
+
## Naming Note (2026-07-21)
|
|
628
|
+
|
|
629
|
+
The current product display name is **Loops**. The dated inventory above retains
|
|
630
|
+
its historical naming as provenance, and compatibility identifiers remain
|
|
631
|
+
unchanged.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Transcript-Driven Loop Patterns
|
|
2
2
|
|
|
3
|
-
This guide turns long-form transcripts, meeting recordings, interviews, and product feedback videos into durable
|
|
3
|
+
This guide turns long-form transcripts, meeting recordings, interviews, and product feedback videos into durable Loops work. It pairs `iapp-transcriber` for media ingestion with Loops workflows for recurring review, implementation, and verification.
|
|
4
4
|
|
|
5
|
-
The pattern came from reviewing a Claude Code fireside chat transcript. The useful operational takeaway was not just "use agents more"; it was that recurring agents need narrow scope, evidence, review gates, and clear ROI. In
|
|
5
|
+
The pattern came from reviewing a Claude Code fireside chat transcript. The useful operational takeaway was not just "use agents more"; it was that recurring agents need narrow scope, evidence, review gates, and clear ROI. In Loops terms, that means using workflows and goals to move from transcript insight to scheduled loop safely.
|
|
6
6
|
|
|
7
7
|
## Baseline Workflow
|
|
8
8
|
|
|
@@ -20,7 +20,7 @@ The transcribe step writes `.openloops/transcripts/latest-transcript.json`. The
|
|
|
20
20
|
|
|
21
21
|
The workflow includes non-shell `check-transcriber` and `check-loops` command steps so `loops workflows validate --preflight` can catch those missing CLIs. Shell command bodies, provider credentials, and media access are still checked by the transcriber step at runtime.
|
|
22
22
|
|
|
23
|
-
The ingestion template intentionally does not wrap the whole workflow in
|
|
23
|
+
The ingestion template intentionally does not wrap the whole workflow in a Loops goal. Goal wrappers execute the underlying target for each ready goal-plan node, which is useful for implementation workflows but too surprising for media ingestion. Use goals in the generated follow-up workflows after the transcript has been converted into a concrete backlog.
|
|
24
24
|
|
|
25
25
|
Schedule the workflow only after a manual run produces useful backlog items:
|
|
26
26
|
|