@hasna/loops 0.4.27 → 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.
Files changed (79) hide show
  1. package/CHANGELOG.md +205 -1
  2. package/README.md +232 -49
  3. package/dist/api/index.d.ts +20 -19
  4. package/dist/api/index.js +7770 -1342
  5. package/dist/cli/index.js +2976 -966
  6. package/dist/cli/safe-error-context.d.ts +1 -0
  7. package/dist/daemon/daemon.d.ts +1 -0
  8. package/dist/daemon/index.js +1899 -499
  9. package/dist/generated/storage-kit/index.d.ts +1 -1
  10. package/dist/generated/storage-kit/mode.d.ts +6 -12
  11. package/dist/index.d.ts +3 -3
  12. package/dist/index.js +5319 -1096
  13. package/dist/lib/advancement.d.ts +52 -0
  14. package/dist/lib/agent-adapter.d.ts +20 -2
  15. package/dist/lib/auth/route-policy.d.ts +14 -0
  16. package/dist/lib/auth/tenant-auth.d.ts +38 -0
  17. package/dist/lib/cloud/mode.d.ts +2 -8
  18. package/dist/lib/cloud/storage.d.ts +1 -2
  19. package/dist/lib/cloud/transport.d.ts +4 -18
  20. package/dist/lib/errors.d.ts +43 -1
  21. package/dist/lib/executor.d.ts +9 -0
  22. package/dist/lib/format.d.ts +2 -2
  23. package/dist/lib/goal/runner.d.ts +36 -3
  24. package/dist/lib/health.d.ts +1 -1
  25. package/dist/lib/labels.d.ts +4 -0
  26. package/dist/lib/loop-status.d.ts +4 -0
  27. package/dist/lib/migration.d.ts +70 -17
  28. package/dist/lib/mode.d.ts +2 -5
  29. package/dist/lib/mode.js +28 -37
  30. package/dist/lib/route/fields.d.ts +8 -0
  31. package/dist/lib/route/index.d.ts +2 -2
  32. package/dist/lib/route/throttle.d.ts +7 -0
  33. package/dist/lib/route/types.d.ts +3 -0
  34. package/dist/lib/run-completion.d.ts +18 -0
  35. package/dist/lib/scheduler.d.ts +5 -11
  36. package/dist/lib/storage/contract.d.ts +15 -1
  37. package/dist/lib/storage/index.d.ts +1 -1
  38. package/dist/lib/storage/index.js +4083 -486
  39. package/dist/lib/storage/pg-executor.d.ts +10 -5
  40. package/dist/lib/storage/postgres-loop-storage.d.ts +52 -26
  41. package/dist/lib/storage/postgres-schema.d.ts +8 -0
  42. package/dist/lib/storage/postgres-schema.js +1326 -1
  43. package/dist/lib/storage/postgres.d.ts +3 -1
  44. package/dist/lib/storage/postgres.js +1356 -27
  45. package/dist/lib/storage/provider-credentials.d.ts +84 -0
  46. package/dist/lib/storage/shared-database-transfer.d.ts +136 -0
  47. package/dist/lib/storage/sqlite.d.ts +15 -2
  48. package/dist/lib/storage/sqlite.js +1379 -217
  49. package/dist/lib/storage/tenant-backfill-s3.d.ts +53 -0
  50. package/dist/lib/storage/tenant-backfill.d.ts +40 -0
  51. package/dist/lib/store/index.d.ts +14 -8
  52. package/dist/lib/store.d.ts +129 -7
  53. package/dist/lib/store.js +1352 -218
  54. package/dist/lib/templates.d.ts +11 -0
  55. package/dist/lib/workflow-events.d.ts +6 -0
  56. package/dist/lib/workflow-provenance.d.ts +8 -0
  57. package/dist/lib/workflow-runner.d.ts +52 -4
  58. package/dist/mcp/index.js +2074 -657
  59. package/dist/runner/index.d.ts +20 -2
  60. package/dist/runner/index.js +2146 -183
  61. package/dist/sdk/http.d.ts +364 -4
  62. package/dist/sdk/http.js +379 -1
  63. package/dist/sdk/index.d.ts +7 -2
  64. package/dist/sdk/index.js +2341 -742
  65. package/dist/serve/index.d.ts +14 -0
  66. package/dist/serve/index.js +13269 -1830
  67. package/dist/types.d.ts +75 -3
  68. package/docs/AUTOMATION_RUNTIME_DESIGN.md +32 -32
  69. package/docs/CUTOVER-RUNBOOK.md +158 -31
  70. package/docs/DEPLOYMENT_MODES.md +84 -56
  71. package/docs/RUNTIME_BOUNDARY.md +26 -26
  72. package/docs/SHARED-DATABASE-TRANSFER.md +95 -0
  73. package/docs/SHARED_KIT_EXTRACTION_INVENTORY.md +631 -0
  74. package/docs/TRANSCRIPT_LOOP_PATTERNS.md +3 -3
  75. package/docs/UNIFIED_PRODUCT_CONTRACT.md +365 -0
  76. package/docs/USAGE.md +150 -56
  77. package/docs/workflows/transcript-feedback-to-loops.json +2 -2
  78. package/package.json +8 -4
  79. package/dist/lib/storage/pg-runner-claim.d.ts +0 -40
package/CHANGELOG.md CHANGED
@@ -1,10 +1,83 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to OpenLoops (npm `@hasna/loops`, repo `hasna/loops`) are
3
+ All notable changes to Loops (npm `@hasna/loops`, repo `hasna/loops`) are
4
4
  documented in this file. Version entries are generated from the
5
5
  conventional-commit git history; one commit maps to one released patch version
6
6
  unless noted.
7
7
 
8
+ ## 0.4.29 (2026-07-21)
9
+
10
+ This source release gives the post-`npm/loops/v0.4.28` code line a new,
11
+ unambiguous package, OpenAPI, and generated HTTP SDK identity.
12
+
13
+ ### Added
14
+
15
+ - **Tenant-bound authentication and PostgreSQL row isolation:** migrations
16
+ `0008_tenant_prepare`, `0009_tenant_backfill`, and
17
+ `0010_tenant_enforce` add tenant/principal/membership/API-key state, require
18
+ an explicit complete tenant assignment before enforcement, and install the
19
+ closed-world owner/migrator/runtime/authenticator role model with
20
+ tenant-scoped privileges and RLS. The API now validates tenant-bound keys,
21
+ roles, scopes, and token kinds and emits structured denial evidence.
22
+ - **Tenant migration operations:** encrypted tenant-backfill delivery,
23
+ provider credential reconciliation, PostgreSQL 16 bootstrap membership
24
+ gates, and protected shared-database transfer tooling now support rehearsed,
25
+ auditable cutovers without command overrides or unverified TLS targets.
26
+ - **Runner and workflow execution:** long-running runner readiness and workflow
27
+ execution are implemented, with operator recovery, replayable advancement,
28
+ workflow-definition provenance in `0011_workflow_run_provenance`, and loop
29
+ labels in `0012_loop_labels`.
30
+
31
+ ### Changed
32
+
33
+ - **Product identity:** user-facing product and documentation naming is now
34
+ **Loops**, while published compatibility identifiers and paths such as
35
+ the legacy uppercase environment-variable namespace, `open_loops`,
36
+ `.openloops`, `openloops`, `runtimeOwner`, MCP identifiers, project slugs,
37
+ and the `loops-api` compatibility binary/waiver remain stable.
38
+ - **Runtime and supply chain:** the runtime image now uses pinned Bun Alpine
39
+ packages, runs the runner as non-root, pins CI actions, adds a protected ECR
40
+ candidate workflow, and fails closed on high-severity or malformed scan
41
+ results. Packed artifacts are checked for private-host leakage, branding
42
+ regressions, storage-kit drift, and contract conformance.
43
+ - **Public contracts:** the OpenAPI document and generated HTTP SDK cover the
44
+ expanded tenant, runner, workflow, recovery, labels, count, archive, and
45
+ operational surfaces. MCP output is bounded, and public or persisted
46
+ workflow output is scrubbed before truncation.
47
+
48
+ ### Fixed
49
+
50
+ - **Agent boundaries:** Codewith auth profiles are resolved from exact
51
+ JSON-first inventory, unusable or malformed profiles and extra arguments
52
+ fail closed, session creation is atomic, root agent directories are rejected,
53
+ route agent allowlists propagate correctly, and Cursor provider/retry
54
+ handling no longer weakens trust boundaries.
55
+ - **API and claim safety:** tenant error compatibility is preserved while
56
+ runner endpoints, route admission, loop updates, runner clocks, local claims,
57
+ recovery snapshots, and persisted workflow/session contracts reject
58
+ ambiguous, stale, or cross-boundary state.
59
+ - **Archive and finalization:** ambiguous archive names fail closed and resolve
60
+ against target state; PostgreSQL finalization conflicts are enforced
61
+ directly; SQLite generated-route finalization matches PostgreSQL behavior;
62
+ and public CLI errors and pagination avoid leaking unsafe context.
63
+ - **Recovery and advancement:** workflow recovery ownership is fenced,
64
+ advancement is unified across schedulers, replay is idempotent, successor and
65
+ completion parity gaps are closed, and recovery cannot double-claim local
66
+ work or regenerate already-finalized routes.
67
+ - **Security boundaries:** private and encoded infrastructure hostnames are
68
+ removed from publishable output, encoded separator bypasses are rejected,
69
+ trusted contracts and legacy events are validated, and the shared transfer
70
+ gate accepts only verified TLS DSNs.
71
+
72
+ ### Upgrade warning
73
+
74
+ - **`0010_tenant_enforce` is a rollback boundary.** After this migration is
75
+ applied, the immutable published `0.4.28` image cannot pass readiness because
76
+ it does not contain the `0008`-`0010` tenant migration lineage. Do not roll
77
+ the binary back in place. Recovery requires rolling forward to `0.4.29` or a
78
+ later compatible image, or restoring the rehearsed pre-cutover database
79
+ target before starting the older image.
80
+
8
81
  ## 0.4.26
9
82
 
10
83
  ### Fixed
@@ -19,6 +92,16 @@ unless noted.
19
92
 
20
93
  ## Unreleased
21
94
 
95
+ ### Fixed
96
+
97
+ - **Codewith auth-profile preflight:** use JSON-first exact profile matching for
98
+ local and remote runs. Root `data`/`profiles` entries are authoritative:
99
+ `usable: false` is rejected, legacy entries without `usable` remain accepted,
100
+ and `currentProfile` does not add inventory membership. Human-table parsing,
101
+ including active `*` rows, is used only when JSON mode is unsupported or its
102
+ inventory is structurally unavailable. NUL-containing names, missing
103
+ profiles, and non-fallback profile-list failures fail closed.
104
+
22
105
  ### Added
23
106
 
24
107
  - `loops-mcp` now serves a shared Streamable HTTP transport (default
@@ -42,6 +125,127 @@ unless noted.
42
125
  execution over the runner protocol, and id-preserving remote import remain
43
126
  follow-up work.
44
127
 
128
+ ## 0.4.18 (2026-07-07/08)
129
+
130
+ Drain reliability: kill the todos-task redispatch "black hole" family, then the
131
+ merge-lane routing wedge and the schema-lockout class behind it. One artifact
132
+ consolidates the whole independently-reviewed family: #82 (dead-letter at the
133
+ cap + attempt refunds + requeue reset + worktree self-heal), #88 (per-task
134
+ repository routing + candidate-window memory), #89 (schema-compat soft-open +
135
+ gate-death ceiling), plus the previously unpublished 0.4.15–0.4.17 ride-alongs
136
+ documented below.
137
+
138
+ ### Fixed
139
+
140
+ - **Merge-lane wedge — the task's own repository wins over a group-root
141
+ `--project-path`:** commit 8ab2664 made the router-level `--project-path` win
142
+ unconditionally in todos-task drains, so multi-repo routers that pass it as a
143
+ concurrency group root (a non-repository directory such as the operator's
144
+ home) sent every task to the group root and skipped it (`worktreeMode=required
145
+ but projectPath is not an existing git repository`), zeroing merge dispatch
146
+ fleet-wide. A drain
147
+ now routes each task to its own first *usable* repository path (explicit
148
+ `project_path`, metadata, the description's `Repository:` line, then
149
+ `working_dir` — first that is a real git repo, probed once per path per tick);
150
+ the router-level `--project-path` remains the rescue fallback for tasks whose
151
+ recorded path is stale or broken (8ab2664's original intent). Registry drains
152
+ are unchanged (the scanned source project still wins; task-controlled fields
153
+ cannot redirect a route).
154
+ - **Route-disallowed tasks no longer burn the candidate window:** tasks bearing
155
+ `no-auto`/`blocked`/`manual`-class tags can never route, but each occupied one
156
+ of the bounded candidate rows every tick just to be rejected by eligibility —
157
+ enough marked tasks starved a drain into `considered=N created=0` forever.
158
+ They are now held out of the window before slicing (unless the drain's own
159
+ `--tags` explicitly selects that tag) and counted as `excludedDisallowedTag`
160
+ in drain reports, so the exclusion is auditable.
161
+ - **Deterministic gate deaths are bounded by a secondary ceiling:** gate deaths
162
+ (runs that fail at worktree prep or a fast triage/planner gate before any real
163
+ work) refund their redispatch attempt — correct for transient faults, but a
164
+ deterministic fault would retry forever at the backoff floor. Work items now
165
+ count consecutive gate deaths (`gate_deaths`, additive migration
166
+ `0011_work_item_gate_deaths`, no schema `user_version` bump); at the ceiling
167
+ (20) the item is dead-lettered — visible in drain reports — instead of
168
+ spinning, and the bounded route re-admission will not requeue it. A
169
+ productive failure or an `exit 75` tempfail (runs that reached the worker)
170
+ resets the streak; `loops routes requeue` (default attempts reset) re-arms
171
+ the full ceiling. Known gap (review finding N1; fix queued for the next
172
+ patch): a non-closing SUCCESS does not yet reset the streak — bounded and
173
+ safe (it errs toward a recoverable early dead-letter, and the redispatch cap
174
+ independently bounds chronically non-closing successes).
175
+ - **Redispatch cap no longer a silent black hole** (the original #82 core: a
176
+ still-actionable task whose runs kept finishing without closing it was
177
+ deduped forever once its attempt count reached the cap): when a todos-task
178
+ work item reaches `MAX_TODOS_TASK_ROUTE_REDISPATCHES` (8) it is transitioned
179
+ to a visible `dead_letter` state instead of being deduped forever with no
180
+ signal. Drain reports gain a `deadLettered` count (and the deduped result
181
+ carries `deadLettered: true` + the reason), so a capped task is surfaced and
182
+ an operator can requeue it rather than the drain silently reporting
183
+ `created=0`.
184
+ - **Gate deaths no longer count toward the cap:** a run that dies before doing
185
+ real work — worktree preparation failure, or a fast (`<60s`) `triage`/`planner`
186
+ gate failure — has its attempt refunded by `finalizeWorkflowRun`, so an infra
187
+ fault cannot dead-letter a task that never reached its worker.
188
+ - **`exit(75)` tempfail is requeueable, not dedupe-bait:** a step that exits 75
189
+ (`EX_TEMPFAIL`, "retry later") drops its work item back to `queued` with the
190
+ attempt refunded, so the "retry next tick" contract fires instead of leaving a
191
+ terminal row that counts toward the cap.
192
+ - **`loops routes requeue` resets attempts by default:** an operator unwedge is
193
+ now durable rather than one-shot (a capped item no longer re-caps after a
194
+ single further terminal run). `--keep-attempts` preserves the count for the
195
+ cautious path; the bounded route-path re-admission still preserves attempts so
196
+ the cap keeps working.
197
+ - **Executor self-heals a stale worktree registration:** on git's "missing but
198
+ already registered worktree" error, `ensureLocalWorktree` (and the remote
199
+ worktree-prep script) now runs `git worktree prune` and retries the add exactly
200
+ once — git's own prescribed remedy — before failing honestly. This removes the
201
+ single biggest burner of the redispatch cap at its source.
202
+
203
+ ### Changed
204
+
205
+ - **Newer-schema databases soft-open when the delta is non-breaking:** an older
206
+ binary used to refuse ANY database with a newer `PRAGMA user_version` — during
207
+ the 2026-07-07 schema-8 lockout that bricked the whole CLI fleet over purely
208
+ additive migrations. The database now carries a compatibility floor
209
+ (`schema_compat.min_compatible_user_version`, raised only by BREAKING
210
+ migrations; additive ones leave it untouched): a binary opens any newer
211
+ database whose floor it meets, preserves the newer `user_version` stamp
212
+ (never downgrades it), and refuses only on a known-breaking delta or when the
213
+ floor row is absent (pre-contract/unblessed databases stay conservative).
214
+
215
+ ## 0.4.15 – 0.4.17 (2026-07-06/07 — unpublished; first shipped with 0.4.18)
216
+
217
+ These three versions were committed to `main` with version bumps but never
218
+ published to npm individually; the 0.4.18 release is the first registry artifact
219
+ that carries them. Consolidated here so the published history stays honest.
220
+
221
+ ### Added
222
+
223
+ - **0.4.15** — self-hosted client mode: the CLI routes loop reads/writes to the
224
+ hosted `/v1` API when `self_hosted` mode is configured (#74).
225
+ - **0.4.16** — id-preserving bulk import endpoint (`POST /v1/import`) for
226
+ self-hosted backfill, plus `loops self-hosted push --apply` in the CLI (#76).
227
+ - **0.4.17** — `GET /v1/loops/count` and `GET /v1/runs/count` endpoints (#77).
228
+ - Run receipt contract: run receipts table + API surface for verifiable run
229
+ evidence (`migrations/0005_run_receipts.sql` mirror).
230
+
231
+ ### Changed
232
+
233
+ - **SQLite schema `user_version` 7 → 8** via ledger migrations
234
+ `0009_run_receipts` and `0010_work_item_machine_id` (additive; applied
235
+ automatically on first open). NOTE: binaries older than this range refuse to
236
+ open a migrated database ("schema version 8 is newer than this binary
237
+ supports"), so downgrading below 0.4.15 after opening a database with this
238
+ release requires restoring a pre-upgrade backup. A version-tolerance softening
239
+ (open unless a known-breaking delta) is planned follow-up work.
240
+ - Launch-gated route drains: `--launch-gate`/`--launch-gate-blocker` hold a
241
+ drain closed until named blocker tasks are completed.
242
+
243
+ ### Fixed
244
+
245
+ - codewith agent JSON output parsing (#17).
246
+ - PR handoff: no-remote fallback repaired and handoff artifact errors scrubbed
247
+ from templates.
248
+
45
249
  ## 0.4.14 (2026-07-06)
46
250
 
47
251
  Self-hosted control-plane service brought to the full Hasna standard: all four