Skip to content

feat(foreman): flag unverifiable facts instead of inventing them (slicer anti-confabulation)#1062

Open
Defilan wants to merge 2 commits into
defilantech:mainfrom
Defilan:fix/slicer-anti-confabulation
Open

feat(foreman): flag unverifiable facts instead of inventing them (slicer anti-confabulation)#1062
Defilan wants to merge 2 commits into
defilantech:mainfrom
Defilan:fix/slicer-anti-confabulation

Conversation

@Defilan

@Defilan Defilan commented Jul 10, 2026

Copy link
Copy Markdown
Member

What

Teach the slicer's coder and planner to flag facts they cannot verify instead of inventing them, and recognize the resulting NEEDS-VERIFICATION outcome as a terminal non-failure that is never escalated.

Why

Fixes #1061. On the first live slicer run on #700, the coder invented AMD GPU metric names for a Grafana dashboard and reached for a community exporter that does not enumerate the target gfx1151 iGPU (confirmed by a contributor on the actual box). The output was plausible, complete-looking, and wrong on facts only hardware can settle. GO means "compiles and looks plausible," not "verified against reality," and there was no honesty layer between GO and a capability-failure NO-GO. Two distinct failures: a grounding gap (the fact lives outside the repo) and confabulation under that gap (the model invented rather than flagged).

How

  • Coder contract (config/foreman/system-prompts/coder.md, re-synced into both coder Agent CRs):
    • A "ground every external fact" rule in Step 2: never present a guess about another component's metric names, an API shape, or an image's hardware behavior as fact.
    • A NEEDS-VERIFICATION outcome in Step 3: NO-GO + extra.outcome="NEEDS-VERIFICATION" + extra.unverified listing each ungroundable fact and how to settle it, instead of guessing.
  • Planner (pkg/cli/slice_planner.go): a premise-classification step (settled-in-repo / repo-verifiable / externally-empirical), treating issue hedging as an unverified signal; UNSLICEABLE when the whole issue hinges on an empirical premise, verify-first or NEEDS-VERIFICATION for the affected slices otherwise.
  • Controller (internal/foreman/controller/workload_coder_escalation.go): NEEDS-VERIFICATION recognized as a terminal non-failure NO-GO and explicitly excluded from escalation, because a larger model cannot reach the ground truth (hardware, a live system's output) either. Mirrors the ALREADY-RESOLVED handling ([FEATURE] Foreman: distinct ALREADY-RESOLVED coder outcome (don't escalate the honest 'already done' bail) #970).

Testing

  • go build ./..., go vet, golangci-lint on the changed packages: clean.
  • go test ./pkg/cli/... ./internal/foreman/controller/... ./pkg/foreman/slicer/...: pass, including new TestShouldEscalateCoder case and TestIsNeedsVerificationCoder.
  • Empirical regression to follow: re-run [FEATURE] AMD GPU observability: rocm-smi exporter + llama.cpp /metrics + Grafana panel #700 through the slicer with these prompts deployed and confirm the coder returns NEEDS-VERIFICATION (naming the unverifiable metric names / the iGPU-enumeration premise) instead of inventing.

Deferred follow-up

Rollup surfacing: a dedicated classifyChildren bucket, a CoderNeedsVerification Workload condition, and cascade-skip so a needs-verification slice does not cascade-fail integrate/reconcile. Best designed after observing a real NEEDS-VERIFICATION run (the #700 re-validation), so the terminal-state semantics match reality rather than a guess.

Checklist

  • Tests added/updated
  • go build ./... passes
  • Lint passes
  • Commits are DCO signed-off
  • Coder prompt change re-synced into the Agent CR inline copies

Assisted-by: Claude (Anthropic) — analysis, prompt/contract design, controller guard, and tests; reviewed by the maintainer.

Defilan added 2 commits July 10, 2026 11:20
Add an anti-confabulation contract to the slicer's coder and planner so a
load-bearing fact the model cannot ground from the workspace is surfaced,
not invented.

Coder (config/foreman/system-prompts/coder.md + the two coder Agent CRs it
is mirrored into): a "ground every external fact" rule in Step 2 (never
present a guess about another component's metric names, an API shape, or an
image's hardware behavior as fact) and a NEEDS-VERIFICATION outcome in Step 3
(NO-GO + extra.outcome="NEEDS-VERIFICATION" + extra.unverified listing each
ungroundable fact and how to settle it) instead of guessing.

Planner (pkg/cli/slice_planner.go): a premise-classification step that labels
each load-bearing premise settled-in-repo / repo-verifiable /
externally-empirical, treats issue hedging ("e.g.", "should be hands-verified")
as an unverified signal, outputs UNSLICEABLE when the whole issue hinges on an
empirical premise, and otherwise routes the affected slices to verify-first or
NEEDS-VERIFICATION rather than confident guessing.

Motivated by the first live slicer run on defilantech#700, where the coder invented AMD
GPU metric names for a Grafana dashboard and reached for a community exporter
that does not enumerate the target iGPU: plausible, complete-looking, and wrong
on facts only hardware can settle.

Refs defilantech#1033

Signed-off-by: Christopher Maher <chris@mahercode.io>
… outcome

A coder that returns NO-GO + extra.outcome="NEEDS-VERIFICATION" (it could not
ground a load-bearing external fact, defilantech#1033) must not be escalated to a larger
model: the larger model cannot reach the ground truth (hardware, a live
system's output) either. Add the outcome constant and isNeedsVerificationCoder
helper mirroring the ALREADY-RESOLVED handling (defilantech#970), plus an explicit guard
in shouldEscalateCoder with table-test coverage.

Refs defilantech#1033

Signed-off-by: Christopher Maher <chris@mahercode.io>
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...al/foreman/controller/workload_coder_escalation.go 71.42% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Slicer coder/planner invent unverifiable facts instead of flagging them

1 participant