Problem log — eggs1 test run
Agents append problems here during the flf-epistack quick test run. Purpose: catch major errors or problems in the pipeline on a fast N=10 shakedown — before the real N=25/50 runs. This is NOT a place to record minor imperfections.
How to append (every agent)
- Only log BLOCKER or MAJOR problems. Skip minor/cosmetic imperfections — the run is deliberately quick and rough, and sub-optimal output is expected and fine.
- Append your entry at the bottom of
## Log, using a single write (e.g. a>>shell append) so parallel appends don’t clobber. Never edit or delete another agent’s entry. - One block per problem, in this format:
### [SEVERITY] step <n> / <slice or agent> — <short title>
<1–3 lines: what happened, where (file / script / cross-step interface), and why it blocks or corrupts the run>
Severity scale:
- BLOCKER — stops the step or run, or corrupts the graph; must be fixed before the real runs.
- MAJOR — wrong/misleading output, a broken cross-step interface, or instructions ambiguous/contradictory enough that a competent agent could easily get them wrong.
The orchestrator appends a ## Ranked summary at the end of the run: deduped, all BLOCKERs first then MAJORs. That ranked list is the deliverable Simon reads.
Log
[MAJOR] step 1 / heterogeneity-subgroup-dose — no schema field for “surrogate vs hard endpoint”
The run’s initial_prompt.md and my slice brief require tagging each source’s outcome as surrogate (lipids/glycemia) vs hard (events) endpoint “so downstream clustering can separate them,” but step-01’s source-node frontmatter schema defines no such field, and grepping step-03/04/05/10 for endpoint|surrogate finds nothing either — no later step formalizes it. I added an ad-hoc endpoint_type frontmatter field + prose restatement on S-1..S-6, but slice-1/slice-2 sources have no reason to add it (each is single-endpoint-type), so the signal is inconsistent across the pool and step 4’s clustering may have to infer endpoint type from free-text content instead of a field.
[MAJOR] step 1 / cohorts-hard-endpoints — create_node.py snippet’s required cwd is unstated
The verbatim mint snippet in every searcher brief (python3 .claude/skills/flf-epistack/scripts/create_node.py <analysis-dir> --type source --title "...") gives both the script path and analysis-dir as relative, with no stated required cwd. A fresh agent naturally treats the given “Analysis directory” as its working context first; running the snippet from inside it (or any cwd but the repo root) fails with “no such file” for the script. Hit this on all 7 of my mint calls before switching to absolute paths — a likely retry for any searcher who doesn’t happen to guess repo-root cwd.
[MAJOR] step 2a / scorer S-11..S-20 — brief mislabels S-14’s data basis as “PHS/WHS”
The slice brief lists “S-14 on the Physicians’/Women’s Health Study (PHS/WHS)”, but S-14 (Djoussé 2008, AJCN) uses only the all-male Physicians’ Health Study; WHS belongs to S-4, not S-14. A scorer following the brief literally would attribute WHS data to a male-only study and link S-14 to a WHS basis, manufacturing a false correlation edge in step 5. I minted a PHS-only D node (D-9) instead. The brief’s per-source data_basis hints need to match each paper’s actual cohort.
[MAJOR] step 2a / slice S-1..S-10 — data-basis granularity for pooled multi-cohort studies is undefined
initial_prompt scope-note 2 says “give each cohort its own data-basis node,” but the 2a slice brief describes S-7 (Zhong, IPD pool of 6 US cohorts) and S-9 (Harvard pool of NHS/NHSII/HPFS) as resting on “the pooled US cohorts”/“the NHS family” — a single basis. So a pooled analysis can be nested as 1 D node or as N per-cohort nodes, with no rule saying which; the choice directly changes step-5’s correlated-evidence counting (1 vs N evidence units, and whether a component cohort like Framingham can be shared with another source). I split S-9 into NHS/NHSII/HPFS (S-3 shares the NHS node) but minted ONE pooled node for S-7 (no other source uses its components) — defensible but inconsistent, and a different scorer could reasonably mint 5 nodes for S-7. Needs an explicit rule for pooled/IPD analyses.
[MAJOR] step 3 (+ recurring) / orchestrator — create_node.py stdin requirement not shown in mode-file invocation examples
The one-line create_node.py ... --type X --title "..." example in step-01/02/03 mode files omits that the node markdown (with a {{ID}} placeholder) MUST be piped on stdin. Both step-3 extractors (and earlier agents) had their first mint call fail before discovering this. Fix: show the ... | create_node.py pipe (or a heredoc) in every mode file’s example.
-
MAJOR (step 4b, hard-endpoint cluster HC-2): 4a kept H-4/H-9/H-10 as distinct actives (discriminable by scope riders) but all assert ~null direction, so they are not pairwise mutually-exclusive members of one direction cluster. 4b cannot merge (out of remit) so must accept intra-cluster overlap — the null branch is really one answer partitioned by population/endpoint. Pipeline gap: no clean mechanism for “same-answer, different-scope” hypotheses (scope-conditioned members, or a merge-with-scope-rider at 4a). Handled by accepting overlap + documenting; also flagged milder co-hold strain in HC-3 (subgroup vs responder axes).
-
MAJOR (step 5, HC-2 slice + orchestrator):
create_node.py --titledoes not strip a{{ID}}placeholder passed in the title, silently producing corrupt filenames likeE-14 - {{ID}} - ....md. The mode file requires{{ID}}in the piped body, so mirroring it into--titleis a natural misreading; 10 of 23 edge files had to be renamed by hand. Fix: strip/reject{{ID}}in--title, and state in the mode file that the placeholder belongs in the body ONLY. -
MAJOR (step 5, HC-3 slice): the HC-3 carve is empirically undiscriminated, not just theoretically strained — of 5 edges, E-9/E-10 separate H-6 from residual H-13 and E-11/E-12 separate H-7 from H-13, but NO observation separates H-6 from H-7. Two members no in-scope observation can pull apart are exactly what step 4a’s discriminability test is meant to merge, so 4a’s “discriminable” verdict was wrong here and step 4b had no remit to fix it. Confirms the same root gap as the HC-2 null-members entry: no mechanism to re-merge once linking reveals members are indistinguishable (candidate fix: a step-5 feedback signal back into 4a).
-
MAJOR (step 5 consolidator → step 8 interface):
build_correlation_groups.pygroups strictly per-cluster, so an observation linked into two clusters never has its two edges joined — 8 of 23 edges carry nogroupdespite their observation being correlated elsewhere (e.g. O-17 is in CG-7 inside HC-3 but its HC-1 edge E-6 is ungrouped). Correct semantics for per-cluster joint likelihoods, but nothing documents it: step 8 must not read “missinggroup” as “independent evidence”. Fix: state the per-cluster scoping in step-05/step-08 mode files, or have the script write an explicitgroup: none-in-clustermarker. -
MAJOR (step 7, all three clusters): every cluster child independently chose to mark zero edges
used_for_prior, with identical reasoning — every inbound edge is case-specific discriminating evidence, so consuming any would strip it from step 8, and correlation groups force all-or-none marking of a whole CG. So theused_for_priormechanism never fired in the entire run and the step-7/step-8 partition degenerated to “prior = pure outside view, step 8 = all evidence”. Either that IS the intended design (then the step-07 spec should stop implying base-rate edges are normally pulled, and Check 5 should confirm zero marks pass), or the mechanism needs edges that genuinely carry reference-class rates — which step 3 currently never extracts as separate observations. Also note the CG all-or-none coupling: you cannot consume one edge of a correlation group for the prior and leave its partner for step 8. -
MAJOR (step 7 → steps 9/10 presentation): in HC-2 the three null members partition one branch, so normalised per-member probabilities are NOT comparable across members — H-9’s 0.257 outranks H-2’s 0.126 purely because the null was split three ways while the directional answers were not. Read as a member ranking this says “H-9 is the leading hypothesis”, which is misleading; the honest read is branch totals (~0.57 null vs 0.13 protective vs 0.10 harmful vs 0.20 varies). Nothing in the pipeline marks members as belonging to a shared branch, so steps 9/10 have no way to know they must aggregate before presenting. Fix: a branch/scope-group field on cluster members, or forbid same-answer partitions at step 4.
-
BLOCKER (step 8, HC-2 — scope-restricted members drift upward by never being tested): a member whose scope rider excludes an observation correctly gets a likelihood near the anchor (~1) on that observation, because it genuinely predicts nothing there. But across many observations this means the narrowest-scope member accumulates relative advantage purely by abstaining — CG-3 priced H-9 at 0.72 as “near out-of-scope and so near-uninformative”, CG-4 at 0.55, CG-5 at 1.00 (anchor). H-9 therefore rises not because evidence supports it but because most evidence cannot touch it. This is a genuine Bayesian defect, not a presentation issue: it silently rewards narrow hypotheses, and at N=25/50 with more scope-refined members it will systematically crown the most-hedged hypothesis. Any cluster mixing broad and scope-restricted members is affected. Fix required before production runs — either forbid scope-restricted members inside a direction cluster (make scope a separate cluster dimension), or renormalise likelihoods over only the members a given observation is in-scope for.
-
MAJOR (step 8, HC-1 — self-confirming hypothesis/evidence loops): H-5 was extracted from S-19 and its ONLY evidence edges (E-3, E-4 = CG-2) are S-19’s own observations, so its posterior rests entirely on the data that generated it. The CG-2 child noticed and hand-capped the H-5:H-1 ratio at ~3.3:1 to avoid circularity, but nothing in the pipeline detects or prevents this — it depended on one child’s judgement. Same shape affects any hypothesis whose
sourceis the sole basis of all its edges. Fix: flag at step 5 or 8 when an edge’s observation traces to the same source as the hypothesis it most favours, and require an explicit discount. -
MAJOR (step 4b → step 8, residuals written as substantive claims): step-04 rule 2 requires a residual’s
statementto read “the answer is something not listed here”, NEVER as one more named answer. Two of the three minted residuals violate this: H-13 = “Egg intake’s effect is essentially homogeneous across people - no stable protected subgroup or intrinsic responder class exists” (a substantive homogeneity claim) and H-12 = “not a single population-wide direction (e.g. non-monotonic or J-shaped)” (a substantive J-shape claim). Only H-11 is a true catch-all. Step-4 Check 3 does not catch this — it only verifiesresidual: trueis present and listed last, never inspecting the statement. Downstream consequence is concrete: step-8 rule 3 says the residual should get a middling likelihood, but CG-7 had to argue H-13 down to 0.25, and CG-4 anchored on the residual H-12 at 1.0 — it best predicted the PHS pattern, i.e. the “catch-all” is competing as a first-class hypothesis and absorbing mass on its own merits. Fix: extend Check 3 to inspect residual statements, or drop the middling-residual assumption in step 8. -
MAJOR — step 9 / HC-1: self-confirming loop not detected by the pipeline. H-5 was extracted from S-19 and its only evidence edges (E-3, E-4 = CG-2) are S-19’s own observations; the same holds weakly for H-8 (extracted from S-8, strongest edge E-7 = S-8’s O-18). The CG-2 child hand-capped the H-5:H-1 ratio at ~3.3:1 to limit circularity, but nothing in steps 5-8 requires or checks this, and no cap was applied to the H-8/E-7 case. Needs a pipeline-level rule: an edge whose source is the hypothesis’s own extraction source must be flagged and capped.
-
MAJOR — step 9 (all slices, tooling): the Write tool refuses to create the step-9 review file, erroring “Subagents should return findings as text, not write report files”. Step 9’s required artifact is a prose review note, so every step-9 child hits this. Worked around with a shell heredoc append; a child that takes the error at face value will silently produce no artifact.
-
MAJOR — step 9, HC-3 slice: Write tool refused the deliverable review file (“Subagents should return findings as text, not write report files”); had to write it via a bash heredoc instead. Any step-9 child using Write will be blocked and may silently produce no artifact.
-
MAJOR — step 9, HC-2 slice: the
Writetool refuses to create the step-9 review artifact when run inside a subagent (“Subagents should return findings as text, not write report files”). Step 9’s entire deliverable is a prose.mdreview, so every parallel step-9 slice will hit this. Worked around by writing via a shell heredoc +cp. Step 9 (and any prose-artifact step) needs to either run in the main agent or instruct children to write via shell. -
MAJOR — step 10 / final report:
external_consensusis required by step 10 part 4 (“the labelled field recording what the field thinks”) but no HC-N cluster file in this run has the field populated, so there is nothing to compare against. Either step 7/8 does not actually mint it or the field name differs; step 10 had to substitute prose from general knowledge, which weakens the rule-5 independent-impression check.
Ranked summary
Full end-to-end run completed (steps 0–10, N=10 curated sources). 19 raw entries deduped to 16: 2 BLOCKERs, 14 MAJORs. Ranked by severity, then by how much they’d bite at N=25/50.
BLOCKERs — fix before the real runs
-
[step 4a → step 8] HC-2 is not a partition, so its posterior is not a probability distribution — and the scope riders used to price it were fabricated. Two compounding faults:
- (a) Non-exclusive members. H-4, H-9 and H-10 can all be true simultaneously, and HC-2’s own
exclusivityfield admits it (“STRAINED: … not pairwise mutually exclusive”). Normalising over a non-exclusive set does not yield a distribution over anything, so every HC-2 number — including the headline 0.349 — is arithmetically fine but semantically undefined. Step-04 rule 2 makes exclusivity the thing that makes the cluster a probability space; 4a passed a set that violates it and every Check downstream still passed. - (b) Fabricated scope riders. H-9’s actual
statementis “Habitual egg intake up to ~1/day carries no material excess CVD risk in general adult populations” — a BROAD claim, near-duplicate of H-10. The narrow rider “generally healthy Western adults” appears in no hypothesis node: it was invented in 4b’s prose (structure.md+ HC-2 body, inferring scope from S-9’s Harvard cohorts) and then propagated by the orchestrator into every step-7/step-8 brief as if it were the claim. So the entire null-branch likelihood spread was priced against a distinction that does not exist in the graph. Same failure shape as entry 15 (S-14 “PHS/WHS”), but larger: orchestrator prose overwrote node content across two steps. Fix: 4a must merge H-9/H-10 (or scope must become its own cluster dimension); and briefs must quote nodestatements verbatim rather than paraphrasing them.
Correction to an earlier reading of this run. During the run I logged this as “scope-restricted members drift upward by abstaining” — a claimed defect in the Bayesian update. That diagnosis was wrong and is withdrawn. The runner composes
t·lik[i] + (1−t)·margwheremargis the prior-weighted average likelihood, which already implements the correct shrinkage. Checking H-9’s five likelihoods against each block’s ownmarg: CKB 0.72 vs marg 0.58 (gain), PHS 0.55 vs 0.55 (neutral), EPIC 1.00 vs 0.88 (gain), PURE 0.40 vs 0.46 (loss), Harvard 1.00 vs 0.71 (gain). H-9 gains where it genuinely fits the data (4 of 5 cohorts show no excess risk, which is exactly what it asserts) and loses where it doesn’t. That is ordinary correct updating, not an artifact. The real residual issue is narrower — see MAJOR 3a below. - (a) Non-exclusive members. H-4, H-9 and H-10 can all be true simultaneously, and HC-2’s own
-
[steps 9–10, tooling] The
Writetool refuses subagent report files, erroring “Subagents should return findings as text, not write report files”. Hit 4 of 4 children whose deliverable is a prose.md(all three step-9 reviews + step 10). All four happened to work around it with a shell heredoc, but a child that accepts the error produces no artifact at all, silently — the run would report success with the two main human-readable deliverables missing. Children logged this MAJOR; escalated because it is 100% reproducible and fails silently. FIXED 2026-07-20: not asettings.jsonmatter (the refusal is injected into the subagent system prompt; no permission or hook governs it), so the fix went into the specs —step-09-cluster-review.mdandstep-10-final-report.mdnow mandate a quoted shell heredoc, explain why the refusal is spurious, warn that accepting it yields no artifact, and require awc -wverification. No manual setup step is needed before a run.
MAJORs
3a. [step 8] No stated convention for what likelihood a member gets when it is SILENT on an observation. The runner’s mixture makes the correct answer exact: a member that says nothing about E should be given marg (the prior-weighted average likelihood of that block), which leaves its posterior share unchanged — evidence about a domain your hypothesis doesn’t cover must not move it. Assigning the anchor (1.0, the maximum) instead treats “predicts nothing” as “predicts perfectly” and makes it gain; assigning a penalty treats silence as disconfirmation. The mode file states neither, and children used opposite conventions: CG-3 gave H-9 0.72 reasoning “near out-of-scope and so near-uninformative” (→ above marg, a gain), while CG-6 gave it 0.40 reasoning “largely outside H-9’s scope — compatible but unpredictive” (→ below marg, a penalty). Both children were being careful; nothing told them which way silence points. Fix: state the silent ⇒ lik = marg rule in step-08, and have the runner warn when a vector’s spread implies a member was priced as silent.
-
[step 4a/4b] No mechanism for “same answer, different scope” hypotheses, and no way to re-merge once step 5 proves members undiscriminated. Two independent instances: HC-2’s H-4/H-9/H-10 all assert ~null and differ only by scope rider; HC-3’s H-6/H-7 are different heterogeneity axes that can co-hold, and step 5 found no observation separating them at all. 4a called both “discriminable”; 4b had no remit to merge. This is the root cause of BLOCKER 1 and of the unidentified H-6:H-7 ratio. Fix: a step-5 feedback signal back into 4a, or scope-conditioned members.
-
[step 4b → step 8] Residuals written as substantive claims; Check 3 never inspects the statement. Step-04 rule 2 requires a residual to read “something not listed here”; 2 of 3 violate it (H-12 = a J-shape claim, H-13 = a homogeneity claim). Only H-11 is a true catch-all. Consequences are real, not cosmetic: CG-4 anchored on residual H-12 at 1.0, and in HC-3 genuinely unlisted answers (APOE genotype, baseline LDL, microbiome) are held nowhere, so the cluster is not a proper probability space and residual mass understates “none of the above”.
-
[step 8] Self-confirming hypothesis/evidence loops are undetected. H-5 was extracted from S-19 and its only edges (CG-2) are S-19’s own observations; H-8’s defining evidence E-7 likewise comes from S-8, its own source. The CG-2 child hand-capped the first at ~3.3:1 out of its own judgement; the second was never discounted, so HC-1’s 0.81 headline is partly circular. Nothing in the pipeline flags this. Fix: detect when an edge’s observation traces to the same source as the hypothesis it most favours, and require an explicit discount.
-
[step 7] The
used_for_priormechanism never fired in the entire run. All three cluster children independently marked zero edges, with identical reasoning: every inbound edge is case-specific discriminating evidence, so consuming any would starve step 8. The step-7/step-8 partition degenerated to “prior = pure outside view, step 8 = all evidence”. Either that is the intended design (then the mode file should stop implying base-rate edges are normally pulled) or step 3 needs to extract reference-class rates as separate observations. Also: correlation groups force all-or-none marking — you cannot take one edge of a CG for the prior and leave its partner for step 8. -
[step 7 → steps 9/10] Per-member probabilities are not comparable when members partition one branch. H-9’s 0.349 outranks H-2’s 0.126 purely because the null was split three ways while the directional answers were not. Read as a ranking this says “H-9 is the leading hypothesis” — misleading. Nothing marks members as sharing a branch, so steps 9/10 have no way to know they must aggregate before presenting. Fix: a branch/scope-group field on cluster members.
-
[step 5 → step 8]
build_correlation_groups.pyscopes strictly per-cluster, undocumented. An observation linked into two clusters never has its two edges joined; 8 of 23 edges carry nogroupdespite their observation being correlated elsewhere. Correct semantics for per-cluster joint likelihoods, but step 8 could easily read “nogroup” as “independent evidence”. Fix: document it, or emit an explicitgroup: none-in-clustermarker. -
[step 3, recurring — hit nearly every minting child]
create_node.py’s stdin requirement is absent from every mode-file example. The one-line--type X --title "..."snippet omits that the node markdown, with a{{ID}}placeholder, MUST be piped on stdin. Multiple agents’ first mint call failed. Fix: show the pipe or heredoc in every mode file. -
[step 5]
create_node.py --titledoes not strip a{{ID}}placeholder, silently producing filenames likeE-14 - {{ID}} - ....md. Since the body legitimately requires{{ID}}, mirroring it into--titleis a natural misreading; 10 of 23 edge files needed manual renaming. Fix: strip or reject it in--title. -
[step 1, recurring]
create_node.py’s required cwd is unstated. Both the script path and analysis-dir are given relative with no stated working directory; running from the analysis dir (the natural choice) fails. Fix: use absolute paths in examples or state the cwd. -
[step 2a] Data-basis granularity for pooled/IPD multi-cohort studies is undefined. Scope-note says “each cohort its own node”, but pooled analyses (S-7 = 6 US cohorts, S-9 = NHS/NHSII/HPFS) can be 1 node or N with no rule. The run split S-9 but not S-7 — defensible yet inconsistent. This directly changes step-5 correlated-evidence counting (1 vs N evidence units). Needs an explicit rule; matters much more at N=25/50 where pooled re-analyses proliferate.
-
[step 1] No
endpoint_typefield exists in the source schema although briefs required tagging each source surrogate-vs-hard endpoint “so downstream clustering can separate them”. Added ad-hoc on S-1..S-6 only, so the signal is inconsistent pool-wide and step 4 had to infer endpoint type from free text — for a run whose central finding is the surrogate/hard-endpoint split. -
[step 10] No cluster has
external_consensuspopulated, though step-10 part 4 requires it; the child substituted prose, weakening the independent-impression check. Either populate it at step 4/9 or drop the requirement. -
[step 2a, brief-authoring] The orchestrator brief mislabeled S-14’s data basis as “PHS/WHS”. S-14 (Djoussé 2008) is PHS-only; WHS belongs to S-4. A scorer following the brief literally would have manufactured a false step-5 correlation edge. The scorer caught it and minted PHS-only. Per-source hints in briefs need checking against the actual paper.
-
[step 4b, minor-but-real] The
--title/ filename convention drifted between children (×vsx, em-dash vs hyphen) with no normalisation rule, so edge filenames are cosmetically inconsistent. Harmless now; would complicate any future filename-based tooling.
What worked
- Correlation-group construction was exactly right: 7 CG nodes matching the expected data-basis partition (D-4, D-8, D-10, D-7 + self-basis pairs), and the one expected pair that didn’t form (O-13/O-14) was correctly suppressed because O-14 orphaned, leaving 1 live edge.
check_missing_evidence_links.pygate: clean.attach_argument_backlinks.pyresolved both bare-id and full-title wikilink formats. Orphan detection moved exactly the 2 non-discriminating observations (O-3 yolk cholesterol content, O-14 satiety).- The post-step-8 model run caught nothing because nothing was wrong — all 15 evidence blocks had correct vector lengths across three different cluster sizes (4/6/3), including two batches that deliberately spanned clusters.
- Step 6’s argument corrections propagated into step 8 pricing: A-3’s correction (significance-loss vs point-estimate-movement conflation) cut H-4’s EPIC likelihood from a would-be 2–3x to ~1.15x. That cross-step interface works.
- Children reliably surfaced structural problems unprompted — the abstention artifact and the H-6/H-7 non-discrimination were both found by children, not by the orchestrator.