Skip to content

feat(runtime): keep run attributes public and secrets beside the log - #35

Closed
dylnslck wants to merge 10 commits into
mainfrom
feat/run-context
Closed

dylnslck wants to merge 10 commits into
mainfrom
feat/run-context

Conversation

@dylnslck

Copy link
Copy Markdown
Contributor

Summary

  • Runs accept immutable attributes (tenant, project, org). They are stored on runtime.run.started, folded into run state and the run summary, and passed to authorize when a run has any.
  • secrets live in a side store (looms_run_secrets on SQLite, a separate map in memory). Effect handlers read ctx.secrets, and an in-process worker receives them on the dispatch task. Events, snapshots, summaries, and HTTP responses do not include them.
  • A retry may omit secrets and keeps the stored context. A different context conflicts without echoing the values. Forks and effect-launched runs inherit both attributes and secrets. A store that cannot persist secrets rejects a start that supplies them.

Test plan

  • bun x tsc -p packages/core/tsconfig.build.json --noEmit
  • bun x tsc -p packages/runtime/tsconfig.build.json --noEmit
  • bun x tsc -p packages/client/tsconfig.build.json --noEmit
  • bun x tsc -p packages/react/tsconfig.build.json --noEmit
  • bun x tsc -p packages/s2/tsconfig.build.json --noEmit
  • bun test src in packages/core, packages/runtime, packages/react, packages/client, packages/s2, and packages/cloudflare
  • bun x oxlint on the changed sources with --deny-warnings
  • bun run verify for the full workspace (not run here; the package checks above cover the touched packages)

Made with Cursor

dylnslck and others added 10 commits October 23, 2026 10:13
BREAKING CHANGE: POST /runs/:runId/effects/:effectId/:attempt/:action returns { status, cancelRequested } instead of the run state. createLooms().workerCallback and the HTTP client return the same shape. Heartbeats may carry details that the next attempt's task includes. failEffect and worker fail callbacks can mark an attempt non-retryable or set retryAfterMs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Attributes are immutable labels on the start event, run state, and summary, and authorization can see them. Secrets stay in a side store for handlers and in-process dispatch, and are kept out of events, snapshots, and HTTP responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
…full fold

Run attributes are immutable and recorded on runtime.run.started, so authorization reads seq 1 and only falls back to loading the run when the log is trimmed. Store failures now fail the request instead of authorizing without attributes. Also fixes the start-body attribute decode, which did not type-check.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…text

A transport that persists tasks cannot carry secrets, so its worker needs another way to read them. POST /runs/:runId/effects/:effectId/:attempt/secrets returns the secret context only while that attempt is started and unsettled, and stale or cancelled otherwise. It uses worker access, so it stays closed until the host configures worker auth, and responses are not cacheable. client.workerSecrets wraps it.

Co-authored-by: Cursor <cursoragent@cursor.com>
The retry is scheduled from the wake's clock, which is read before the event timestamp, so comparing against the event could fail by a millisecond. The assertion also no longer skips when the payload is missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dylnslck

Copy link
Copy Markdown
Contributor Author

Superseded by squash-merge of the stack tip (#46), which already includes this change set after #34 landed on main.

@dylnslck dylnslck closed this Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant