diff --git a/.agents/messages/receiver-ad4e4f8f/.processed b/.agents/messages/receiver-ad4e4f8f/.processed deleted file mode 100644 index 5884b45..0000000 --- a/.agents/messages/receiver-ad4e4f8f/.processed +++ /dev/null @@ -1 +0,0 @@ -699db7a9-1f51-4b47-9853-5cd79bf040e0 diff --git a/.agents/messages/receiver-bbb512c8/.processed b/.agents/messages/receiver-bbb512c8/.processed deleted file mode 100644 index eb21e7b..0000000 --- a/.agents/messages/receiver-bbb512c8/.processed +++ /dev/null @@ -1 +0,0 @@ -3ca5aa61-0024-4898-b0c2-95b1a9a9e074 diff --git a/.agents/messages/receiver-c059e24d/.processed b/.agents/messages/receiver-c059e24d/.processed deleted file mode 100644 index 083da58..0000000 --- a/.agents/messages/receiver-c059e24d/.processed +++ /dev/null @@ -1 +0,0 @@ -564adfe8-43f1-49d5-8758-11952a19d16a diff --git a/.agents/messages/receiver-c5fe09dd/.processed b/.agents/messages/receiver-c5fe09dd/.processed deleted file mode 100644 index 0501408..0000000 --- a/.agents/messages/receiver-c5fe09dd/.processed +++ /dev/null @@ -1 +0,0 @@ -d2d2ba16-d68f-4853-948c-e0eee65a1332 diff --git a/.agents/messages/receiver_ops-37cadd82/.processed b/.agents/messages/receiver_ops-37cadd82/.processed deleted file mode 100644 index dedb159..0000000 --- a/.agents/messages/receiver_ops-37cadd82/.processed +++ /dev/null @@ -1,2 +0,0 @@ -43af8b7e-e66d-449c-b8d3-d33247092adf -3c967026-e932-4bd8-a99a-a9d4ac22bc7e diff --git a/.agents/messages/receiver_scale-dab9c017/.processed b/.agents/messages/receiver_scale-dab9c017/.processed deleted file mode 100644 index 3df718e..0000000 --- a/.agents/messages/receiver_scale-dab9c017/.processed +++ /dev/null @@ -1,6 +0,0 @@ -da7b718b-4d18-433c-abde-a8b736f10bdd -f7c930b9-86bd-4f6f-963f-fa7faa0e0311 -3d12c1db-5430-4254-8988-d9d585e0381a -9a48b29a-e115-4ca3-b3bc-584d136c73cf -70725fc6-9725-49ef-ad9c-bedeb5f83771 -7decdefc-ea08-4b71-abd5-4dccae879894 diff --git a/.agents/messages/receiver_sec-371a042e/.processed b/.agents/messages/receiver_sec-371a042e/.processed deleted file mode 100644 index 1f0a909..0000000 --- a/.agents/messages/receiver_sec-371a042e/.processed +++ /dev/null @@ -1 +0,0 @@ -43866846-c215-4320-ae72-abac12462bed diff --git a/.agents/messages/sender-ae6bf2b2/.processed b/.agents/messages/sender-ae6bf2b2/.processed deleted file mode 100644 index 41c0c83..0000000 --- a/.agents/messages/sender-ae6bf2b2/.processed +++ /dev/null @@ -1 +0,0 @@ -80316bd4-4a59-4892-9f6c-4c62d0981c5c diff --git a/.agents/messages/test-b-0231eb27/.processed b/.agents/messages/test-b-0231eb27/.processed deleted file mode 100644 index 470b283..0000000 --- a/.agents/messages/test-b-0231eb27/.processed +++ /dev/null @@ -1 +0,0 @@ -c6ebd7ec-85b8-4f15-8633-1038b029cda8 diff --git a/.agents/messages/test-b-29544c66/.processed b/.agents/messages/test-b-29544c66/.processed deleted file mode 100644 index 9e6a9e6..0000000 --- a/.agents/messages/test-b-29544c66/.processed +++ /dev/null @@ -1 +0,0 @@ -0a926b05-860e-4561-8c03-a2d73f19223e diff --git a/.agents/messages/test-b-3617e505/.processed b/.agents/messages/test-b-3617e505/.processed deleted file mode 100644 index edfbc91..0000000 --- a/.agents/messages/test-b-3617e505/.processed +++ /dev/null @@ -1 +0,0 @@ -b9482fd4-148d-4a0c-9d66-2ebb41137d04 diff --git a/.agents/messages/test-b-4313c9d0/.processed b/.agents/messages/test-b-4313c9d0/.processed deleted file mode 100644 index 4674161..0000000 --- a/.agents/messages/test-b-4313c9d0/.processed +++ /dev/null @@ -1 +0,0 @@ -1e891feb-ded4-4aac-8800-eca456b97163 diff --git a/.agents/messages/test-b-714aedf8/.processed b/.agents/messages/test-b-714aedf8/.processed deleted file mode 100644 index 25a4eaa..0000000 --- a/.agents/messages/test-b-714aedf8/.processed +++ /dev/null @@ -1 +0,0 @@ -831986f3-5b3c-47c5-97a1-b99a0aa0d645 diff --git a/.agents/messages/test-b-78219b37/.processed b/.agents/messages/test-b-78219b37/.processed deleted file mode 100644 index d568c2e..0000000 --- a/.agents/messages/test-b-78219b37/.processed +++ /dev/null @@ -1 +0,0 @@ -fd02e2cc-bc3d-4b3d-9120-75ced6f5b915 diff --git a/.agents/messages/test-b-7db0f955/.processed b/.agents/messages/test-b-7db0f955/.processed deleted file mode 100644 index 74c9228..0000000 --- a/.agents/messages/test-b-7db0f955/.processed +++ /dev/null @@ -1 +0,0 @@ -bb2a7664-1579-46fe-aacf-cf9cfe571f70 diff --git a/.agents/messages/test-b-863045de/.processed b/.agents/messages/test-b-863045de/.processed deleted file mode 100644 index 4c7953b..0000000 --- a/.agents/messages/test-b-863045de/.processed +++ /dev/null @@ -1 +0,0 @@ -7be9c24a-11ba-461d-aca0-5dca597c0548 diff --git a/.agents/messages/test-b-8ef1b6bc/.processed b/.agents/messages/test-b-8ef1b6bc/.processed deleted file mode 100644 index f1f2491..0000000 --- a/.agents/messages/test-b-8ef1b6bc/.processed +++ /dev/null @@ -1 +0,0 @@ -2b9394e3-6c0a-45df-82a8-399067b852d9 diff --git a/.agents/messages/test-b-94de765b/.processed b/.agents/messages/test-b-94de765b/.processed deleted file mode 100644 index f39f204..0000000 --- a/.agents/messages/test-b-94de765b/.processed +++ /dev/null @@ -1 +0,0 @@ -7f272aca-fa15-4688-82ee-f1d923f99202 diff --git a/.agents/messages/test-b-d6ff15cb/.processed b/.agents/messages/test-b-d6ff15cb/.processed deleted file mode 100644 index d53ab57..0000000 --- a/.agents/messages/test-b-d6ff15cb/.processed +++ /dev/null @@ -1 +0,0 @@ -1800528e-a0f9-4dc6-a923-01ffb398eb9e diff --git a/.agents/messages/test-b-e36f5d0e/.processed b/.agents/messages/test-b-e36f5d0e/.processed deleted file mode 100644 index 0a7b845..0000000 --- a/.agents/messages/test-b-e36f5d0e/.processed +++ /dev/null @@ -1 +0,0 @@ -dc61d968-a29b-4d88-8748-51b7a71183a4 diff --git a/.agents/messages/test-b-f99f7fd8/.processed b/.agents/messages/test-b-f99f7fd8/.processed deleted file mode 100644 index e623133..0000000 --- a/.agents/messages/test-b-f99f7fd8/.processed +++ /dev/null @@ -1 +0,0 @@ -3bd250d6-cce5-4a6a-8507-d7e1ac6516b2 diff --git a/.agents/messages/test-b-fd4cc5d4/.processed b/.agents/messages/test-b-fd4cc5d4/.processed deleted file mode 100644 index 9253b38..0000000 --- a/.agents/messages/test-b-fd4cc5d4/.processed +++ /dev/null @@ -1 +0,0 @@ -d3643487-c51b-4e91-8236-72843a6bffe0 diff --git a/.agents/registry/.lock b/.agents/registry/.lock deleted file mode 100644 index e69de29..0000000 diff --git a/docs/review/REVIEW_20260104.md b/docs/review/REVIEW_20260104.md deleted file mode 100644 index e3001b2..0000000 --- a/docs/review/REVIEW_20260104.md +++ /dev/null @@ -1,60 +0,0 @@ -# Review of Agent Coordination Enhancements -**Date:** 2026-01-04 -**Author:** Gemini Agent - -## Overview -This review covers the completion of the "Multi-Agent Coordination System Enhancements" Epic (`INFRASTRUCTURE-20260104-095616-HMX`). All planned sub-tasks have been implemented, verified, and documented. - -## Completed Tasks - -### 1. Concurrency Enhancements (`EUM`) -- **Status:** Completed -- **Changes:** - - Implemented `scripts/lib/concurrency.py` with `FileLock` (using `fcntl`). - - Added registry locking to prevent race conditions during registration and pruning. - - Implemented atomic "move-then-read" pattern for public message processing. - -### 2. Reliability Improvements (`AOR`) -- **Status:** Completed -- **Changes:** - - Added `retry_count` and exponential backoff to `send()`. - - Implemented Dead-Letter Queue (DLQ) for corrupt, expired, or invalid messages. - - Added Time-To-Live (TTL) enforcement. - - Added Idempotency checks using a local processed ID log. - - Added Delivery Receipts mechanism. - -### 3. Scalability Optimizations (`RZF`) -- **Status:** Completed -- **Changes:** - - Integrated GZIP compression for messages (transparent support in `io.py`). - - Optimized `read()` to use `os.scandir` and `heapq` for memory-efficient directory listing. - - Added `cleanup_archive` utility. - - Added `send_batch` capability. - -### 4. Security Hardening (`PND`) -- **Status:** Completed -- **Changes:** - - Implemented HMAC-SHA256 signature generation and verification for message integrity/auth. - - Added mock Encryption hooks (extensible). - - Implemented sender-side Rate Limiting (leaky bucket). - - Added strict payload size and type validation. - -### 5. Operational Enhancements (`EXF`) -- **Status:** Completed -- **Changes:** - - Added CLI commands: `health`, `metrics`. - - Implemented system health checks (disk, permissions). - - Added Prometheus-style metrics output. - - Implemented Priority Queueing (Urgent > Normal > Low). - -### 6. Git Policy Review (`RUD`) -- **Status:** Completed -- **Findings:** Current policies are standard and not overly restrictive. No changes required. - -## Technical Notes -- **Dependencies:** New `concurrency.py` module added. `io.py` updated for GZIP. -- **Compatibility:** Fully backward compatible. Old agents can read new messages (ignoring metadata), new agents handle old messages gracefully. -- **Libraries:** No external dependencies (`cryptography`, `jwt`, etc.) were introduced; functionality relies on Python standard library. - -## Verification -Dedicated test scripts were created for each feature set and verified successfully. diff --git a/scripts/index b/scripts/index deleted file mode 100755 index 4c59e38..0000000 --- a/scripts/index +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Ensure python3 is available -if ! command -v python3 &> /dev/null; then - echo "Error: python3 is required but not found." - exit 1 -fi - -# Get the directory of this script -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Execute the python script -exec python3 "$DIR/index.py" "$@" diff --git a/scripts/lib/audit.py b/scripts/lib/audit.py deleted file mode 100644 index a301b7f..0000000 --- a/scripts/lib/audit.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import json -import datetime -from scripts.lib import io, config - -def log_activity(action, args=None, agent_id=None, result="success"): - """ - Appends a structured log entry to the agent audit log. - """ - # Get configuration - # Note: repo_root calculation logic copied from other scripts - script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - repo_root = os.getenv("TASKS_REPO_ROOT", os.path.dirname(script_dir)) - - conf = config.get_config(repo_root) - log_path = os.path.join(repo_root, conf["agents"]["audit_log"]) - - # Ensure logs directory exists - log_dir = os.path.dirname(log_path) - if not os.path.exists(log_dir): - os.makedirs(log_dir, exist_ok=True) - - entry = { - "timestamp": datetime.datetime.now().isoformat(), - "agent_id": agent_id or os.getenv("AGENT_ID", "human-or-unknown"), - "action": action, - "args": args or {}, - "result": result - } - - # Helper for JSON serialization of complex objects - def serialize(obj): - try: - return json.dumps(obj) - except (TypeError, OverflowError): - return str(obj) - - # Append to JSONL file - try: - # Use a custom default or pre-process entry to ensure serializability - safe_entry = json.loads(json.dumps(entry, default=lambda o: str(o))) - with open(log_path, "a") as f: - f.write(json.dumps(safe_entry) + "\n") - except Exception as e: - print(f"Warning: Failed to write to audit log: {e}") - -def audit_log(action): - """ - Decorator for simple function auditing. - """ - def decorator(func): - def wrapper(*args, **kwargs): - try: - res = func(*args, **kwargs) - log_activity(action, {"args": list(args), "kwargs": kwargs}, result="success") - return res - except Exception as e: - log_activity(action, {"args": list(args), "kwargs": kwargs}, result=f"error: {str(e)}") - raise e - return wrapper - return decorator diff --git a/scripts/lib/concurrency.py b/scripts/lib/concurrency.py deleted file mode 100644 index 28b55d4..0000000 --- a/scripts/lib/concurrency.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import time -import fcntl -import errno -from contextlib import contextmanager - -class FileLockException(Exception): - pass - -class FileLock: - """ - A file locking mechanism using fcntl.flock for POSIX systems. - """ - def __init__(self, lock_file, timeout=5, delay=0.1): - self.lock_file = lock_file - self.timeout = timeout - self.delay = delay - self.fd = None - - def acquire(self): - start_time = time.time() - # Ensure directory exists - os.makedirs(os.path.dirname(os.path.abspath(self.lock_file)), exist_ok=True) - - self.fd = open(self.lock_file, 'w') - - while True: - try: - # LOCK_EX: Exclusive lock - # LOCK_NB: Non-blocking - fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - return - except (IOError, OSError) as e: - if e.errno != errno.EAGAIN: - raise - if (time.time() - start_time) >= self.timeout: - self.fd.close() - raise FileLockException(f"Could not acquire lock on {self.lock_file} within {self.timeout}s") - time.sleep(self.delay) - - def release(self): - if self.fd: - try: - fcntl.flock(self.fd, fcntl.LOCK_UN) - except: - pass - self.fd.close() - self.fd = None - - def __enter__(self): - self.acquire() - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.release() diff --git a/scripts/lib/io.py b/scripts/lib/io.py index ed99784..649cd97 100644 --- a/scripts/lib/io.py +++ b/scripts/lib/io.py @@ -2,7 +2,6 @@ import tempfile import json import time -import gzip def write_atomic(filepath, content, mode='w', encoding='utf-8'): """ @@ -33,62 +32,28 @@ def write_atomic(filepath, content, mode='w', encoding='utf-8'): os.remove(tmp_path) raise e -def write_atomic_gzip(filepath, content_str, encoding='utf-8'): - """Atomic write for GZIP files.""" - directory = os.path.dirname(os.path.abspath(filepath)) - if not os.path.exists(directory): - os.makedirs(directory, exist_ok=True) - - fd, tmp_path = tempfile.mkstemp(dir=directory, suffix='.gz') - os.close(fd) - - try: - with gzip.open(tmp_path, 'wt', encoding=encoding) as f: - f.write(content_str) - f.flush() - # Try to fsync underlying file - if hasattr(f, 'fileobj') and f.fileobj: - f.fileobj.flush() - os.fsync(f.fileobj.fileno()) - - os.replace(tmp_path, filepath) - except Exception as e: - if os.path.exists(tmp_path): - os.remove(tmp_path) - raise e - def read_text(filepath, encoding='utf-8', retries=3, delay=0.1): """ Reads text from a file with simple retry logic for transient errors. - Supports .gz files transparently. """ if not os.path.exists(filepath): raise FileNotFoundError(f"File not found: {filepath}") - is_gzip = filepath.endswith('.gz') - for attempt in range(retries): try: - if is_gzip: - with gzip.open(filepath, 'rt', encoding=encoding) as f: - return f.read() - else: - with open(filepath, 'r', encoding=encoding) as f: - return f.read() + with open(filepath, 'r', encoding=encoding) as f: + return f.read() except OSError: if attempt == retries - 1: raise time.sleep(delay) def write_json(filepath, data, indent=2): - """Atomic write for JSON (supports .gz).""" + """Atomic write for JSON.""" content = json.dumps(data, indent=indent, sort_keys=True) - if filepath.endswith('.gz'): - write_atomic_gzip(filepath, content) - else: - write_atomic(filepath, content + "\n") + write_atomic(filepath, content + "\n") def read_json(filepath): - """Read JSON from file (supports .gz).""" + """Read JSON from file.""" content = read_text(filepath) - return json.loads(content) \ No newline at end of file + return json.loads(content) diff --git a/templates/task.md b/templates/task.md deleted file mode 100644 index 58a9703..0000000 --- a/templates/task.md +++ /dev/null @@ -1,23 +0,0 @@ -# Task: {title} - -## Task Information -- **Task ID**: {task_id} -- **Status**: pending -- **Priority**: medium -- **Phase**: 1 -- **Estimated Effort**: 1 day -- **Dependencies**: None - -## Task Details - -### Description -{description} - -### Acceptance Criteria -- [ ] Criterion 1 -- [ ] Criterion 2 - ---- - -*Created: {date}* -*Status: pending*