Skip to content

feat(truth-resolver): alignment-gating prototype over intent/context/value - #19

Merged
ZuluYokohama merged 10 commits into
masterfrom
feat/truth-resolver-prototype
Jun 6, 2026
Merged

ZuluYokohama merged 10 commits into
masterfrom
feat/truth-resolver-prototype

Conversation

@ZuluYokohama

@ZuluYokohama ZuluYokohama commented Jun 6, 2026 •

Copy link
Copy Markdown
Collaborator

Truth-Resolver prototype: alignment-gating over intent/context/value

Branch-target note: This fork has no dev branch and does not use main; default/active branch is master. Internal fork PR, not an upstream contribution → targets master. Bundles the design spec + implementation plan + the prototype so the full design story is reviewable in one place.

Who is submitting this PR? (required)

Field Value
Your model + version Orchestration: Claude Opus 4.8 (claude-opus-4-8, 1M context). Implementation/review subagents: dispatched at the opus tier; the harness does not surface the exact minor version and the tier selector cannot pin 4.7, so workers most likely ran on the session default Opus 4.8, not 4.7. Disclosed honestly.
Harness + version Claude Code (CLI). Exact build/version not surfaced to the agent.
All plugins installed superpowers 5.1.0, plugin-dev, context7 (MCP). MCP servers: claude.ai Gmail / Google Calendar / Google Drive / Hugging Face.
Human partner who reviewed this diff b.jones@jtech.ai (ZuluYokohama)

What problem are you trying to solve?

The framework has gates that purge mutations breaking the [INTENT] ≡ [CODE OPS] ≡ [VALUE GEN] isomorphism (AAA, Quantum, Visual), but no gate that resolves alignment across the actors involved (user / agent / subagent / element). During this session the orchestrator repeatedly had to judge, ad hoc, whether a proposed action was aligned with the user's intent and net-positive on value (e.g. whether to apply a reviewer's suggestion, whether a fix preserved the doctrine). That judgment was implicit and unrepeatable. This prototype makes it an explicit, inspectable function — the first concrete step toward a "truth resolver" that can gate autonomous action on verified alignment.

What does this PR change?

Adds scripts/truth_resolver.py (and tests + fixtures): a deterministic gate that distills each actor's intent/context/value, scores their multi-set overlap and the action's net value, and returns a Verdict {passed, alignment, value, rationale, dissent}. The one genuinely-semantic step (distillation) is isolated behind a @runtime_checkable Distiller Protocol — DeterministicDistiller now, an LLM distiller a future drop-in (deliberately not implemented; the seam is proven satisfiable by a stub). Also includes the design spec and TDD plan.

Is this change appropriate for the core library?

No. This is a fork-specific framework component for the RotarySlider/Autoresearch-Superpowers gate family (siblings: aaa_quality.py, quantum_gate.py, evolution_gate_template.py). It is general-purpose within this fork's domain but not a general Superpowers core skill. Internal fork PR only.

What alternatives did you consider?

  • LLM-backed resolver from the start — rejected for the prototype: non-deterministic, needs model access to even run, hard to unit-test. Captured instead as the Distiller seam so the semantics arrive without a rewrite.
  • Pure deterministic vector resolver with no seam — rejected: would quietly hollow out the concept ("semantic distillation" reduced to token overlap with no upgrade path).
  • Wiring directly into the evolution loop now — rejected (YAGNI): prove the contract standalone first; live integration is a later cycle.

Does this PR contain multiple unrelated changes?

No. One component (the truth-resolver) plus its own design spec and plan. The docs and code are a single coherent unit (design → plan → implementation of the same feature).

Existing PRs

Environment tested

Harness Harness version Model Model version/ID
Claude Code (CLI) not surfaced to agent Claude Opus 4.8 orchestration; opus-tier subagents
  • python -m pytest tests/test_truth_resolver.py -q → 26 passed (Python 3.14.0, pytest 9.0.2).
  • CLI: python scripts/truth_resolver.py tests/fixtures/action_pass.json → "passed": true, exit 0; action_fail.json → "passed": false, exit 1; bad path → error: ..., exit 2.
  • Strict TDD: each of the 6 build tasks wrote a failing test, observed RED (the function-specific AttributeError), then implemented to GREEN. Deterministic — no network, no API key, no LLM call.

New harness support (required if this PR adds a new harness)

N/A — no new harness.

Evaluation

N/A for skill evals — this is a framework component, not a behavior-shaping skill. Functional evaluation: 6 red→green TDD cycles (RED proof captured per task), then two independent reviewer passes — a spec-compliance review (re-ran the suite, verified the Jaccard is true multi-set |∩all|/|∪all|, value > 0 strict, no LLMDistiller, zero non-deterministic calls) and a code-quality review (empirically exercised zero/single-actor and empty-dimension edge cases, found unguarded CLI input + an untested weights override, both since fixed and re-verified at 26 tests).

Rigor

  • Skills change — N/A (no skill content modified).
  • Tested adversarially — reviewers re-derived correctness from the code and ran edge cases (empty/one actor, star-unpack hazards, threshold boundaries), not from the implementer's report.
  • Did not modify behavior-shaping content.

Human review

  • A human has reviewed the COMPLETE proposed diff before submission.

Summary by CodeRabbit

  • New Features

    • Truth-resolver CLI prototype: assesses actions by actor alignment and value scoring, emits JSON verdicts with pass/fail, scores, rationale, and dissent.
  • Documentation

    • Added design spec and implementation plan outlining pipeline, interfaces, CLI behavior, and definition of done.
  • Tests

    • New deterministic test suite covering distillation, overlap, value scoring, resolve logic, CLI, plus JSON fixtures for pass/fail cases.

RogueGringo and others added 9 commits June 6, 2026 00:49
Hybrid truth-resolver gate (SP2, prototype-first): distill -> overlap
(intent/context/value) -> score_value -> Verdict, with the semantic
distillation step behind a pluggable Distiller seam (deterministic now,
LLM later). Encodes knowledge-integration as a value dimension. Runs and
unit-tests with no API key. Doctrine (SP1) and operating-mode binding
(SP3) are deferred cycles.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TDD plan (pytest) for scripts/truth_resolver.py: 6 tasks building
dataclasses + Distiller seam, DeterministicDistiller, Jaccard overlap,
shared-value-gated value scoring, resolve()+dissent, and a CLI — 23
deterministic tests, no API key, LLMDistiller left as a proven seam.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- main() returns 2 (not a traceback) on missing file / bad JSON / missing keys
- add tests for the error paths and for the weights override + partial fallback
@coderabbitai

coderabbitai Bot commented Jun 6, 2026 •

Copy link
Copy Markdown

Linter diff in the way? Review this PR in Change Stack to focus on meaningful changes and expand context only when needed.

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a deterministic Truth-Resolver: design, dataclasses and Distiller protocol, deterministic distillation/tokenization, Jaccard overlap and weighted value scoring, resolve logic with dissent reporting, CLI entrypoint, fixtures, and comprehensive pytest coverage.

Changes

Truth-Resolver Deterministic Prototype

Layer / File(s) Summary
Design specification and implementation plan
docs/superpowers/specs/2026-06-06-truth-resolver-prototype-design.md, docs/superpowers/plans/2026-06-06-truth-resolver-prototype.md
Design doc and TDD plan specify pipeline (distill → overlap → score_value → resolve), contracts, outputs, input schema, scope boundaries, and Definition of Done.
Data contracts, constants, and pluggable protocol
scripts/truth_resolver.py (lines 1–44), tests/test_truth_resolver.py (lines 1–29)
Module constants (ALIGN_THRESHOLD, VALUE_DIMENSIONS, DEFAULT_WEIGHTS), AlignmentVector and Verdict dataclasses, and runtime-checkable Distiller protocol; tests assert fields and Protocol satisfiability.
Tokenization and deterministic distillation
scripts/truth_resolver.py (lines 46–85), tests/test_truth_resolver.py (lines 31–56)
_tokens() normalizes text into lowercased token/tag sets; DeterministicDistiller.distill() converts actor dicts to AlignmentVectors with intent/context token sets and normalized values; tests cover punctuation, lowercasing, and defaults.
Multi-actor Jaccard overlap alignment scoring
scripts/truth_resolver.py (lines 59–85), tests/test_truth_resolver.py (lines 62–93)
overlap() computes per-dimension Jaccard agreement across actors and aggregates an alignment score; handles identical, disjoint, partial overlap, and vacuous-empty cases.
Value claim-to-dimension mapping and weighted scoring
scripts/truth_resolver.py (lines 87–121), tests/test_truth_resolver.py (lines 95–129, 242–248)
CLAIM_MAP maps claim phrases to (dimension, polarity); score_value() sums weighted polarity only for dimensions shared by all actors, supports weight overrides, and ignores unmapped claims; tests cover positive/negative/unknown claims and weight fallback.
Resolution gate and dissent reporting
scripts/truth_resolver.py (lines 123–157), tests/test_truth_resolver.py (lines 131–181)
resolve() distills actors, computes alignment/value, gates on alignment >= threshold and value > 0, returns Verdict with rationale and dissent actor/dimension attribution; tests verify pass/fail, dissent naming, and threshold override.
CLI entry point, test fixtures, and end-to-end validation
scripts/truth_resolver.py (lines 160–187), tests/fixtures/action_pass.json, tests/fixtures/action_fail.json, tests/test_truth_resolver.py (lines 183–248)
main() loads JSON, calls resolve(), prints verdict JSON, and returns exit codes (0/1/2); includes pass/fail fixtures and tests for usage, missing files/keys, subprocess invocation, and CLI output parsing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit reads tokens in the night,
Distills each actor by soft lamp light.
Jaccard sings where intents align,
Values sum, the verdict signs.
A little gate decides what's right. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: a deterministic alignment-gating prototype that evaluates actions based on intent/context/value consistency across actors.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/truth-resolver-prototype

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/specs/2026-06-06-truth-resolver-prototype-design.md`:
- Around line 29-34: The fenced code block showing the pipeline
(Distiller.distill, overlap, score_value, resolve) lacks a language identifier;
update the opening fence to include a language such as "python" (i.e. change ```
to ```python) so tooling and syntax highlighting work correctly while leaving
the block content unchanged.

In `@scripts/truth_resolver.py`:
- Line 18: The DEFAULT_WEIGHTS dict is built with a comprehension
"DEFAULT_WEIGHTS = {d: 1.0 for d in VALUE_DIMENSIONS}"; replace it with the
simpler equivalent using dict.fromkeys by assigning DEFAULT_WEIGHTS =
dict.fromkeys(VALUE_DIMENSIONS, 1.0) to keep identical behavior while making
initialization clearer; update any nearby comments if necessary to reflect the
refactor (refer to DEFAULT_WEIGHTS and VALUE_DIMENSIONS).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 04721df6-4921-4949-b14b-71aa04eb5e0c

📥 Commits

Reviewing files that changed from the base of the PR and between 5be6121 and f38d519.

📒 Files selected for processing (6)
  • docs/superpowers/plans/2026-06-06-truth-resolver-prototype.md
  • docs/superpowers/specs/2026-06-06-truth-resolver-prototype-design.md
  • scripts/truth_resolver.py
  • tests/fixtures/action_fail.json
  • tests/fixtures/action_pass.json
  • tests/test_truth_resolver.py

Comment thread docs/superpowers/specs/2026-06-06-truth-resolver-prototype-design.md Outdated
Comment thread scripts/truth_resolver.py Outdated
- spec: add 'text' language to the pipeline code fence (markdownlint MD040)
- truth_resolver.py: DEFAULT_WEIGHTS via dict.fromkeys (equivalent, clearer)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
scripts/truth_resolver.py (2)

112-112: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

set.intersection crashes with a single actor.

When vectors contains only one element, set.intersection(*[v.value]) raises TypeError: intersection expected at least 1 argument, got 0. The single-actor case is not explicitly ruled out by the design spec, and no validation enforces a minimum of two actors.

🐛 Proposed fix matching the pattern from line 72
-    shared = set.intersection(*[v.value for v in vectors]) if vectors else set()
+    shared = vectors[0].value.intersection(*[v.value for v in vectors[1:]]) if vectors else set()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/truth_resolver.py` at line 112, The current computation of shared
using set.intersection(*[v.value for v in vectors]) fails for a single-element
vectors; change it to handle three cases: if vectors is empty return an empty
set, if len(vectors) == 1 use set(vectors[0].value), otherwise compute
set.intersection(*[v.value for v in vectors]). Update the line that assigns
shared (referencing the variables vectors and v.value) accordingly.

131-131: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Same set.intersection crash risk with a single actor.

If vectors has one element and a dimension score falls below threshold (edge case), set.intersection(*sets) will crash. Although the normal flow would have single-actor dimension scores at 1.0 (and thus skip this branch), the fragility remains.

🐛 Proposed fix matching the safe pattern
-        shared = set.intersection(*sets) if sets else set()
+        shared = sets[0].intersection(*sets[1:]) if sets else set()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/truth_resolver.py` at line 131, The intersection call using
set.intersection(*sets) is unsafe when `sets` has exactly one element; update
the logic in scripts/truth_resolver.py (the block that computes `shared` from
`sets` derived from `vectors`) to handle the single-element case explicitly: if
`sets` is empty return set(), if it has one element return that element
directly, otherwise call set.intersection(*sets); adjust the code around the
`shared = set.intersection(*sets) if sets else set()` expression so it uses this
safe branching to avoid the crash.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/truth_resolver.py`:
- Line 112: The current computation of shared using set.intersection(*[v.value
for v in vectors]) fails for a single-element vectors; change it to handle three
cases: if vectors is empty return an empty set, if len(vectors) == 1 use
set(vectors[0].value), otherwise compute set.intersection(*[v.value for v in
vectors]). Update the line that assigns shared (referencing the variables
vectors and v.value) accordingly.
- Line 131: The intersection call using set.intersection(*sets) is unsafe when
`sets` has exactly one element; update the logic in scripts/truth_resolver.py
(the block that computes `shared` from `sets` derived from `vectors`) to handle
the single-element case explicitly: if `sets` is empty return set(), if it has
one element return that element directly, otherwise call
set.intersection(*sets); adjust the code around the `shared =
set.intersection(*sets) if sets else set()` expression so it uses this safe
branching to avoid the crash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d670dc7d-6aad-48ef-8f52-a9a17a8d2115

📥 Commits

Reviewing files that changed from the base of the PR and between f38d519 and 9381534.

📒 Files selected for processing (2)
  • docs/superpowers/specs/2026-06-06-truth-resolver-prototype-design.md
  • scripts/truth_resolver.py

@ZuluYokohama
ZuluYokohama merged commit 65c6d79 into master Jun 6, 2026
1 of 2 checks passed
@ZuluYokohama
ZuluYokohama deleted the feat/truth-resolver-prototype branch June 6, 2026 06:26
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.

2 participants