Contracts

event-bridge-port.md

Contract: EventBridge port (Python)

  • WorkPackageTransitionPort.record_work_package_transition(transition: WorkPackageTransition) -> None
  • EventBridgePort = RuntimeEventEmitter (Mission state advance) + WorkPackageTransitionPort, defined in runtime/next/_internal_runtime/events.py; the rest lives in the stdlib-only leaf runtime/next/event_bridge.py
  • bind_work_package_transition_port(port): reject-on-conflict by module.qualname; rebinding the same class is idempotent
  • reset_work_package_transition_port(): test-only
  • bound_work_package_transition_port() -> WorkPackageTransitionPort | None

The adapter raises what the underlying append raised; it never swallows.

interim-ledger-lock.md

Contract: interim ledger lock (retires at the #6193 handover)

Every append to an event log other than status.events.jsonl / canonical-events.jsonl (which keep the status lock):

0. Anchor. The log itself. For a family of one-file-per-record logs (kitty-ops/<op>.jsonl), the family directory. 1. Lock file. L = <git-common-dir>/spec-kitty-locks/event-logs/<sha256(normcase(resolve(anchor)))[:32]>.lock.

2. Lock. An exclusive flock(2) (POSIX) or msvcrt.locking (Windows) on L, with a bounded wait of 10 s (EVENT_LOG_LOCK_TIMEOUT). The lock file holds only a lock record and is never unlinked. 3. Torn tail. Under the lock, refuse if the log's last byte is not LF (EVENT_LOG_TORN_TAIL). 4. Write. One write(2) on an O_APPEND descriptor of the whole unit, then fsync. 5. Release.

  • Not a git repository: L = <anchor>.event-log.lock.
  • Git cannot be invoked: refuse (EVENT_LOG_LOCK_UNAVAILABLE); write nothing.

A Java writer that shares a file with the CLI must take the same L with flock(2) semantics (ADR 2026-10-22-1 D-4).