§2/§3 state ownership: register_process_wait resume_mode ('fifo' default
preserves T15; 'self' = waiter owns continuation via completion-file
inotify, NO resume_cmd). ci_event_wait registers self-mode and stamps
durable terminal operation state (COMPLETED/FAILED + authority evidence)
before the envelope — a dead session can no longer downgrade operation
truth. Daemon drive skips resume_cmd-less waits; resume() re-reads and
never touches terminal records.
§4 orphan sweep: bounded periodic reconciliation of RESUMING waits past
ORPHAN_GRACE_SECS (failure detection, not scheduling) — truthful
RESUME_UNVERIFIED/READY_TO_RETRY + lease release; deterministic tests.
§5 CLI contract: ci_event_wait parses strictly; --watchdog supported;
unknown flags exit 2 loudly. No silent argument loss.
§6 governance: canonical daemon source IN REPO (bridge/daemon/);
scripts/install_wr_daemon.py installs atomically + verifies sha256
convergence (--check/--restart). One implementation, one deploy path.
§9 task binding: --task-id through cli/tool; task-bound resolution scopes
pending operations; stored operation wins over model hints; fresh
explicit-id operations normalize provisionally (ghost shas refused).
tests/test_real_async_integration.py: 10 frozen tests. Full suite 2196/0.
75 lines
2.9 KiB
Python
75 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""await_intent_cli.py — CLI surface for the intent normalization layer.
|
|
|
|
Used by the await-operation harness tool so the MODEL's scheduling hints
|
|
never reach the wait engine. Prints one JSON line.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
import await_intent # noqa: E402
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
sub = ap.add_subparsers(dest="cmd", required=True)
|
|
n = sub.add_parser("normalize", help="normalize a continuation intent")
|
|
n.add_argument("--sha", default="")
|
|
n.add_argument("--operation-id", default="")
|
|
n.add_argument("--task-id", default="",
|
|
help="§9 task binding: scope pending resolution to "
|
|
"operations registered for this task")
|
|
n.add_argument("--model-op-type", default=None)
|
|
n.add_argument("--model-deadline", default=None)
|
|
n.add_argument("--user-deadline", default=None,
|
|
help="USER_EXPLICIT deadline (authoritative)")
|
|
n.add_argument("--contract-deadline", default=None,
|
|
help="EXTERNAL_CONTRACT deadline (authoritative)")
|
|
rb = sub.add_parser("route-bash",
|
|
help="route a Bash command expressing wait intent")
|
|
rb.add_argument("--command", required=True)
|
|
rb.add_argument("--sha-hint", default="")
|
|
args = ap.parse_args()
|
|
|
|
if args.cmd == "route-bash":
|
|
record = await_intent.normalize_bash(args.command,
|
|
sha_hint=args.sha_hint)
|
|
if record is None:
|
|
print(json.dumps({"normalized": False,
|
|
"reason": "no external continuation intent"}))
|
|
return 0
|
|
if record.get("normalized") is True:
|
|
# the compiled wait needs the SHA: derive from operation_id
|
|
oid = str(record.get("operation_id", ""))
|
|
if oid.startswith("ci-"):
|
|
record["sha_for_wait"] = oid[3:]
|
|
await_intent.emit_normalized_record(record)
|
|
print(json.dumps(record, sort_keys=True))
|
|
return 0
|
|
|
|
action = {"kind": "await_operation", "sha": args.sha,
|
|
"operation_id": args.operation_id,
|
|
"op_type": args.model_op_type}
|
|
model_deadline = (int(args.model_deadline)
|
|
if args.model_deadline else None)
|
|
user_deadline = (int(args.user_deadline)
|
|
if args.user_deadline else None)
|
|
contract_deadline = (int(args.contract_deadline)
|
|
if args.contract_deadline else None)
|
|
record = await_intent.normalize_action(
|
|
action, model_deadline=model_deadline,
|
|
user_deadline=user_deadline, contract_deadline=contract_deadline,
|
|
task_id=args.task_id)
|
|
await_intent.emit_normalized_record(record)
|
|
print(json.dumps(record, sort_keys=True))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|