[AUTO-SPEC-3] Spec Proposal: Document LockService advisory locking for plan lifecycle concurrency #8966

Open
opened 2026-04-14 04:29:06 +00:00 by HAL9000 · 1 comment
Owner

Spec Update Proposal — [AUTO-SPEC-3]

Supervisor: Spec Update Pool | Agent: spec-update-pool-supervisor
Discrepancy Type: Spec gap — implementation has a mechanism not documented in the spec
Related: LockService advisory lock wiring (#7989, mentioned in CHANGELOG)

Metadata

  • Commit Message: docs(spec): document LockService advisory locking for plan lifecycle concurrency
  • Branch: docs/spec-lockservice-advisory-locking

Background and Context

The spec documents plan.concurrency config (line 30705):

Maximum number of plans that can execute concurrently. When this limit is reached, new plan execute commands queue until a slot opens.

And mentions optimistic concurrency control (line 45701):

The updated_at timestamp column on mutable entities serves as a version check. Update operations include WHERE updated_at = <previous_value> to detect concurrent modifications.

The spec does not document:

  1. The LockService advisory locking mechanism for plan and project resources
  2. LockConflictError — raised when a different owner tries to acquire a held lock
  3. LockExpiredError — raised when a lock has expired
  4. Lock TTL defaults (5 min default, 1 hr max, 5 sec min)
  5. Re-entrant locking (same owner can re-acquire, extending TTL)
  6. Automatic lock expiry and cleanup

Discrepancy

What the Spec Currently Says

The spec documents plan.concurrency config and optimistic concurrency control via updated_at timestamps, but does not mention advisory locking at all.

What the Implementation Does

src/cleveragents/application/services/lock_service.py provides:

class LockService:
    """Advisory lock manager for plan and project resources.
    
    Features:
    - Re-entrant: same owner can re-acquire a held lock (extends TTL)
    - Conflict detection: different owner receives LockConflictError
    - Automatic expiry: expired locks are transparently cleaned up
    - Renewal: owners can extend TTL for long-running phases
    - Graceful shutdown: release_all_for_owner cleans up on exit
    """
    
    DEFAULT_LOCK_TTL_SECS = 300  # 5 minutes
    MAX_LOCK_TTL_SECS = 3600     # 1 hour
    MIN_LOCK_TTL_SECS = 5        # 5 seconds

Locks are persisted in the locks table and enforced before plan state transitions. This prevents race conditions when multiple processes or workers attempt to transition the same plan simultaneously.

Classification

Implementation found a better approach → Update the spec to match.

The advisory locking mechanism is an important concurrency safety feature that users and implementers should know about. It explains how the system prevents race conditions in plan lifecycle transitions.

Expected Behavior

The spec should document the LockService advisory locking mechanism so that:

  1. Users understand why LockConflictError may be raised during plan execution
  2. Implementers know about the locks table and TTL configuration
  3. The concurrency section accurately reflects all concurrency control mechanisms in use

Acceptance Criteria

  • docs/specification.md includes a section on advisory locking via LockService
  • Lock TTL defaults (5 min default, 1 hr max, 5 sec min) are documented
  • LockConflictError and LockExpiredError exceptions are documented
  • Re-entrant locking behavior is documented
  • Automatic lock expiry and cleanup is documented
  • The locks table is mentioned in the Storage and Persistence section
  • The spec update PR is reviewed and approved

Subtasks

  • Draft spec addition for advisory locking in the concurrency/persistence section
  • Add LockConflictError and LockExpiredError to the error reference section
  • Document the locks table schema in the Storage section
  • Document TTL configuration and defaults
  • Document re-entrant locking behavior
  • Submit spec update PR for review

Proposed Spec Change

Add a brief section to docs/specification.md in the Storage and Persistence section (or the Plan Lifecycle section) documenting:

  1. Advisory locking via LockService for plan and project resources
  2. Lock TTL defaults and behavior
  3. LockConflictError and LockExpiredError exceptions
  4. Re-entrant locking behavior

Suggested addition in the concurrency/persistence section:

Advisory Locking: The LockService provides advisory locking for plan and project resources to prevent race conditions during phase transitions. Locks are persisted in the locks table with configurable TTL (default: 5 minutes, max: 1 hour). The same owner can re-acquire a held lock (extending TTL). A different owner attempting to acquire a held lock receives LockConflictError. Expired locks are automatically cleaned up. Locks are released on graceful shutdown via release_all_for_owner.

Definition of Done

This issue should be closed when:

  • A spec update PR has been merged that documents the LockService advisory locking mechanism
  • The spec accurately reflects the implementation's concurrency control approach
  • The PR has been reviewed and approved by a maintainer

Approval Request

Please review and approve this proposal so a spec update PR can be created.

To approve: Add a 👍 reaction or comment "approved"
To reject: Close this issue or comment "rejected"


Automated by CleverAgents Bot
Supervisor: Spec Update Pool | Agent: spec-update-pool-supervisor


Automated by CleverAgents Bot
Agent: new-issue-creator

## Spec Update Proposal — [AUTO-SPEC-3] **Supervisor**: Spec Update Pool | Agent: spec-update-pool-supervisor **Discrepancy Type**: Spec gap — implementation has a mechanism not documented in the spec **Related**: LockService advisory lock wiring (#7989, mentioned in CHANGELOG) ## Metadata - **Commit Message**: `docs(spec): document LockService advisory locking for plan lifecycle concurrency` - **Branch**: `docs/spec-lockservice-advisory-locking` ## Background and Context The spec documents `plan.concurrency` config (line 30705): > Maximum number of plans that can execute concurrently. When this limit is reached, new `plan execute` commands queue until a slot opens. And mentions optimistic concurrency control (line 45701): > The `updated_at` timestamp column on mutable entities serves as a version check. Update operations include `WHERE updated_at = <previous_value>` to detect concurrent modifications. **The spec does not document**: 1. The `LockService` advisory locking mechanism for plan and project resources 2. `LockConflictError` — raised when a different owner tries to acquire a held lock 3. `LockExpiredError` — raised when a lock has expired 4. Lock TTL defaults (5 min default, 1 hr max, 5 sec min) 5. Re-entrant locking (same owner can re-acquire, extending TTL) 6. Automatic lock expiry and cleanup ## Discrepancy ### What the Spec Currently Says The spec documents `plan.concurrency` config and optimistic concurrency control via `updated_at` timestamps, but does not mention advisory locking at all. ### What the Implementation Does `src/cleveragents/application/services/lock_service.py` provides: ```python class LockService: """Advisory lock manager for plan and project resources. Features: - Re-entrant: same owner can re-acquire a held lock (extends TTL) - Conflict detection: different owner receives LockConflictError - Automatic expiry: expired locks are transparently cleaned up - Renewal: owners can extend TTL for long-running phases - Graceful shutdown: release_all_for_owner cleans up on exit """ DEFAULT_LOCK_TTL_SECS = 300 # 5 minutes MAX_LOCK_TTL_SECS = 3600 # 1 hour MIN_LOCK_TTL_SECS = 5 # 5 seconds ``` Locks are persisted in the `locks` table and enforced before plan state transitions. This prevents race conditions when multiple processes or workers attempt to transition the same plan simultaneously. ### Classification **Implementation found a better approach** → Update the spec to match. The advisory locking mechanism is an important concurrency safety feature that users and implementers should know about. It explains how the system prevents race conditions in plan lifecycle transitions. ## Expected Behavior The spec should document the `LockService` advisory locking mechanism so that: 1. Users understand why `LockConflictError` may be raised during plan execution 2. Implementers know about the `locks` table and TTL configuration 3. The concurrency section accurately reflects all concurrency control mechanisms in use ## Acceptance Criteria - [ ] `docs/specification.md` includes a section on advisory locking via `LockService` - [ ] Lock TTL defaults (5 min default, 1 hr max, 5 sec min) are documented - [ ] `LockConflictError` and `LockExpiredError` exceptions are documented - [ ] Re-entrant locking behavior is documented - [ ] Automatic lock expiry and cleanup is documented - [ ] The `locks` table is mentioned in the Storage and Persistence section - [ ] The spec update PR is reviewed and approved ## Subtasks - [ ] Draft spec addition for advisory locking in the concurrency/persistence section - [ ] Add `LockConflictError` and `LockExpiredError` to the error reference section - [ ] Document the `locks` table schema in the Storage section - [ ] Document TTL configuration and defaults - [ ] Document re-entrant locking behavior - [ ] Submit spec update PR for review ## Proposed Spec Change Add a brief section to `docs/specification.md` in the Storage and Persistence section (or the Plan Lifecycle section) documenting: 1. Advisory locking via `LockService` for plan and project resources 2. Lock TTL defaults and behavior 3. `LockConflictError` and `LockExpiredError` exceptions 4. Re-entrant locking behavior **Suggested addition** in the concurrency/persistence section: > **Advisory Locking**: The `LockService` provides advisory locking for plan and project resources to prevent race conditions during phase transitions. Locks are persisted in the `locks` table with configurable TTL (default: 5 minutes, max: 1 hour). The same owner can re-acquire a held lock (extending TTL). A different owner attempting to acquire a held lock receives `LockConflictError`. Expired locks are automatically cleaned up. Locks are released on graceful shutdown via `release_all_for_owner`. ## Definition of Done This issue should be closed when: - A spec update PR has been merged that documents the `LockService` advisory locking mechanism - The spec accurately reflects the implementation's concurrency control approach - The PR has been reviewed and approved by a maintainer ## Approval Request Please review and approve this proposal so a spec update PR can be created. **To approve**: Add a 👍 reaction or comment "approved" **To reject**: Close this issue or comment "rejected" --- **Automated by CleverAgents Bot** Supervisor: Spec Update Pool | Agent: spec-update-pool-supervisor --- **Automated by CleverAgents Bot** Agent: new-issue-creator
HAL9000 added this to the v3.2.0 milestone 2026-04-14 04:35:26 +00:00
Author
Owner

Verified — LockService advisory locking spec documentation is a valid spec proposal. MoSCoW: Should-have. Priority: Low — documentation enhancement, not blocking implementation.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — LockService advisory locking spec documentation is a valid spec proposal. MoSCoW: Should-have. Priority: Low — documentation enhancement, not blocking implementation. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#8966
No description provided.