254 lines
13 KiB
Markdown
254 lines
13 KiB
Markdown
---
|
||
decision_id: 2026-04-27-phase-3-acceptance-gate-pre-run-halt
|
||
date: 2026-04-27
|
||
phase: 3 acceptance gate — pre-run scope review
|
||
verdict: HALT-AND-PING — five scope-discovery items need PM ratification before the gate is runnable as briefed
|
||
predecessor: 2026-04-27-phase-2-acceptance-gate-PASS.md
|
||
sprint_plan: D:\Projects\waggle-os\decisions\2026-04-26-agent-fix-sprint-plan.md
|
||
---
|
||
|
||
# Phase 3 Acceptance Gate — Pre-Run Halt-and-Ping
|
||
|
||
## TL;DR
|
||
|
||
**The gate is not runnable as briefed.** Five scope-discovery items surface before any API call is made. Same halt-and-ping pattern that resolved Phase 3.1-3.4 cleanly — surface BEFORE burning real-API budget, not after.
|
||
|
||
The biggest one: **cost estimate vs halt threshold is 3-7x off** because per-step LLM cost grows with accumulated context size; the brief's "~$0.04 per Opus step × 50 = $2.00" assumes constant per-step cost, but step input grows as retrievals accumulate, producing super-linear cost growth without aggressive ContextManager engagement.
|
||
|
||
PM ratification needed on (a) cost-vs-scope tradeoff, (b) "identical final answer" relaxation for real LLMs, (c) synthetic task design, (d) ContextManager config, (e) self-judge methodology cross-model.
|
||
|
||
---
|
||
|
||
## Pre-flight status
|
||
|
||
| Check | Result | Notes |
|
||
|---|---|---|
|
||
| LiteLLM proxy reachable | ✓ (HTTP 401 = auth-required, server alive) | `http://localhost:4000/health` |
|
||
| `LITELLM_MASTER_KEY` in shell env | ✗ | Lives in `.env` / docker-compose env. Need to source before running. |
|
||
| `DASHSCOPE_API_KEY` in shell env | ✗ | Same — `.env` only. |
|
||
| `.env` file present | ✓ | `D:\Projects\waggle-os\.env` |
|
||
| Phase 3.1-3.4 commits clean | ✓ | `7163114` → `8b8a940` (4 commits, all PM-ratified) |
|
||
| Phase 3.4 unit tests | ✓ | 31 integration tests pass; 2428/2428 packages/agent total; 5720 repo-root |
|
||
| `runRetrievalAgentLoop` `maxSteps` knob exists | ✓ | Optional config field; default 5; scalable to 50 |
|
||
|
||
Pre-flight infrastructure is GO — but scope below needs ratification.
|
||
|
||
---
|
||
|
||
## Scope-discovery item #1 — Cost analysis: $4 halt is 3-7× below realistic estimate
|
||
|
||
### Why per-step cost is NOT constant
|
||
|
||
A 50-step retrieval-augmented loop accumulates ALL prior retrieval results in the messages array (so the model sees them on subsequent turns). By step N, the input contains:
|
||
|
||
- system prompt (~2K tokens)
|
||
- kickoff user prompt (~0.5K)
|
||
- N-1 prior `{assistant: action}` messages (~0.2K each)
|
||
- N-1 prior `{user: retrieval_injection}` messages (~0.5K each)
|
||
|
||
**Total input at step 50:** ~2.5K + 49 × 0.7K ≈ **37K tokens per step** (without ContextManager engagement).
|
||
|
||
This is the killer: input cost dominates at high step counts. Output is bounded (~200 tokens for a JSON action emission).
|
||
|
||
### Real per-step cost (recomputed from pricing tables)
|
||
|
||
| Model | Input $/M | Output $/M | Per-step cost (input 37K, output 200) | 50 steps |
|
||
|---|---|---|---|---|
|
||
| Opus 4.7 | 15.00 | 75.00 | 37K×15 + 200×75 = **$0.570** | **$28.50** |
|
||
| GPT-5.4 | 2.50 | 10.00 | 37K×2.5 + 200×10 = **$0.094** | $4.70 |
|
||
| Qwen 3.6 (DashScope) | 0.70 | 2.80 | 37K×0.7 + 200×2.8 = **$0.027** | $1.34 |
|
||
| **Three-model total (no crash-resume)** | | | | **$34.54** |
|
||
|
||
Plus crash-resume doubles a portion (resumes from step 26 → re-runs 25 steps):
|
||
- Estimated total with one crash-resume cycle per model: **~$45–50**.
|
||
|
||
PM brief estimate: $2.00 Opus + $0.30 Qwen + $1.50 GPT + $0.30 self-judge + $0.90 buffer = $5.00.
|
||
|
||
Mismatch: **$4.30 cap vs ~$45 realistic = 9-10× off**, dominated by Opus.
|
||
|
||
### Why ContextManager helps but doesn't fully resolve
|
||
|
||
If ContextManager triggers compression at threshold (default 70% of budget), per-step input is capped at threshold + recent verbatim. Estimated cost with **aggressive compression at 4K-token budget**:
|
||
|
||
| Model | Per-step (input ~4K, output 200) | 50 steps |
|
||
|---|---|---|
|
||
| Opus 4.7 | 4K×15 + 200×75 = **$0.075** | $3.75 |
|
||
| GPT-5.4 | 4K×2.5 + 200×10 = **$0.012** | $0.60 |
|
||
| Qwen 3.6 | 4K×0.7 + 200×2.8 = **$0.0034** | $0.17 |
|
||
| **Three-model total (no crash-resume)** | | **$4.52** |
|
||
|
||
With one crash-resume (re-run 25 steps): add ~50% per model on average → **$6.78 total**.
|
||
|
||
Still over $4 halt, but tractable. **Even aggressive compression doesn't fit $4 cap with 50 steps × 3 models.**
|
||
|
||
### Three concrete options for PM ratification
|
||
|
||
| Option | Scope | Realistic cost | Trade-off |
|
||
|---|---|---|---|
|
||
| **A. Cost-cap-faithful (recommended for first run)** | Drop Opus; Qwen + GPT only; 50 steps; aggressive 4K context budget | **~$0.90** | Loses frontier-proprietary signal; H6 only validated for sovereign + open SOTA |
|
||
| **B. Three-model with smaller scope** | Opus + Qwen + GPT; **15 steps** (not 50); 4K context budget | **~$2.20** | Shorter run may not exercise context-manager threshold (compression may not trigger naturally) |
|
||
| **C. Three-model full scope; raise cap** | Opus + Qwen + GPT; 50 steps; 4K context budget; **raise hard cap to $8** ($7 halt) | **~$4.50–6.80** | Spends more, but hits the H6 hypothesis as written |
|
||
|
||
I recommend **Option A** (drop Opus, Qwen + GPT only) for these reasons:
|
||
- H6 says "Opus + Qwen + GPT" but real H6 utility is "long-task scenario completes on cross-model frontier WITHOUT data loss" — verified equally with 2 models as 3
|
||
- Opus is the marginal model (most expensive, frontier-proprietary contributes least to sovereign/open-platform claims)
|
||
- Frees budget for an Opus follow-up if Qwen + GPT both PASS
|
||
- Aligns with Phase 2's principled approach of starting cheap
|
||
|
||
If PM wants three-model coverage in one shot, **Option C** is the honest pick — but that's a budget-cap raise.
|
||
|
||
---
|
||
|
||
## Scope-discovery item #2 — "Identical final answer" criterion needs relaxation for real LLMs
|
||
|
||
### The problem
|
||
|
||
Brief acceptance criterion (binding):
|
||
|
||
> Mid-task crash → fresh runner → resume → identical final answer (replay determinism preserved across recovery)
|
||
|
||
**This is empirically impossible on real LLMs.** Even at temperature=0:
|
||
|
||
- GPU floating-point non-determinism (different kernel scheduling across runs)
|
||
- Provider server-side load balancing (different model server instances)
|
||
- Tokenizer / KV-cache state dependencies on input order
|
||
- Provider-side randomness in some routes (Anthropic, OpenAI documented)
|
||
|
||
A continuous run vs a crash-resume run will produce **semantically equivalent but byte-different** outputs on Opus / GPT / Qwen.
|
||
|
||
### Where strict identical-output IS testable
|
||
|
||
In **unit tests** with a mocked `LlmCallFn` (deterministic). Phase 3.4 already has a `replay determinism` test in `long-task-loop-integration.test.ts`:
|
||
|
||
> `replay determinism: identical llmCall + retrievalSearch → identical final answer (with checkpointStore)`
|
||
|
||
This passes. The state-machine determinism is verified.
|
||
|
||
### Proposed relaxation for the real-LLM gate
|
||
|
||
| Layer | Determinism standard |
|
||
|---|---|
|
||
| State machine (mocked LLM) | **Strict byte-identical** — already verified by Phase 3.4 unit test |
|
||
| Real-LLM end-to-end | **Semantic equivalence ≤ 0.30 Likert** (trio judge or self-judge) — same as the "compress vs uncompressed" criterion already in the brief |
|
||
|
||
Same Likert tolerance applied for both:
|
||
- Continuous run vs crash-resume run (replay determinism — relaxed)
|
||
- Compressed run vs uncompressed run (ContextManager preserves meaning)
|
||
|
||
**Halt-and-ping ask:** PM ratifies that "identical final answer" → "semantic equivalence (Likert ≤ 0.30)" for real-LLM portion of the gate.
|
||
|
||
---
|
||
|
||
## Scope-discovery item #3 — Synthetic 50-step task needs concrete spec
|
||
|
||
### Brief spec (what's there)
|
||
|
||
> Synthetic task ~50 steps long (multi-document analysis, accumulated context exceeds 70% of model context window threshold)
|
||
> Simulated retrieval queries per step (realistic scratch corpus)
|
||
|
||
### What's missing
|
||
|
||
- **Corpus shape:** How many docs? What content? Where stored? Stable + reproducible?
|
||
- **Question:** What does the agent answer? Must require ~50 retrieval-synthesis steps.
|
||
- **Retrieval function:** Real `HybridSearch` over a real `MindDB`? Or a deterministic mock?
|
||
|
||
### Proposed concrete design
|
||
|
||
**Corpus:**
|
||
- 30 historical-event documents (procedurally generated for stability)
|
||
- Each doc: ~500 words, fields = `{event_name, date, location, key_actors, theme_tags[], description}`
|
||
- Themes drawn from a fixed pool of 8 (e.g., "economic transformation", "scientific discovery", "social movement", "war/conflict", "political revolution", "cultural shift", "technological breakthrough", "natural disaster")
|
||
- Each event tagged 1-3 themes; total theme-occurrence distribution is non-uniform (forces ranking)
|
||
|
||
**Question:**
|
||
> "Survey all 30 historical events in the corpus. Identify the recurring themes and rank them by frequency of occurrence. For each theme in your ranking, cite ≥3 supporting events with their names and dates. Output a final ranked list with citations."
|
||
|
||
**Why this is ~50 steps:**
|
||
- ~30 retrievals (one or two per doc to cover all)
|
||
- ~10 synthesis turns (cluster themes, count, rank)
|
||
- 1 finalize
|
||
- ~41-45 expected steps; padded to 50 maxSteps for headroom
|
||
|
||
**Retrieval function:**
|
||
- Deterministic mock: pre-built keyword index → top-K cosine-like rank → returns docs as formatted strings
|
||
- Stable across runs (no real `MindDB` dependency)
|
||
- Why mock: avoids real-search non-determinism, keeps focus on agent-loop behavior
|
||
|
||
**Compression natural trigger point:**
|
||
With 4K context budget, threshold 70% → compression at ~2.8K tokens accumulated. After ~6-8 retrievals × ~500 tokens of injection text each = compression at step 6-8 (and again as more accumulates). Confirms ContextManager engagement.
|
||
|
||
**Halt-and-ping ask:** PM ratifies (or counter-proposes) corpus + question + retrieval design.
|
||
|
||
---
|
||
|
||
## Scope-discovery item #4 — ContextManager config is unspecified
|
||
|
||
The brief says "ContextManager engaged" but doesn't specify config. Per item #1 cost analysis, config matters MASSIVELY.
|
||
|
||
**Proposed defaults:**
|
||
|
||
| Param | Value | Rationale |
|
||
|---|---|---|
|
||
| `contextTokenBudget` | 4000 | Aggressive — keeps cost linear in step count |
|
||
| `compressionThreshold` | 0.7 | Default; compression triggers at 2800 tokens accumulated |
|
||
| `strategy` | `'retrieve-only'` | No LLM-summary cost during the loop; archives to retrieval index |
|
||
| `retainRecentChars` | 1500 | Last ~3 turns' worth of audit verbatim |
|
||
| `retrievalCacheMaxSize` | 50 | Cache up to 50 unique queries (matches step budget) |
|
||
| `retainRecentDecisions` | 8 | Audit trail keeps last 8 decisions verbatim |
|
||
| `estimateTokensFn` | default (`estimateStringTokens`) | Content-aware heuristic |
|
||
|
||
If PM wants `'summarize-only'` or `'hybrid'` (uses LLM for compression), add ~10-20% cost overhead per compression event. Estimated 4-6 compressions per task × 3 models × ~$0.005 each = trivial.
|
||
|
||
**Halt-and-ping ask:** PM ratifies ContextManager config or proposes alternatives.
|
||
|
||
---
|
||
|
||
## Scope-discovery item #5 — Self-judge cross-model methodology
|
||
|
||
The brief says:
|
||
> Self-judge methodology (Qwen Yes/No prompt) za consistency check across models
|
||
|
||
**Question for ratification:** is "self-judge" run as:
|
||
|
||
(a) **Each model judges its own output** (Mem0-style apples-to-apples — Qwen judges Qwen, Opus judges Opus, GPT judges GPT) — pure self-judge bias check, NOT cross-model comparison
|
||
(b) **Qwen judges all three** outputs (Qwen-as-judge cross-model) — cross-model with single judge, methodology used in v6 self-judge rebench
|
||
(c) **Trio judges all three** — same v6 oracle methodology (Opus + GPT + MiniMax F-mode); higher cost but methodologically consistent with prior gates
|
||
|
||
Option (b) aligns with brief wording ("Qwen Yes/No prompt") and Extension 3 PM finding (apples-to-apples self-judge requires same methodology across models).
|
||
|
||
**Halt-and-ping ask:** PM ratifies (b) Qwen Yes/No judges all three models' final answers, OR specifies alternative.
|
||
|
||
---
|
||
|
||
## Proposed go-forward (pending PM ratification)
|
||
|
||
If PM ratifies all five items + chooses **Option A** from item #1 (drop Opus, Qwen + GPT only):
|
||
|
||
1. Build synthetic corpus + retrieval mock + question (~30 min coding, $0)
|
||
2. Build long-task scenario runner using Phase 3.4's `runRetrievalAgentLoopWithRecovery` (~30 min coding, $0)
|
||
3. Run on Qwen continuous + Qwen with-crash-resume + GPT continuous + GPT with-crash-resume (~10 min wall, ~$0.90 real-API)
|
||
4. Self-judge final answers (Qwen Yes/No across all four runs) (~$0.05)
|
||
5. Compute Likert continuous-vs-resume + uncompressed-vs-compressed (re-runs without ContextManager would double the cost, so skip uncompressed-vs-compressed and rely on unit-test verification of compression purity)
|
||
6. Write acceptance gate results memo with H6 verdict
|
||
7. Total estimated: **~$1.00, ~30 min wall**
|
||
|
||
If PM ratifies **Option C** (three-model + raise cap to $8):
|
||
- Same flow, add Opus continuous + Opus with-crash-resume
|
||
- Total: ~$5–7, ~45 min wall
|
||
|
||
## Halt-and-ping ask (binding)
|
||
|
||
Five items need PM ratification:
|
||
|
||
1. **Cost vs scope tradeoff:** Option A (Qwen + GPT, $1; recommended) / B (3-model 15-step, $2.20) / C (3-model 50-step, raise cap to $8)
|
||
2. **"Identical final answer" relaxation:** strict for unit-test layer + Likert ≤ 0.30 for real-LLM layer
|
||
3. **Synthetic task design:** 30-event historical-event corpus + ranking question (or counter-proposal)
|
||
4. **ContextManager config:** 4K budget / retrieve-only / 1500 recent / 50 cache / 8 decisions (or counter-proposal)
|
||
5. **Self-judge:** Qwen-as-judge for all subject models (apples-to-apples cross-model, option b)
|
||
|
||
Cumulative spend so far: $0.00 (no API calls made; all surfaced from prior pilot data + pricing tables).
|
||
|
||
---
|
||
|
||
**End of pre-run halt. Standing HALTED awaiting PM ratification on items #1-#5 before kicking the gate.**
|