Skip to content
Less of Lee
Go back

Code Review Architecture and Governance

Executive Summary (Architecture + Governance + Idempotency Review)

Status: Not Ready.

P0 Issues

Boundaries are mostly separated (orchestrator vs. governance vs. workspace), but webhook and orchestrator duplicate logic (triggers/tags and agent routing), raising divergence risk.

Path safety for dirname is strong (no dots/slashes, lowercase/dashes), but safe_write_file doesn’t normalize or block absolute paths if misused, so G4 is “likely” rather than proven.

Flood control is implemented in spawner (max 20 children), which is a positive guard for I3.

Findings Table

TitleSeverityComponentFailure ModeRepro StepsRecommended FixSuggested Test
Ratchet bypass via delete/recreateP0lib/workspace.py, lib/ratchet.pyLocked files can be deleted and re-written because safe_write_file checks lock only if file exists; ratchet doesn’t block recreation.1) Lock DESIGN.md via governance. 2) Delete file. 3) Call safe_write_file to recreate—write succeeds despite lock.Always check ratchet status regardless of file existence; deny writes when lock exists even if file missing. Consider storing locks on normalized paths and block recreate.Add test: lock file, delete it, assert safe_write_file raises PermissionError.
Webhook/orchestrator idempotency raceP0orchestrator.py, webhook_server.py, lib/task_fields.pyDuplicate webhook deliveries or concurrent orchestrators can run the same agent twice because tag-based checks aren’t atomic and there’s no lock/dedupe key.Send same webhook twice quickly or run two orchestrators; both may observe “no started tag” and trigger agent.Add a lock/tag with TTL or per-task metadata lock (e.g., agent_lock=ARCHITECT_AGENT + timestamp) and refuse if lock already set; ensure lock release on failure.Simulate concurrent invocations: run two worker threads and verify only one executes agent.
Spawner idempotency misses orphansP0agents/spawner.pyIdempotency uses links + metadata; if a child is created but link or metadata write fails, reruns will duplicate because the orphan isn’t detected.Force error after duplicate creation but before metadata/link; rerun spawner creates another child with same atomic ID.Add fallback idempotency scan of “Tests Draft” tasks filtering by parent_id/atomic ID in description or metadata; ensure spawner writes an idempotency marker early.Test: create an orphan child without link/metadata and ensure spawner skips it.
Ralph test immutability not enforced for unstaged changesP0agents/ralph.py, lib/ratchet.pyGuard only checks staged files; unstaged test edits or missing/altered tests (when not ratcheted) won’t fail. Only one test file hash checked.Modify tests/test_x.py without staging; Ralph runs and commits source changes without detecting test modification.Extend guard to detect any changes in tests/ (staged or unstaged) and verify all ratcheted test hashes.Test: modify test file without staging and assert Ralph aborts before commit.
Orchestrator/Webhook logic duplicationP2orchestrator.py, webhook_server.pyTRIGGERS/TAGS and per-agent routing logic are duplicated; divergences can create inconsistent behavior across entrypoints.Change TRIGGERS in one file; webhook and orchestrator diverge.Extract shared constants + processor functions into a module used by both.Unit test ensures trigger map and tag set are identical across entrypoints.
“Started” tags never cleared on failureP2orchestrator.py, webhook_server.pyFailed agents leave “started” tags set, preventing retries and causing “stuck” cards.Force an agent failure; observe *-started tag stays and task never reprocesses.On failure, either clear the started tag or set a failed tag with TTL-based retry logic.Test: simulated failure clears started tag or marks failed to allow manual retry.
Global monkeypatch of HTTP handlerP3webhook_server.pyModule import mutates BaseHTTPRequestHandler and BaseServer error handling globally, which can affect other server instances in-process.Import webhook module into another HTTP server context; handlers are globally patched.Scope the behavior to the webhook server class instead of global monkeypatching.Test: import webhook module and verify other HTTP handlers remain unmodified.

Governance Invariants Checklist

Architecture & Boundaries (Direct Answers)

Responsibilities separation:

Conclusion: Boundaries are mostly clean, but duplicated orchestration logic increases divergence risk.

Import-order dependency / side-effect registration risk:
Webhook server globally monkeypatches HTTP handler error behavior at import-time, which can affect other server usage in-process.

Duplicate agent logic across webhook vs orchestrator:
Both files replicate TRIGGERS/TAGS and per-agent process_* flows; risk of drift is real.

Sources of truth are ambiguous in practice:

Optional Small Patch Suggestions (Targeted)

Commands Run

rg -n "kanboard" -S .
rg -n "subprocess|shell=True|os.system|bash -lc" -S agents lib orchestrator.py webhook_server.py
rg --files -g 'AGENTS.md'
nl -ba <file> | sed -n '<range>p' (used to inspect orchestrator.py, webhook_server.py, lib/ratchet.py, lib/workspace.py, lib/task_fields.py, agents/*.py, and tests/*.py)

Tests: Tests were not run (review-only).


Share this post on:

Previous Post
Code Review Strategy Before Shipping
Next Post
Ralph Wiggum Testing: A Comprehensive Guide