Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Commits: worker-applied-keys-dedup

Append every commit created during the run immediately after creating it.

Format:

```md
- <commit-sha>: <commit message>
```

## Log

- 7f1d011: feat(workers): add worker idempotency contract
- 1a959dd: test(workers): cover worker idempotency key resolution
- d68ae7c: feat(workers): add kv worker idempotency store
- dc37d5b: feat(workers): gate worker effects by idempotency claims
- 951c27b: feat(triggers): propagate worker idempotency keys
- 206e31a: docs(workers): document worker idempotency guarantees
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Context Pack: worker-applied-keys-dedup

## Run Metadata

| Field | Value |
| ----- | ----- |
| Run ID | `feat-prime-time-worker-applied-keys-dedup--impl` |
| Branch | `feat/prime-time/worker-applied-keys-dedup` |
| Current phase | `implement` |
| Archetype | `ARCHETYPE-3 - Runtime / Behavior` |
| Scope overlays | `SCOPE-service` |

## Current State

Implementation is complete for worker consumer-side applied-keys dedup. The branch carries the core
message/port contract, key resolver, KV store, dispatcher gates, trigger producer propagation,
composition wiring, tests, docs, and gate evidence.

## Completed

- Read harness/doctrine/tooling/PR instructions and the approved slice plan artifacts.
- Confirmed branch `feat/prime-time/worker-applied-keys-dedup` tracks
`origin/feat/prime-time/worker-applied-keys-dedup`.
- Created implementation run artifacts.
- Implemented all approved contracts and tests for this slice.
- Ran scoped static gates, targeted runtime tests, JSR audit, doc lint, and publish dry-run.

## In Progress

- Final docs/evidence commit and PR completion comment.

## Next Steps

1. Push final docs/evidence commit.
2. Comment PR #79 ready for IMPL-EVAL.

## Key Decisions

| Decision | Source | Notes |
| -------- | ------ | ----- |
| Worker idempotency is required | `plan.md` | Production must not silently fall back to no-op/in-memory. |
| Store uses shared `getKv()` | `plan.md` | Same durable KV handle as worker runtime state. |
| Queue remains read-only | `research.md` | Consumer-side applied-key dedup is the defect site. |

## Files Changed

| Path | Status | Notes |
| ---- | ------ | ----- |
| `.llm/tmp/run/feat-prime-time-worker-applied-keys-dedup--impl/*` | new | Harness implementation artifacts. |
| `packages/plugin-workers-core/src/ports/worker-idempotency-port.ts` | new | Storage-agnostic worker idempotency port. |
| `packages/plugin-workers-core/src/runtime/worker-idempotency.ts` | new | Key resolver and hash fallback. |
| `plugins/workers/worker/worker-idempotency-store.ts` | new | KV-backed applied-keys store. |
| `plugins/workers/worker/job-dispatcher.ts` | changed | Claim/skip/mark/release gate for job and task effects. |
| `plugins/triggers/src/runtime/trigger-runtime-processor.ts` | changed | Stamps idempotency key on `JobMessage`. |

## Gates

| Gate family | Current status | Evidence |
| ----------- | -------------- | -------- |
| Static | PASS | Scoped check/lint/fmt green for workers-core, workers, triggers. |
| Fitness | PASS_WITH_EXISTING_ARCH_DEBT | JSR audit/doc lint/publish green; repo-wide `arch:check` fails on pre-existing unrelated debt. |
| Runtime | PASS | Combined targeted run passed 35 tests. |
| Consumer | PASS | workers-core, workers plugin, and triggers tests passed. |

## Open Questions

- None.

## Drift and Debt

- Drift: minor commit-order drift, composition wiring folded into consumer commit to preserve a
compiling branch after each push.
- Debt: no new debt accepted.

## Commits
- 7f1d011: feat(workers): add worker idempotency contract
- 1a959dd: test(workers): cover worker idempotency key resolution
- d68ae7c: feat(workers): add kv worker idempotency store
- dc37d5b: feat(workers): gate worker effects by idempotency claims
- 951c27b: feat(triggers): propagate worker idempotency keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Drift Log: worker-applied-keys-dedup

Drift is append-only. Record facts that diverge from the plan, RFC, doctrine, or current-state
documentation.

## 2026-06-20 — Initialized

- **What:** Implementation artifacts initialized from the PLAN-EVAL-passed brief.
- **Source:** `.llm/tmp/run/feat-framework-prime-time--supervisor/slices/worker-applied-keys-dedup/implement-brief.md`
- **Expected:** Implementation starts from approved plan artifacts.
- **Actual:** No drift.
- **Severity:** minor
- **Action:** accept
- **Evidence:** This run directory.

## 2026-06-20 — Composition Wiring Folded Into Consumer Commit

- **What:** Composition wiring is committed with the consumer gate instead of as a later standalone
commit slice.
- **Source:** `plugins/workers/worker/worker-options.ts` makes `WorkerOptions.idempotency`
required.
- **Expected:** Plan listed consumer gate before composition wiring.
- **Actual:** Pushing consumer gate alone would leave in-repo `new Worker(...)` call sites
non-compiling until a later commit.
- **Severity:** minor
- **Action:** accept
- **Evidence:** `plugins/workers/bin/runtime.ts`, `plugins/workers/services/src/service-runtime.ts`,
and `plugins/workers/services/src/routers/router-context.ts` are included with the consumer gate
commit to keep each pushed branch state type-checkable.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# IMPL-EVAL — worker-applied-keys-dedup

**Verdict: PASS**

## Gate evidence

| Gate | Command | Exit | Result |
|---|---|---|---|
| deno check (unstable-kv, scoped) | `run-deno-check.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | 237 files, 0 occurrences |
| deno lint (scoped) | `run-deno-lint.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | 237 files, 0 occurrences |
| deno fmt (scoped) | `run-deno-fmt.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | 237 files, 0 findings |
| deno test (workers-core) | `deno test --unstable-kv packages/plugin-workers-core/` | 0 | 20 passed, 0 failed |
| deno test (workers plugin) | `deno test --unstable-kv plugins/workers/` | 0 | 12 passed, 0 failed |
| deno test (triggers) | `deno test --unstable-kv plugins/triggers/` | 0 | 8 passed, 0 failed (12 E2E ignored correctly) |
| deno test (job-dispatcher targeted) | `deno test plugins/workers/worker/job-dispatcher_test.ts` | 0 | 3 passed (redelivery-skip, failure-release, task-applied) |
| publish:dry-run (plugin-workers-core) | `deno task publish:dry-run` | 0 | Success (one pre-existing unanalyzable-dynamic-import warning, non-blocking) |
| arch:check | `deno task arch:check` | 0 | Only pre-existing F-14/AP-19/AP-23 findings, none slice-related |

## Contracts verified

- `runtime-types.ts`: `idempotencyKey?: string` on both `JobMessage` and `TaskMessage`.
- `worker-idempotency-port.ts`: `WorkerIdempotencyPort` + `WorkerIdempotencyInput` + `WorkerIdempotencyClaim` + `WorkerIdempotencySource` (matches plan spec).
- `ports/mod.ts` re-export + `public/mod.ts` re-export via `public-schema.ts` named exports.
- `worker-idempotency-store.ts`: concrete `KvWorkerIdempotencyStore` over `@netscript/kv` (getKv-shared).
- `worker-options.ts`: `WorkerDispatchContext.idempotency` required; `WorkerOptions.idempotency` required.
- `trigger-runtime-processor_test.ts`: producer stamps `idempotencyKey` onto `JobMessage` body.
- `router-context.ts`: `WorkersServiceRuntime` exposes `idempotency: KvWorkerIdempotencyStore`.

## Test plan vs delivery

- Unit resolver precedence (caller > message-id > payload-hash): ✓ `worker-idempotency_test.ts` (3 tests).
- Unit store (first-claim, duplicate, release, markApplied, TTL, non-durable-backend throw): ✓ `worker-idempotency-store_test.ts` (5 tests).
- Integration dispatcher redelivery + failure-path + task gate: ✓ `job-dispatcher_test.ts` (3 tests).
- Producer propagation: ✓ `trigger-runtime-processor_test.ts` (stamps idempotencyKey onto JobMessage).
- publish:dry-run surface: ✓ passes.

## Production bar checks

- **Durable persistence (NOT in-memory):** KV-backed, shared `getKv()` handle, TTL-bounded (active `expireIn`, applied `expireIn`). ✓
- **Idempotency under retry:** claim → markApplied / release flow; TTL releases crashed claims; no permanent wedge. ✓
- **No in-memory-only set:** confirmed — port in core, KV impl in plugin; constructor throws if backend cannot guarantee durability. ✓
- **Observability:** span event `worker.job.idempotent_skip` / `worker.task.idempotent_skip` + dedup metric attribute. ✓
- **Structured already-applied (skip, not failure):** confirmed in dispatcher and test output. ✓
- **Graceful shutdown:** TTL bounds guarantee no dangling active claims. ✓

## Lock hygiene

`deno.lock` not modified during the run. No stray files generated.

## Slice-specific note (durable + idempotent under retry)

Verified: `KvWorkerIdempotencyStore` persists to KV (`['workers','idempotency','active'|'applied', key]`), uses atomic when available with sequential-has+set fallback, and rejects non-durable backends. The retry path is exercised by `KvWorkerIdempotencyStore release allows a failed delivery to retry` and `processWorkerJob releases a failed claim so redelivery can re-run`.

## Gaps

None.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## IMPL-EVAL Verdict: ✅ PASS

**Slice:** `worker-applied-keys-dedup`
**Evaluator:** Independent (separate session from generator)
**Archetype:** ARCHETYPE-3 (Stateful Runtime / Plugin Runtime)

### Gate Evidence

| Gate | Command | Exit Code | Result |
|------|---------|-----------|--------|
| deno check (scoped) | `deno run --allow-all --unstable-kv .llm/tools/run-deno-check.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | ✅ 237 files, 0 errors |
| deno lint (scoped) | `deno run --allow-all .llm/tools/run-deno-lint.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | ✅ 237 files, 0 errors |
| deno fmt (scoped) | `deno run --allow-all .llm/tools/run-deno-fmt.ts --root packages/plugin-workers-core --root plugins/workers --root plugins/triggers --ext ts` | 0 | ✅ 237 files, 0 errors |
| deno test (workers-core) | `deno test --allow-all --unstable-kv packages/plugin-workers-core/` | 0 | ✅ 20 passed, 0 failed |
| deno test (workers plugin) | `deno test --allow-all --unstable-kv plugins/workers/` | 0 | ✅ 12 passed, 0 failed |
| deno test (triggers) | `deno test --allow-all --unstable-kv plugins/triggers/` | 0 | ✅ 8 passed, 0 failed (12 E2E ignored) |
| deno test (dispatcher integration) | `deno test --allow-all plugins/workers/worker/job-dispatcher_test.ts` | 0 | ✅ 3 passed (redelivery-skip, failure-release, task-dedup) |
| publish:dry-run | `cd packages/plugin-workers-core && deno task publish:dry-run` | 0 | ✅ Success (1 pre-existing warning) |
| arch:check | `deno task arch:check` | 0 | ✅ No new issues |

### Contracts Verified

- ✓ `JobMessage.idempotencyKey?: string` and `TaskMessage.idempotencyKey?: string` (runtime-types.ts)
- ✓ `WorkerIdempotencyPort` interface with `claim/markApplied/release` (worker-idempotency-port.ts)
- ✓ `KvWorkerIdempotencyStore` using KV atomic operations with TTL (worker-idempotency-store.ts)
- ✓ Dispatcher integration: claim before dispatch, release on failure, markApplied on success
- ✓ Trigger producer propagates `idempotencyKey` to job messages
- ✓ Service runtime injects store into Worker instances via composition root

### Production Bar Assessment

- **Durable persistence:** ✅ KV-backed store with atomic versionstamp checks and TTL expiry (no in-memory-only set)
- **Idempotency guarantees:** ✅ claim/markApplied/release lifecycle prevents double-apply on redelivery
- **Failure recovery:** ✅ `release()` on failure allows retry; TTL expiry prevents permanent wedging
- **Observability:** ✅ Skip telemetry events, idempotent skip counters, claim source tracking
- **Graceful degradation:** ✅ Store throws on initialization if KV unavailable (no silent fallback)

### Slice-Specific Verification

**Applied-keys durability and idempotency under retry:**

- KV atomic operations with `versionstamp: null` ensure exactly-once claims
- Active claims have 15-minute TTL; applied markers have 24-hour TTL
- Failed dispatches call `release()` to remove active claim, enabling retry
- Test `KvWorkerIdempotencyStore release allows a failed delivery to retry` validates this path
- No in-memory-only Set or Map used for deduplication

### Test Plan Coverage

- ✓ Unit: key resolution precedence (caller > message-id > payload-hash)
- ✓ Unit: store operations (claim, markApplied, release, TTL expiry, non-durable rejection)
- ✓ Integration: dispatcher redelivery prevention (job and task paths)
- ✓ Integration: failure release and retry
- ✓ Integration: trigger producer key propagation

### Gaps

None identified.

### Verdict Rationale

All required gates pass with comprehensive test coverage. The implementation correctly achieves exactly-once-effective semantics for worker job execution through durable KV-backed idempotency keys. The slice meets the production bar for persistence, error handling, idempotency, observability, and graceful failure recovery. No in-memory-only deduplication mechanisms are present. The implementation fully satisfies the locked contracts specified in plan-meta.json.

---
_Evaluation conducted by OpenHands agent (independent evaluator session)_
Loading