Skip to content

docs(ingest): spec for speaker-gate + sentiment-routing + SVO floor (#785) - #786

Merged
github-actions[bot] merged 2 commits into
mainfrom
docs/issue-785-ingest-speaker-gate
May 14, 2026
Merged

docs(ingest): spec for speaker-gate + sentiment-routing + SVO floor (#785)#786
github-actions[bot] merged 2 commits into
mainfrom
docs/issue-785-ingest-speaker-gate

Conversation

@robotrocketscience

@robotrocketscience robotrocketscience commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Spec for #785 — closes the narration-bloat feedback loop in belief ingest with three coordinated subtractive changes:

  • §1 Speaker-attribution gate (transcript_logger.py) — skip role == "assistant" messages for belief creation; edge construction unchanged.
  • §2 Sentiment → feedback_history routing (hook.py ↔ ingest) — single source of truth at the hook; ingest reads a feedback-only mark and skips belief creation.
  • §3 SVO min-length floor + edge-anchor demotion (ingest.py) — MIN_BELIEF_CONTENT_CHARS = 80; sub-floor candidates demote to edge anchor_text or are rejected.

Determinism (#605) preserved. No retrieval-side or scoring-side change. No back-purge of existing rows (deferred to a separate stratum-aware cleanup campaign once these gates land).

Test plan

Tracks #785.

Summary by CodeRabbit

  • Documentation
    • Added a feature specification detailing ingest-side changes to optimize message ingestion: refined handling of archived assistant messages, sentiment-first feedback routing to feedback history, raised minimum content threshold for belief creation, a determinism guarantee, explicit non-decisions, an acceptance checklist, and accompanying unit-test plans.

Review Change Stack

@sourcery-ai sourcery-ai 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.

Sorry @robotrocketscience, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

This PR adds a feature specification document (docs/feature-ingest-speaker-gate.md) that defines three coordinated ingest-side changes: skip belief creation for role == "assistant", route sentiment-matched user prompts to feedback_history only, and enforce MIN_BELIEF_CONTENT_CHARS = 80 for SVO-extracted candidates.

Changes

Ingest speaker-gate specification

Layer / File(s) Summary
Problem definition and feedback loop
docs/feature-ingest-speaker-gate.md
Establishes that agent self-narration (51%), user sentiment text (30%), and sub-floor prose (19%) drive reinforced-belief growth in the α+β ≥ 10 stratum. The spec targets all three sources at the ingest boundary to break the feedback cycle.
Three coordinated ingest-side specifications
docs/feature-ingest-speaker-gate.md
Specifies speaker-attribution gate (skip belief creation for role == "assistant" while keeping edge construction), sentiment-to-feedback_history routing (suppress belief on match while preserving feedback bumping, preferring hook-side sentiment-first), and SVO minimum-length enforcement (MIN_BELIEF_CONTENT_CHARS = 80 with sub-floor demotion to edge anchor_text or complete rejection).
Non-functional requirements and acceptance criteria
docs/feature-ingest-speaker-gate.md
Captures determinism property (same payload → same belief set), lists out-of-scope decisions (no SQL delete, no ambiguity-classifier expansion, no retrieval-top-K changes), and provides unit test acceptance checklist across all three implementation targets.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Suggested labels

docs, attn:review

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the primary change: documentation of three coordinated ingest improvements (speaker-gate, sentiment routing, and SVO floor) addressing the feedback loop issue #785.
Description check ✅ Passed The description includes all key template sections: a focused summary explaining the three coordinated changes and the problem they solve, linked issue reference (#785), a test plan with specific verification steps, and notes about determinism preservation and out-of-scope decisions.
Linked Issues check ✅ Passed The spec comprehensively addresses all three primary objectives from #785: (1) speaker-role gate logic for transcript_logger, (2) sentiment-to-feedback_history routing strategy with recommended implementation option, and (3) MIN_BELIEF_CONTENT_CHARS floor with demotion/rejection semantics and acceptance criteria.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #785: the PR adds only documentation (docs/feature-ingest-speaker-gate.md, 158 LOC) specifying three coordinated ingest changes with no retroactive implementation, no code changes, and no unrelated alterations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/issue-785-ingest-speaker-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the docs label May 14, 2026
@robotrocketscience robotrocketscience added author-mondragon Authored by parallel session mondragon attn:review Needs review (PR open, awaiting reviewer) labels May 14, 2026

@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/feature-ingest-speaker-gate.md`:
- Around line 19-31: The fenced code block that begins with the lines "agent
narrates progress" is missing a language tag which triggers MD040; update the
opening fence from ``` to ```text (or another appropriate language like ```text
or ```none) so the block is explicitly tagged, e.g., change the opening ``` to
```text for the block containing "agent narrates progress" through "agent sees
its own old narration as 'context' and continues the pattern".
- Around line 151-157: Update the acceptance checklist entry that reads "All six
unit tests in §1, §2, §3 pass." to reflect the actual number of tests defined in
the spec (change to "All eight unit tests in §1, §2, §3 pass."), ensuring the
acceptance criteria matches the enumerated tests; no other changes to the
checklist items are needed.
🪄 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: CHILL

Plan: Pro

Run ID: b7d6a726-5012-493b-8343-f52844f191a5

📥 Commits

Reviewing files that changed from the base of the PR and between f004ede and af13734.

📒 Files selected for processing (1)
  • docs/feature-ingest-speaker-gate.md

Comment thread docs/feature-ingest-speaker-gate.md Outdated
Comment thread docs/feature-ingest-speaker-gate.md
@github-actions github-actions Bot added the attn:merge-conflict PR branch needs rebase label May 14, 2026
@github-actions

Copy link
Copy Markdown

This PR is now behind main. Rebase locally so your commit signatures stay intact:

git fetch origin && git checkout 'docs/issue-785-ingest-speaker-gate' && git rebase origin/main
# resolve conflicts if any, then
git push --force-with-lease

Auto-rebase was removed because the bot has no signing key; rebasing as the bot strips author signatures and the required_signatures rule on main then blocks the merge. See #341.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:pascal:2026-05-14T15:19:35Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

LGTM — well-structured spec, ready to merge after a rebase.

Verification:

  • 1 atomic G-signed commit, docs: prefix correct, 158 LOC added under docs/feature-ingest-speaker-gate.md (one new file).
  • Discretion grep on the full diff vs github/main: clean.
  • Prereqs cross-checked against github/main:
  • Empirical claim spot-checked: transcript_logger.py:244 does append role='assistant' rows, so §1's "agent narration dominates the short-reinforced-belief leak" is grounded in current code, not folklore.

Substantive notes:

  • §1 is the right shape — speaker-role is structural, not heuristic; no false positives.
  • §2 picking Option A (sentiment-first, single source of truth at the hook) over Option B (ingest-side mirror) is correct. The mirror would duplicate the classifier and create a divergence risk every time v3.0: sentiment-feedback hook production wire-up (evaluation #193 passed; integration pending) #606's pattern set changes.
  • §3's 80-char floor as a module constant (not a config knob) is the right call for a content-quality boundary — turning it into a config surface invites accidental defeats.
  • "No SQL DELETE on existing rows" + "defer back-purge to stratum-aware cleanup once gates are upstream" is the safe sequencing.

Nit (non-blocking): the implementation PR (separate, per the body) is the load-bearing one. This spec PR establishes the contract reviewers will measure against — once it lands, the implementation PR should reference docs/feature-ingest-speaker-gate.md from its body and include the six named unit tests verbatim. Worth pinning that in the implementation PR's checklist.

Blocker before merge-train fires:

Rebasing + force-pushing on mondragon's behalf, then adding ready-to-merge. (Single-commit branch, one file, no real conflict — cheap operation.)

…785)

Three coordinated additions across transcript_logger.py, ingest.py,
and hook.py that close the narration-bloat feedback loop in belief
ingest. Subtractive on the ingest path; no retrieval/scoring change.

§1 skips assistant-role messages for belief creation. §2 routes
sentiment-matched UPS text to feedback_history only (single source
of truth at the hook). §3 adds MIN_BELIEF_CONTENT_CHARS=80 with
edge-anchor demotion for sub-floor candidates.

Spec only; implementation follows in a separate PR closing #785.
@robotrocketscience
robotrocketscience force-pushed the docs/issue-785-ingest-speaker-gate branch from af13734 to d5c8434 Compare May 14, 2026 15:21
@robotrocketscience robotrocketscience added ready-to-merge Trigger merge-train: FF main to this PR's head and removed attn:merge-conflict PR branch needs rebase labels May 14, 2026
@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:pascal:2026-05-14T15:21:07Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:curie:2026-05-14T15:21:15Z]

@github-actions

Copy link
Copy Markdown

merge-train: blocked

1 review thread(s) are unresolved on these files: docs/feature-ingest-speaker-gate.md. Resolve them on the PR (click 'Resolve conversation' on each) and re-add the label.

The ready-to-merge label has been removed. Address the issue above and re-add the label when you're ready for another attempt.

@github-actions github-actions Bot removed the ready-to-merge Trigger merge-train: FF main to this PR's head label May 14, 2026
@robotrocketscience

Copy link
Copy Markdown
Owner Author

Reviewed and pushed a small follow-up commit (8de2f86) addressing the two unresolved CodeRabbit threads:

  1. MD040 — added text language tag to the fenced block at line 19.
  2. Acceptance test count — line 156 said "All six unit tests" but the spec enumerates 8 tests across §1–§3 (2 + 3 + 3). Changed "six" → "eight".

Both CR threads resolved. Verification:

  • Diff is 2 lines; both edits trivial.
  • Both commits signed G.
  • Discretion grep clean.
  • Spec contract on each of §1/§2/§3 reads coherently against the named files (transcript_logger.py, hook.py, ingest.py) on github/main.

Spec itself: well-structured, three subtractive changes are independent and individually testable, determinism (#605) preserved, prereqs (#606, #290) shipped. Ready for the implementation PR that closes #785.

Re-adding ready-to-merge.

@robotrocketscience robotrocketscience added ready-to-merge Trigger merge-train: FF main to this PR's head and removed attn:review Needs review (PR open, awaiting reviewer) labels May 14, 2026
@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:curie:2026-05-14T15:24:40Z]

@github-actions github-actions Bot removed the ready-to-merge Trigger merge-train: FF main to this PR's head label May 14, 2026
@github-actions
github-actions Bot merged commit 8de2f86 into main May 14, 2026
21 of 22 checks passed
@github-actions

Copy link
Copy Markdown

merge-train: merged 8de2f86main via FF push.

@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: 1

♻️ Duplicate comments (2)
docs/feature-ingest-speaker-gate.md (2)

19-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language tag to fenced code block.

The fenced code block is missing a language identifier, triggering MD040 linting.

📝 Suggested fix
-```
+```text
 agent narrates progress
     ↓
🤖 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 `@docs/feature-ingest-speaker-gate.md` around lines 19 - 31, The fenced code
block in the markdown snippet (the block that starts with ``` and contains the
narrative lines like "agent narrates progress" and arrows) lacks a language tag
which triggers MD040; update the opening fence from ``` to ```text so the block
is explicitly marked as plain text; ensure any other similar fences in
docs/feature-ingest-speaker-gate.md are also tagged the same way to satisfy the
linter.

156-156: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct test count in acceptance criterion.

Line 156 states "All six unit tests" but the specification defines eight tests: 2 in §1 (lines 65-66), 3 in §2 (lines 96-98), and 3 in §3 (lines 130-132).

📝 Suggested fix
-- [ ] All six unit tests in §1, §2, §3 pass.
+- [ ] All eight unit tests in §1, §2, §3 pass.
🤖 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 `@docs/feature-ingest-speaker-gate.md` at line 156, The acceptance criterion
incorrectly states "All six unit tests in §1, §2, §3 pass." — update that
checklist item text to reflect the actual total of eight tests (2 in §1, 3 in
§2, 3 in §3) so it reads something like "All eight unit tests in §1, §2, §3
pass."; locate and edit the checklist line containing "All six unit tests in §1,
§2, §3 pass." in docs/feature-ingest-speaker-gate.md (the checklist item string)
to correct the test count.
🧹 Nitpick comments (1)
docs/feature-ingest-speaker-gate.md (1)

104-117: ⚡ Quick win

Document edge schema prerequisite for anchor_text field.

The contract references attaching sub-floor clauses as anchor_text on edges (line 115), but the specification doesn't note whether the edge schema currently supports this field or if it requires creation.

📋 Suggestion

Consider adding a note to either the §3 header or the "Substrate prereqs" section (line 5) clarifying:

**Schema prerequisite:** Edge records must support an `anchor_text` text field to store demoted sub-floor clauses. If not present, add during implementation.
🤖 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 `@docs/feature-ingest-speaker-gate.md` around lines 104 - 117, Add a short
schema prerequisite noting that edge records must include an anchor_text text
field to hold demoted sub‑floor clauses referenced by MIN_BELIEF_CONTENT_CHARS;
update the §3 header or the "Substrate prereqs" section to state that if the
current edge schema lacks anchor_text it must be added during implementation and
define its type/constraints (e.g., text, nullable, max length) so consumers know
how to store the attached clause.
🤖 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/feature-ingest-speaker-gate.md`:
- Around line 72-88: Add an explicit "Interface contract" subsection that
defines the archived-message marking and how ingest reads it: when the sentiment
classifier in hook.py matches a UserPromptSubmit, hook.py must set
archived_message.retention_class = "feedback_only" (or explicitly name an
alternative field if not reusing retention_class); ingest.py must check
archived_message.retention_class and, if it equals "feedback_only", skip belief
creation but still apply the existing feedback_history bump logic; include the
exact field name and allowed value(s) so hook.py and ingest.py can be
implemented independently.

---

Duplicate comments:
In `@docs/feature-ingest-speaker-gate.md`:
- Around line 19-31: The fenced code block in the markdown snippet (the block
that starts with ``` and contains the narrative lines like "agent narrates
progress" and arrows) lacks a language tag which triggers MD040; update the
opening fence from ``` to ```text so the block is explicitly marked as plain
text; ensure any other similar fences in docs/feature-ingest-speaker-gate.md are
also tagged the same way to satisfy the linter.
- Line 156: The acceptance criterion incorrectly states "All six unit tests in
§1, §2, §3 pass." — update that checklist item text to reflect the actual total
of eight tests (2 in §1, 3 in §2, 3 in §3) so it reads something like "All eight
unit tests in §1, §2, §3 pass."; locate and edit the checklist line containing
"All six unit tests in §1, §2, §3 pass." in docs/feature-ingest-speaker-gate.md
(the checklist item string) to correct the test count.

---

Nitpick comments:
In `@docs/feature-ingest-speaker-gate.md`:
- Around line 104-117: Add a short schema prerequisite noting that edge records
must include an anchor_text text field to hold demoted sub‑floor clauses
referenced by MIN_BELIEF_CONTENT_CHARS; update the §3 header or the "Substrate
prereqs" section to state that if the current edge schema lacks anchor_text it
must be added during implementation and define its type/constraints (e.g., text,
nullable, max length) so consumers know how to store the attached clause.
🪄 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: CHILL

Plan: Pro

Run ID: cb670d62-b10c-4c86-80da-426422148b8f

📥 Commits

Reviewing files that changed from the base of the PR and between af13734 and d5c8434.

📒 Files selected for processing (1)
  • docs/feature-ingest-speaker-gate.md

Comment on lines +72 to +88
### Contract

When a UserPromptSubmit's text matches a sentiment pattern (per the #606 classifier) *and* the same text would otherwise become a belief via the post-compaction ingest path:

- The sentiment match continues to bump `feedback_history` on prior beliefs (existing #606 behavior, unchanged).
- Belief creation is suppressed for that message text.

### Implementation choice — single source of truth

Two structural options were considered:

| Option | Description | Trade-off |
|---|---|---|
| **A. Sentiment-first (recommended)** | Sentiment classifier runs before ingest archives the user message. On match, mark the archived entry as feedback-only. Ingest reads the mark and skips belief creation. | Classifier stays authoritative in one place. |
| B. Ingest-side mirror | Re-run the sentiment classifier inside `ingest.py` on each user-role message and skip belief creation on match. | Simpler wiring, but duplicates the classifier. |

**Adopt Option A.** A single source of truth on sentiment classification keeps classifier-update churn contained to the hook surface.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚖️ Poor tradeoff

Specify the marking mechanism for sentiment-matched text.

The contract states that the hook should "mark the archived entry as feedback-only" and that "Ingest reads the mark," but the specification does not define:

  • Which field or attribute carries this mark in the archived message structure
  • What values distinguish feedback-only from normal belief candidates
  • Whether this reuses the retention_class column from prereq #290 or introduces a new field

For a specification document, the interface contract between hook.py and ingest.py must be explicit enough for independent implementation of both sides.

📋 Recommendation

Add an "Interface contract" subsection to §2 that specifies:

### Interface contract

When the sentiment classifier matches, `hook.py` shall set the archived message field:
- `retention_class = "feedback_only"` (or define alternative field if not using retention_class)

When `ingest.py` processes archived messages, it shall:
- Check the retention_class (or specified field)
- If marked feedback_only, skip belief creation while preserving feedback_history bump logic

Or specify the actual field and values you intend to use.

🤖 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 `@docs/feature-ingest-speaker-gate.md` around lines 72 - 88, Add an explicit
"Interface contract" subsection that defines the archived-message marking and
how ingest reads it: when the sentiment classifier in hook.py matches a
UserPromptSubmit, hook.py must set archived_message.retention_class =
"feedback_only" (or explicitly name an alternative field if not reusing
retention_class); ingest.py must check archived_message.retention_class and, if
it equals "feedback_only", skip belief creation but still apply the existing
feedback_history bump logic; include the exact field name and allowed value(s)
so hook.py and ingest.py can be implemented independently.

@robotrocketscience
robotrocketscience deleted the docs/issue-785-ingest-speaker-gate branch May 20, 2026 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author-mondragon Authored by parallel session mondragon docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ingest): close narration-bloat feedback loop — speaker-gate + sentiment-routing + SVO floor

1 participant