Skip to content

Runtime batch 2: task progress, retained logs, Sentry, leases, in-process outbox (#536 #537 #538 #539 #565) - #573

Merged
antosubash merged 30 commits into
mainfrom
feat/runtime-batch-2
Oct 22, 2026
Merged

antosubash merged 30 commits into
mainfrom
feat/runtime-batch-2

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Runtime batch 2: task progress, retained logs, optional Sentry, distributed leases, and an in-process outbox. Design: docs/superpowers/specs/2026-10-21-runtime-batch-2-design.md.

What changes

The migration graph test now covers the new leases root and the background_tasks revisions.

Verification

  • make lint ✓
  • make test-py: 5382 passed, 36 skipped ✓
  • make test-js: 676 passed ✓
  • make ci-doctor ✓
  • uv lock --check ✓
  • locale check ✓

The Redis variants of the lease tests run only in CI (no local redis-server).

/ship

Closes #536
Closes #537
Closes #538
Closes #539
Closes #565

https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

heartbeat(progress=, message=, phase=) buffers under the existing throttle;
TaskExecution gains progress_* and an indexed owner_user_id stamped from the
sm_owner_id header (propagated through tasks that enqueue tasks, kept on
retry). GET /api/background_tasks/tasks/{id}/status is readable by the owner
in the active tenant or PERM_VIEW holders, 404 otherwise. Migration
bb906e1a1089.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
simple_module_core.leases: lease(name, ttl, owner=None) handle with token,
strictly increasing fence, refresh()/release() and an async context manager
(blocking/wait); semaphore(name, slots, ttl); LeaseBackend Protocol,
InProcessLeaseBackend and configure_leases()/get_leases().

Backends: Redis (SET NX PX, Lua compare-and-set refresh/release, semaphore
ZSET scored by Redis TIME, INCR fence) in simple_module_hosting; the
framework-owned sm_lease table (DB clock, ON CONFLICT claims) in
simple_module_db with migration d263ea727663, a new root labelled
"leases". create_app and the Celery worker bootstrap select Redis, else
the table, else in-process. An expired owner can neither refresh nor
release.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
# Conflicts:
#	CHANGELOG.md
#	host/tests/test_migration_graph.py
# Conflicts:
#	CHANGELOG.md
#	docs/.vitepress/config.ts
#	framework/hosting/simple_module_hosting/app_builder.py
# Conflicts:
#	CHANGELOG.md
#	modules/background_tasks/background_tasks/constants.py
Opt-in DB log sink (log_sink_enabled), LogSink/QueueSinkHandler in hosting,
Logs tab + admin Logs page, retention in purge_old_executions.
Migration 1f5985daa10b.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
# Conflicts:
#	modules/background_tasks/background_tasks/constants.py
#	modules/background_tasks/background_tasks/module.py
#	modules/background_tasks/background_tasks/tasks.py
- Every event field now goes through the recursive pass (tags, server_name,
  top-level stacktrace, threads, unknown future fields), not a field list.
- Key matching: pwd/passphrase/jwt/bearer/card words, whole-word
  auth/pass/otp/pin/sid/sig/ssn/cvv/mfa, camelCase-aware (basicAuth).
- [key, value] pairs in header/query lists, bytes values, quoted values with
  spaces, escaped JSON, whole Cookie:/Authorization: lines, userinfo with
  '@' or '/' in the password, JWTs and bare 32+ char tokens are redacted;
  db.params and frame vars dropped anywhere; user reduced to id.
- The old key=value regex was quadratic (20 KB string: 72 s in before_send);
  all patterns are now boundary-anchored and bounded, strings capped at 64 KiB.
- before_send drops the event if tagging/scrubbing raises, logging only the
  exception type.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
…ined-log sink

log_sinks.redact() now uses sentry_scrub_text.scrub_text so URL passwords with
@ or /, quoted values, escaped JSON, JWTs, long tokens and Cookie lines are
masked identically on both paths; hosting tests no longer leak the Sentry flag.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
# Conflicts:
#	CHANGELOG.md
#	modules/background_tasks/background_tasks/locales/en.json
… lease key namespaces

Structured extras (dicts/lists/objects) bypassed redaction in the retained-log
sink; they now go through the Sentry recursive scrubber. Redis holder and fence
keys use separate prefixes so a lease named 'foo:fence' cannot collide with
foo's counter. Also makes the Sentry route test independent of the git sha
embedded in the release field.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
Resolve background_tasks conflicts keeping both sides: worker DB timeout
settings (WorkerDatabaseSettings) alongside LogSinkFields/outbox_mode;
runner configures DB options before leases and settings hydration, then
re-applies them and installs the log sink; main's configure_database
folded into _lifecycle.startup. CHANGELOG keeps all entries.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-10-22T08:16:11.330792Z 7ab7a38 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 24bef27
Status: ✅  Deploy successful!
Preview URL: https://f1631639.simple-module-python.pages.dev
Branch Preview URL: https://feat-runtime-batch-2.simple-module-python.pages.dev

View logs

CI's xdist workers share one Redis service; the teardown pattern sm:*:t-*
deleted another worker's live semaphore, letting all 8 waiters in.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
re.match with $ accepted "ValueError\n"; use fullmatch. The too-long test
case could not be stored on Postgres (varchar(255)); replace it with
newline cases that can.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
@antosubash
antosubash merged commit 976036f into main Oct 22, 2026
17 checks passed
@antosubash
antosubash deleted the feat/runtime-batch-2 branch October 22, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment