Skip to content

chore(release): pending release v0.42.0#546

Merged
marcusrbrown merged 7 commits into
releasefrom
next
Apr 25, 2026
Merged

chore(release): pending release v0.42.0#546
marcusrbrown merged 7 commits into
releasefrom
next

Conversation

@fro-bot
Copy link
Copy Markdown
Contributor

@fro-bot fro-bot Bot commented Apr 25, 2026

Pending Release: v0.42.0

This PR tracks changes pending release. Released on the next auto-release cycle (Sunday/Wednesday) or via manual dispatch.

Merge this PR to trigger a release. Releases also run automatically on Sunday/Wednesday at 20:00 UTC, or via manual workflow dispatch.

Commits Since Last Release


Auto-generated by the release pipeline. Updated: 2026-04-25 21:42 UTC

Copilot AI and others added 2 commits April 22, 2026 20:20
…536)

* Initial plan

* fix(deps): pin vite to 7.3.2 to remediate dependabot alerts

Agent-Logs-Url: https://github.com/fro-bot/agent/sessions/cb8b43fb-72a0-49dc-83f6-9fd440873d6d

* chore: finalize vite alert remediation status

Agent-Logs-Url: https://github.com/fro-bot/agent/sessions/cb8b43fb-72a0-49dc-83f6-9fd440873d6d

* chore: revert unintended dist artifact churn

Agent-Logs-Url: https://github.com/fro-bot/agent/sessions/cb8b43fb-72a0-49dc-83f6-9fd440873d6d

* build(dist): sync bundled output after vite override

Agent-Logs-Url: https://github.com/fro-bot/agent/sessions/cb8b43fb-72a0-49dc-83f6-9fd440873d6d

* fix(deps): apply vite override via workspace and lockfile

Agent-Logs-Url: https://github.com/fro-bot/agent/sessions/cb8b43fb-72a0-49dc-83f6-9fd440873d6d

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* chore(workspace): scaffold pnpm workspace + project references

* feat(runtime): extract object-store to packages/runtime

* feat(runtime): extract session to packages/runtime

* feat(runtime): extract shared utilities to packages/runtime

* refactor(runtime): localize shared imports in extracted modules

* feat(runtime): extract agent types to packages/runtime

* feat(runtime): extract agent prompts to packages/runtime

* feat(runtime): extract agent execution to packages/runtime

* feat(runtime): extract agent server with SetupAdapter to packages/runtime

* feat(runtime): lift comments error-format

* feat(runtime): lift HydratedContext TriggerContext EventType

* feat(runtime): update Group Y imports and tsdown

* build: rebuild dist/ after workspace extraction

* build: rebuild dist/ after workspace extraction

* build: fix tsdown config split — restore root config, add runtime config

* fix: address PR review feedback (#541)

- Define SetupInputs locally in packages/runtime (breaks cross-package import)
- Import TriggerContext/EventType/TriggerTarget from runtime's own types
- Remove GitHubContext dependency from test (TriggerContext.raw is unknown)
- Add default return to getRunnerOS() for exhaustive platform handling
- Remove duplicate RETRY_DELAYS_MS from constants.ts (canonical in retry.ts)
- Fix dead appendMode if/else branch in buildTaskSection
- Restore CWE-377/378 and SSRF/IAM security rationale comments
- Use path.resolve/normalize instead of URL constructor in discovery.ts
- Add test for getRunnerOS() default/unknown platform case
- Clean up stale re-exports (LLM_RETRY_DELAY_MS, RETRY_DELAYS_MS)

* chore: remove stale apps/action/dist/ (action entry point is dist/ at root)

* fix(deps): pin fast-xml-parser >=5.7.0 to resolve CVE-2026-41650

* chore: update build artifacts
…es (#547)

* feat(coordination): add S3-backed lock, run-state, heartbeat primitives

Implements Gateway v1 Plan Unit 2: coordination layer for distributed
execution over object-store semantics.

Coordination primitives (packages/runtime/src/coordination/):
- Lock: acquire with ifNoneMatch, stale takeover with ifMatch, release,
  renew lease, force-release for operator recovery
- Run-state: create, phase transitions with optimistic concurrency,
  stale-run detection that skips corrupted entries
- Heartbeat: interval-based lease renewal with overlap guard, transient
  error recovery, lease-first ordering to prevent split-brain
- Self-test: startup probe validates both ifNoneMatch and ifMatch
  provider semantics before allowing coordination

ObjectStoreAdapter extension (packages/runtime/src/object-store/):
- conditionalPut (ifNoneMatch/ifMatch), conditionalDelete (ifMatch),
  getObject — all optional, with runtime adapter guards
- ContentType expanded with 'locks' and 'runs'

Review fixes applied:
- Lock takeover race returns acquired:false instead of throwing
- acquireLock returns Result<> for consistent error handling
- tickError cleared on successful tick (no permanent stop failure)
- Overlapping tick guard prevents concurrent S3 writes
- Runtime field validation on JSON parse (blocks NaN/malformed locks)
- findStaleRuns skips bad entries instead of aborting entire scan
- Self-test validates ifMatch semantics (not just ifNoneMatch)
- Cleanup error no longer shadows semantics failure in self-test
- isStale boundary uses <= (lock expires AT ttl, not after)
- Heartbeat renews lease before writing heartbeat (fail-safe ordering)
- Shared adapter-guards.ts eliminates cross-file duplication

* chore: rebuild dist after coordination primitives

* fix(coordination): decouple heartbeat lifecycle from terminal run state

Address PR #547 review findings:

heartbeat.stop() no longer writes phase: 'FAILED'. The heartbeat owns
liveness only; the caller owns the run lifecycle. stop() quiesces the
timer, awaits in-flight ticks, and returns Result<{runEtag, runState,
lockEtag}, Error>. Callers use the returned snapshot to issue their own
transitionRun(COMPLETED|FAILED|CANCELLED).

Result-returning functions in lock and run-state no longer throw when
the adapter is missing optional methods. New resolveConditionalDelete
helper in adapter-guards mirrors the existing resolveConditionalPut /
resolveGetObject pattern. releaseLock, forceReleaseLock, renewLease,
createRun, transitionRun, findStaleRuns, and validateProviderSemantics
all return err(...) instead of unhandled rejection.

Self-test now validates ifMatch on DELETE in addition to ifNoneMatch
and ifMatch on PUT — catches providers that accept unconditional
deletes (notably historical R2 behavior). Probe key uses
buildObjectStoreKey for consistent prefix validation and key
sanitization. Cleanup error remains subordinate to semantics errors.

transitionRun drops the redundant local etag equality check —
S3's IfMatch on the conditional write is the single concurrency gate.

Tests cover all new error paths: adapter without conditionalDelete,
empty prefix self-test, fresh-state-fetch failure on stop, and the
stale-ifMatch DELETE semantics check.
…utual exclusion (#548)

* docs(gateway): correct Unit 3 paths and capture resolved decisions

Plan was written before the Unit 1 extraction settled on its final shape.
Action source still lives at `src/` — only main.ts and post.ts moved to
`apps/action/src/` as thin re-export shims.

Capture the 5 decisions that scope Unit 3 implementation:
- self-test: gateway-only (skip on Action invocations)
- heartbeat: not in v1 Action (15-min TTL with stale takeover)
- run-state: lock-only (no createRun/transitionRun in Action)
- S3-disabled: skip lock cleanly, preserve single-surface compat
- event-type scope: lock all events (PR, issue, schedule, dispatch)

* feat(coordination): action acquires per-repo lock for cross-surface mutual exclusion

Add an acquire-lock phase that runs after dedup so the GitHub Action and the
Discord gateway never execute concurrently against the same repo. Lock release
runs in cleanup's finally block so the next surface waits at most for the run's
critical section, not the 15-min TTL.

- New phase `runAcquireLock` returns a discriminated union: acquired (with
  lockEtag), held-by-other (skip cleanly with holder details), s3-disabled (no
  coordination configured, proceed), or error (log and proceed to preserve
  single-surface behavior).
- Cleanup's CleanupPhaseOptions takes `lockEtag` and releases via runtime's
  `releaseLock` after S3 sync and cache save. Release errors are non-fatal.
- holder_id encodes `action:{run_id}:{run_attempt}` so Discord-side log
  inspection and operator recovery (`/fro-bot force-release-lock`) can
  identify the holder unambiguously.

Decisions captured in plan Unit 3 (2026-04-25):
- Self-test (`validateProviderSemantics`) skipped on Action invocations —
  the gateway is the long-lived process and validates provider semantics at
  startup.
- No heartbeat in v1 — the 15-min TTL covers the median ~2-min Action run;
  rare long runs recover through stale takeover.
- No RunState record — the lock alone provides cross-surface mutual exclusion;
  GitHub already tracks workflow run state.
- S3-disabled is graceful: coordination is opt-in.
- All event types are locked (PR, issue, schedule, dispatch).
fro-bot Bot added 3 commits April 25, 2026 14:32
Co-authored-by: fro-bot[bot] <109017866+fro-bot[bot]@users.noreply.github.com>
Co-authored-by: fro-bot[bot] <109017866+fro-bot[bot]@users.noreply.github.com>
@marcusrbrown marcusrbrown merged commit 4bd3430 into release Apr 25, 2026
1 check passed
@marcusrbrown marcusrbrown deleted the next branch April 25, 2026 21:58
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.

2 participants