Skip to content

fix: provider stability and P2P delta-sync optimizations - #4

Merged
vilmire merged 4 commits into
mainfrom
fix/provider-p2p-stability
May 25, 2026
Merged

fix: provider stability and P2P delta-sync optimizations#4
vilmire merged 4 commits into
mainfrom
fix/provider-p2p-stability

Conversation

@vilmire

@vilmire vilmire commented May 25, 2026

Copy link
Copy Markdown
Owner

Phase 1: Provider Circuit Breaker, Thundering Herd fix, P2P Delta-Sync, Worktree Path Isolation.

@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@vilmire

vilmire commented May 25, 2026

Copy link
Copy Markdown
Owner Author

I have read the CLA Document and I hereby sign the CLA

@vilmire

vilmire commented May 25, 2026

Copy link
Copy Markdown
Owner Author

recheck

@vilmire

vilmire commented May 25, 2026

Copy link
Copy Markdown
Owner Author

I have read the CLA Document and I hereby sign the CLA

@vilmire
vilmire force-pushed the fix/provider-p2p-stability branch from 4190eec to 22f833a Compare May 25, 2026 07:49
@vilmire
vilmire changed the base branch from refactor/async-io-foundation to main May 25, 2026 07:49
@vilmire
vilmire merged commit a87af5e into main May 25, 2026
3 checks passed
vilmire added a commit that referenced this pull request Jun 1, 2026
…s file, pending guard, cooldown sweep

appendRemoteLedgerEntries (#1):
- dedup now uses tail:1000 instead of full O(n) readLedgerEntries;
  P2P replication is cursor-based so duplicates appear in the recent tail

Archive rotation (#4):
- compactLedger now rotates .archive.jsonl to .archive.N.jsonl (max 5)
  when the archive exceeds 50MB before appending new entries

Worker JSON extraction validation (#5):
- extractJsonObjectFromSummary now requires at least one mesh worker result
  field (changedFiles|errors|gitStatus|nextAction|validationResults) before
  accepting a JSON block; prevents false positives from tool/log JSON in
  the final summary

Archived counts file (#6):
- compactLedger writes cumulative counts to <meshId>.archived-counts.json
- getLedgerSummary reads and merges archived counts so taskCompleted/Failed/
  Stalled and totalEntries are accurate even after compaction

Pending events size guard (#2):
- queuePendingMeshCoordinatorEvent trims the pending-events.jsonl to the
  last 50 events when it exceeds 100KB before appending; prevents unbounded
  growth when coordinator stops draining

autoLaunchCooldownUntil cleanup (#3):
- sweepExpiredCooldowns() removes expired entries from the cooldown Map
  whenever a new cooldown is set; inline check at read site also cleans up
  the checked key; prevents long-lived daemon Map accumulation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vilmire added a commit that referenced this pull request Jun 20, 2026
…s file, pending guard, cooldown sweep

appendRemoteLedgerEntries (#1):
- dedup now uses tail:1000 instead of full O(n) readLedgerEntries;
  P2P replication is cursor-based so duplicates appear in the recent tail

Archive rotation (#4):
- compactLedger now rotates .archive.jsonl to .archive.N.jsonl (max 5)
  when the archive exceeds 50MB before appending new entries

Worker JSON extraction validation (#5):
- extractJsonObjectFromSummary now requires at least one mesh worker result
  field (changedFiles|errors|gitStatus|nextAction|validationResults) before
  accepting a JSON block; prevents false positives from tool/log JSON in
  the final summary

Archived counts file (#6):
- compactLedger writes cumulative counts to <meshId>.archived-counts.json
- getLedgerSummary reads and merges archived counts so taskCompleted/Failed/
  Stalled and totalEntries are accurate even after compaction

Pending events size guard (#2):
- queuePendingMeshCoordinatorEvent trims the pending-events.jsonl to the
  last 50 events when it exceeds 100KB before appending; prevents unbounded
  growth when coordinator stops draining

autoLaunchCooldownUntil cleanup (#3):
- sweepExpiredCooldowns() removes expired entries from the cooldown Map
  whenever a new cooldown is set; inline check at read site also cleans up
  the checked key; prevents long-lived daemon Map accumulation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vilmire
vilmire deleted the fix/provider-p2p-stability branch June 27, 2026 09:21
vilmire added a commit that referenced this pull request Jul 10, 2026
…icate execution; slim refine terminal event payload

Two independent daemon-core fixes.

FIX #2 — READONLY/redrive DUPLICATE DISPATCH (delivered-not-consumed race).
When recoverStrandedAssignedDispatches reclaims a delivered-but-unconsumed
task back to pending and it is re-dispatched to another node, the ORIGINAL
P2P inject to the first node was never cancelled — it could still fire and
make that worker start the SAME taskId, double-executing it.

Introduce a monotonic per-task dispatchNonce:
  - claimNextQueueTask bumps it on every (re)dispatch and it rides to the
    worker in meshContext.dispatchNonce (both remote + local dispatch paths).
  - reclaimStrandedAssignedTask bumps it on reclaim, so the stranded inject
    now carries a stale (lower) nonce.
  - the worker stamps it as meshActiveDispatchNonce (attachMeshAssignment) and
    echoes it on agent:generating_started (metadataEvent.dispatchNonce);
    cleared with the task marker on detach.
  - the coordinator's generating_started handler rejects an ack whose echoed
    nonce is strictly less than the row's current nonce, and stops that worker
    (stop_cli, local or remote) so the reclaimed task is never run twice.
Legitimate readonly parallelism is untouched: different taskIds still run
concurrently; only the SAME reclaimed taskId is single-execution. Absent nonce
(legacy worker) falls through to the normal ack — backward safe.

FIX #4 — REFINE TERMINAL EVENT PAYLOAD BLOAT.
queueRefineJobEvent spread the entire terminal CommandRouterResult
(validationSummary.commandsRun[] with per-command stdout/stderr,
rejectedCommands, suggestions, suggestedConfig, full patchEquivalence and
submoduleReachability.entries[]/.unreachable[]) into the coordinator event,
routinely >70KB and overflowing the coordinator token limit on mesh_wait_events.

Add slimRefineEventResult: project the result to decision-relevant fields
(success/code/error/convergenceStatus/blockedReason/branch/into/terminalKind/
nextStep/finalBranchConvergenceState/unreachableSubmoduleCommits subset) plus a
reduced validationSummary (status/failureCode/configSource/configSourceType/
commandsRunCount), patchEquivalence ({status,equivalent}) and
submoduleReachability ({checked,unreachable}). The ledger write and
terminalRefineJobs keep full detail for on-demand fetch, so the event loses
nothing recoverable. Applied to all queueRefineJobEvent emit paths and the
handleMeshForwardEvent forward.

Tests: nonce stamp/bump + readonly-parallel regression (mesh-work-queue);
slim projection field-keep/drop + small serialized size (refine-event-slim).
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