feat(directives): scavenge sweep 4/5 (tracks + commands + styleguides + todos): 18 batch-4 directives + concurrent worker batches

This commit is contained in:
ed
2026-07-04 02:00:42 -04:00
parent e8d3578f2e
commit 79124774ec
82 changed files with 2430 additions and 0 deletions
@@ -0,0 +1,10 @@
# per_conversation_scratch_dir
## v1
**Why this iteration:** Lifted from `conductor/tracks/nagent_review_20260608/decisions.md` §"Candidate 23: Per-conversation scratch directory for Manual Slop dispatch_inference" (MEDIUM priority) + nagent commit `49e07f3` — concurrent instances of a dispatch system must have their own scratch directory keyed by instance name to prevent file collisions in a shared `/tmp`.
**Source:** `conductor/tracks/nagent_review_20260608/decisions.md` §Candidate 23 + `nagent_takeaways_v3_20260619.md` §3 (per-conversation scratch dir hardening)
---
**Lifted:** 2026-07-03 scavenge sweep batch 4/5: tracks + commands + styleguides + todos
@@ -0,0 +1,42 @@
# Each instance of a multi-instance dispatch system MUST have its own scratch directory keyed by instance name — concurrent instances must never collide in a shared `/tmp` or `AppData`
## What it says
When designing a system that supports multiple concurrent instances of the same workflow (multi-agent dispatch, parallel AI calls, multi-conversation chat), each instance MUST have its own scratch directory keyed by its instance name (e.g., `dispatch_scratch_dir(conversation_name)`). The shared `/tmp`, `AppData\Local\Temp`, or `$env:TEMP` is OFF-LIMITS for scratch storage — concurrent instances will collide on filenames.
## Why
nagent discovered this the hard way: when `<nagent-write>` was implemented with a shared scratch directory, two concurrent conversations racing on `scratch.json` corrupted each other's outputs. The fix (per nagent commit `49e07f3`) was to thread a `conversation_scratch_dir(conversation_name)` through every write operation and pre-create the directory on session start.
## The pattern
```python
def scratch_dir_for(instance_name: str) -> Path:
"""Return the scratch directory for this instance, creating it if missing.
Each instance name (conversation name, worker ID, dispatch ticket ID)
gets its own directory under the project's tests/artifacts/ tree.
Concurrent instances never collide because the directories are distinct.
"""
safe_name = re.sub(r"[^A-Za-z0-9_.-]", "_", instance_name)
path = REPO_ROOT / "tests" / "artifacts" / "scratch" / safe_name
path.mkdir(parents=True, exist_ok=True)
return path
```
## Failure mode this prevents
Two instances writing `scratch/state.json` to `/tmp` race on the file. The first writes "in-progress"; the second overwrites with "complete" before the first's `read-modify-write` cycle finishes. The first's `commit` then reads stale state and reverts the second's work. The fix: each instance has its own directory; file collisions are impossible.
## Where to apply this
- **AI client dispatch** — when sending to a provider, route scratch state (rate-limit counters, retry budgets, cached responses) through `scratch_dir_for(conversation_name)`.
- **Worker pool** — each Tier 3 worker has its own scratch dir keyed by `worker_id` (not the shared `tests/artifacts/tier2_state/`).
- **Multi-conversation GUI** — when the user opens two discussions in parallel, each has its own scratch dir for "draft not yet flushed" state.
- **MCP tool execution** — if a tool writes to disk and is called from multiple conversations, the scratch dir is per-conversation.
## Cross-refs
- `conductor/tracks/nagent_review_20260608/decisions.md` §"Candidate 23: Per-conversation scratch directory for Manual Slop dispatch_inference" (MEDIUM priority)
- `conductor/tracks/nagent_review_20260608/nagent_takeaways_v3_20260619.md` §3 ("v3 new candidates") — describes the per-conversation scratch dir hardening commit `49e07f3`
- `conductor/code_styleguides/workspace_paths.md` — the broader rule that all paths must live under `./tests/`, never `%TEMP%`