Skip to content

fix(groups): pre-feature defects N1-N3 - plain-call pricing, schema sentinel, transcript windowing - #636

Merged
ginccc merged 5 commits into
mainfrom
fix/group-pre-feature-defects
Aug 8, 2026
Merged

fix(groups): pre-feature defects N1-N3 - plain-call pricing, schema sentinel, transcript windowing#636
ginccc merged 5 commits into
mainfrom
fix/group-pre-feature-defects

Conversation

@ginccc

@ginccc ginccc commented Aug 7, 2026

Copy link
Copy Markdown
Member

Closes out the three pre-feature defects from planning/group-collaboration-NEXT.md §2 (plus the §4 nested-cost gap flagged as N1's natural fold-in), unblocking the Wave 2/3 queue.

N1 — Price ordinary model calls (11d0812fb, fold-in 89f2b15b4)

AUDIT_COST was written from cascadeCostUsd + toolCostUsd only, so a plain model call — no cascade, no priced tool — contributed $0.00: I1's maxCostPerDiscussion ceiling could never trip for ordinary members, and memberCosts/totalCost were served over REST as if authoritative.

  • LlmConfiguration.Task gains inputPricePer1M/outputPricePer1M — same nullable semantics as the cascade fields (null = unpriced → $0; no behaviour change for anyone not setting prices). Config-driven per Golden Rule 1: no hardcoded provider price table.
  • The pricing arithmetic now lives once in TokenPricing, shared by the cascade path and the new plain-call path (§4.7 unification).
  • Cascade turns keep pricing themselves — key-presence discrimination on cascadeCostUsd prevents double counting; pinned by a test with deliberately absurd task-level prices on a cascade turn.
  • Negative prices fail at deployment (same new-field hard-error rationale as cascade pricing).
  • Fold-in: accumulateNestedGroupCost keyed by agentId, but every GROUP-member turn spawns a fresh child discussion starting at $0, so only the last child's spend survived the re-sum. Attribution is now keyed per child discussion (agentId:childId) — replacement stays idempotent, children sum.

N3 — Schema-version legacy sentinel (65b00b600)

Every pre-F6 document has no schemaVersion key; Jackson leaves the field initialiser (= CURRENT_SCHEMA_VERSION, i.e. 3) standing, so legacy documents loaded claiming schema 3 while being version-1-shaped and prepareForResume's ladder ran zero iterations on exactly the documents it exists for. Test written first (deserialise {} → failed with expected: <1> but was: <3>), then fixed: initialiser is now LEGACY_SCHEMA_VERSION = 1, and the single creation point stamps CURRENT explicitly. ConversationMemorySnapshot got the identical split (correct only by coincidence while its CURRENT == 1). Stale Javadoc in both migration registries corrected. Free only while no released build has written a versioned document — hence before this ships.

N2/I9 — Transcript windowing (b6c0eb4c4)

FULL/ANONYMOUS-scope phases re-fed the whole transcript to every member every turn (~quadratic prompt cost, compounding with every queued item). New contextWindow group config: beyond maxRecentEntries, older entries collapse into a rolling summary — extended incrementally at phase boundaries only via the shared SummarizationService — or a plain [n earlier entries omitted] marker when summarization is off/unconfigured/failing (WARN, never blocks). ANONYMOUS keeps its own summary built from "Anonymous"-labelled input so it can never de-anonymize (deliberate deviation from the plan's single-field wording, recorded in the changelog). Summarizer spend lands on the I1 ledger when priced. The stored transcript is never modified; signing verifies raw entries.

Verification

  • Every fix mutation-checked: reverting each fix fails exactly its intended tests and nothing else.
  • Full ai.labs.eddi.engine.internal suite: 1438 green. LLM-module suites green apart from the known environmental HttpClient/socket failures. Checkstyle clean.
  • Changelog entries ride in the same commits as the work (§2 rule 8).

Summary by CodeRabbit

  • New Features
    • Added configurable transcript windows for group conversations, with recent-entry limits, optional overflow summaries, anonymized summaries, and truncation fallback.
    • Added task-level input and output token pricing for non-cascaded model calls.
  • Bug Fixes
    • Improved migration handling for older conversation and memory records.
    • Fixed nested-group cost tracking so costs from multiple child discussions are combined correctly.
    • Added validation to reject negative pricing values.
  • Documentation
    • Updated configuration, cost accounting, changelog, and group collaboration documentation.

ginccc added 4 commits August 7, 2026 17:44
…utputPricePer1M (N1)

AUDIT_COST summed cascadeCostUsd + toolCostUsd only, so a plain model call
contributed $0 — I1's group cost ceiling could never trip for ordinary
members and REST served $0.00 as authoritative. Task-level prices (null =
unpriced, $0 as before) now price non-cascade calls; the arithmetic lives
once in TokenPricing, shared with the cascade path. Cascade turns keep
pricing themselves — key-presence discrimination prevents double counting.
Negative prices fail at deployment.
…erwriting

accumulateNestedGroupCost keyed memberCosts by the GROUP member's agentId,
but each turn spawns a fresh child discussion starting at totalCost 0 and
the map records by replacement — so only the last child's spend survived.
Key by agentId:childConversationId: replacement stays idempotent per
conversation and multiple children of one member sum.
…t at creation (N3)

A key-less stored document (every pre-F6 document in production) deserialized
claiming CURRENT_SCHEMA_VERSION, so prepareForResume's migration ladder ran
zero iterations on exactly the documents it exists for. The initialiser is now
LEGACY_SCHEMA_VERSION (1) and the single creation point stamps CURRENT —
Jackson runs the no-arg constructor either way, so only the creation stamp can
distinguish absent from current. Same split applied to ConversationMemorySnapshot,
which was correct only by coincidence (CURRENT == floor == 1). Stale Javadoc in
both migration registries corrected.
FULL/ANONYMOUS-scope phases re-fed the whole transcript to every member
every turn (~quadratic prompt cost). contextWindow config bounds the
rendered context: beyond maxRecentEntries the older entries collapse into
a rolling summary — extended incrementally at phase boundaries via the
shared SummarizationService — or a plain truncation marker when
summarization is off, unconfigured, or failing (never blocks). ANONYMOUS
keeps its own summary built from Anonymous-labelled input so it can never
de-anonymize. Summarizer spend is attributed to the discussion's I1 cost
ledger when priced. The stored transcript is never modified.
@ginccc
ginccc requested a review from rolandpickl as a code owner August 7, 2026 22:06
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ginccc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 3 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d0650dc9-cf3e-4e67-a2f9-4dacfe9f873f

📥 Commits

Reviewing files that changed from the base of the PR and between b6c0eb4 and 7d47990.

📒 Files selected for processing (12)
  • docs/changelog.md
  • src/main/java/ai/labs/eddi/configs/groups/model/AgentGroupConfiguration.java
  • src/main/java/ai/labs/eddi/configs/groups/model/GroupConversation.java
  • src/main/java/ai/labs/eddi/configs/groups/mongo/AgentGroupStore.java
  • src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/GroupCostLedger.java
  • src/main/java/ai/labs/eddi/modules/llm/impl/LlmTask.java
  • src/test/java/ai/labs/eddi/engine/internal/GroupConversationServiceCostCeilingTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilderWindowingTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/GroupCostLedgerTest.java
  • src/test/java/ai/labs/eddi/modules/llm/impl/LlmTaskAuditLedgerTest.java
📝 Walkthrough

Walkthrough

The PR adds configurable transcript windowing with rolling summaries, corrects legacy schema migration handling, fixes nested-group cost aggregation, and adds task-level token pricing with validation and cascade precedence.

Changes

Group conversation context

Layer / File(s) Summary
Transcript windowing and summarization
src/main/java/ai/labs/eddi/configs/groups/model/AgentGroupConfiguration.java, src/main/java/ai/labs/eddi/engine/internal/groups/*, src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java, src/main/java/ai/labs/eddi/engine/internal/groups/PhaseExecutionEngine.java, src/test/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilderWindowingTest.java, docs/group-conversations.md
Group context supports recent-entry limits, rolling full and anonymous summaries, truncation fallback, summarization failure handling, and summarizer cost accounting.
Legacy schema migration handling
src/main/java/ai/labs/eddi/configs/groups/model/GroupConversation.java, src/main/java/ai/labs/eddi/engine/memory/model/ConversationMemorySnapshot.java, src/main/java/ai/labs/eddi/engine/memory/ConversationMemoryUtilities.java, src/main/java/ai/labs/eddi/engine/internal/*SchemaMigrations.java, src/test/java/ai/labs/eddi/engine/**/*SchemaMigrationsTest.java, docs/changelog.md
Schema-less group conversations and memory snapshots use version 1 during migration. Newly created records receive the current schema version.
Cost attribution and ledger aggregation
src/main/java/ai/labs/eddi/engine/internal/groups/GroupCostLedger.java, src/test/java/ai/labs/eddi/engine/internal/groups/GroupCostLedgerTest.java, src/test/java/ai/labs/eddi/engine/internal/groups/MemberTurnExecutorTest.java, planning/group-collaboration-NEXT.md, docs/changelog.md
Nested child-discussion costs use per-child keys and accumulate without overwriting. System costs use idempotent ledger recording.
Task-level token pricing
src/main/java/ai/labs/eddi/modules/llm/model/LlmConfiguration.java, src/main/java/ai/labs/eddi/modules/llm/impl/TokenPricing.java, src/main/java/ai/labs/eddi/modules/llm/impl/CascadeConfigValidator.java, src/main/java/ai/labs/eddi/modules/llm/impl/LlmTask.java, src/main/java/ai/labs/eddi/modules/llm/impl/CascadingModelExecutor.java, src/test/java/ai/labs/eddi/modules/llm/impl/*Test.java, docs/langchain.md, docs/changelog.md
Tasks define input and output prices per million tokens. Non-cascade calls use task prices, while cascade pricing remains authoritative. Negative prices fail validation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GroupConversationService
  participant GroupContextBuilder
  participant SummarizationService
  participant GroupCostLedger
  GroupConversationService->>GroupContextBuilder: updateWindowSummary
  GroupContextBuilder->>SummarizationService: summarize uncovered transcript
  SummarizationService-->>GroupContextBuilder: return summary and token usage
  GroupContextBuilder->>GroupCostLedger: recordSystemCost
  GroupContextBuilder-->>GroupConversationService: return windowed context
Loading

Possibly related PRs

  • labsai/EDDI#606: Overlaps in LlmTask, cascade execution, task configuration, and cost-accounting paths.
  • labsai/EDDI#626: Overlaps in group conversation, context-building, phase execution, and LLM task behavior.
  • labsai/EDDI#587: Overlaps in cascade configuration validation and LLM pricing handling.

Suggested reviewers: rolandpickl

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.90% 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 title clearly summarizes the main fixes: ordinary-call pricing, schema version handling, and transcript windowing.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/group-pre-feature-defects

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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
`@src/main/java/ai/labs/eddi/configs/groups/model/AgentGroupConfiguration.java`:
- Around line 156-163: Update the ContextWindowConfig constructor to normalize
blank or whitespace-only summarizer provider and model identifiers to null,
matching AgentGroupStore.warnOnSummarizerlessWindow and
GroupContextBuilder.updateWindowSummary expectations. Preserve nonblank
identifiers and ensure missing values select the documented truncation fallback
instead of invoking SummarizationService.

In `@src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java`:
- Around line 739-744: Move the updateWindowSummary call in the relevant
repeat/phase flow so it runs after the phase has added its transcript entries,
and invoke it after each eligible phase or repeat completes based on FULL or
ANONYMOUS context scope. Ensure a one-repeat OPINION phase can extend the
rolling summary before the following FULL-scope SYNTHESIS phase renders, and add
an integration test covering that overflow sequence.

In `@src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java`:
- Around line 471-474: Update the transcript snapshot in updateWindowSummary to
use the same thread-safe mechanism as transcript appenders: ensure the
transcript collection is a synchronized list and that all
gc.getTranscript().add(...) operations use its monitor, then copy it while
holding that monitor. Do not rely on synchronizing the read alone when writers
bypass the list monitor.

In `@src/main/java/ai/labs/eddi/engine/internal/groups/GroupCostLedger.java`:
- Around line 90-107: Keep GroupConversation.memberCosts keyed exclusively by
member.agentId() so its serialized contract remains member-level. Update
accumulateNestedGroupCost and the associated re-summing state to store per-child
attribution in a separate child-keyed field, then copy the cumulative total for
member.agentId() into memberCosts; ensure multiple null-ID child discussions
accumulate without overwriting.
- Around line 109-120: Update recordSystemCost to reject null keys and
non-finite or negative costs, while allowing zero cost through recordAndReSum so
an existing operation’s spend is replaced and cleared. Preserve the replacement
semantics for valid finite costs and prevent invalid values from reaching
totalCost or ceiling checks.
🪄 Autofix

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e9c88ac-a231-4a6f-8da4-95e0b7e3fce4

📥 Commits

Reviewing files that changed from the base of the PR and between 22852f0 and b6c0eb4.

📒 Files selected for processing (30)
  • docs/changelog.md
  • docs/group-conversations.md
  • docs/langchain.md
  • planning/group-collaboration-NEXT.md
  • src/main/java/ai/labs/eddi/configs/groups/model/AgentGroupConfiguration.java
  • src/main/java/ai/labs/eddi/configs/groups/model/GroupConversation.java
  • src/main/java/ai/labs/eddi/configs/groups/mongo/AgentGroupStore.java
  • src/main/java/ai/labs/eddi/engine/internal/ConversationSchemaMigrations.java
  • src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/GroupConversationSchemaMigrations.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/GroupCostLedger.java
  • src/main/java/ai/labs/eddi/engine/internal/groups/PhaseExecutionEngine.java
  • src/main/java/ai/labs/eddi/engine/memory/ConversationMemoryUtilities.java
  • src/main/java/ai/labs/eddi/engine/memory/model/ConversationMemorySnapshot.java
  • src/main/java/ai/labs/eddi/modules/llm/impl/CascadeConfigValidator.java
  • src/main/java/ai/labs/eddi/modules/llm/impl/CascadingModelExecutor.java
  • src/main/java/ai/labs/eddi/modules/llm/impl/LlmTask.java
  • src/main/java/ai/labs/eddi/modules/llm/impl/TokenPricing.java
  • src/main/java/ai/labs/eddi/modules/llm/model/LlmConfiguration.java
  • src/test/java/ai/labs/eddi/engine/internal/ConversationSchemaMigrationsTest.java
  • src/test/java/ai/labs/eddi/engine/internal/GroupConversationServiceExtendedTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilderWindowingTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/GroupConversationSchemaMigrationsTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/GroupCostLedgerTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/MemberTurnExecutorTest.java
  • src/test/java/ai/labs/eddi/engine/internal/groups/PhaseExecutionEngineTest.java
  • src/test/java/ai/labs/eddi/engine/memory/ConversationMemoryUtilitiesTest.java
  • src/test/java/ai/labs/eddi/modules/llm/impl/CascadeConfigValidatorTest.java
  • src/test/java/ai/labs/eddi/modules/llm/impl/LlmTaskAuditLedgerTest.java

Comment thread src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java Outdated
@ginccc
ginccc requested a balanced review from Copilot August 7, 2026 22:15

Copilot AI 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.

Pull request overview

Fixes group-conversation cost accounting, legacy schema detection, and transcript growth.

Changes:

  • Prices ordinary LLM calls and correctly aggregates nested-group costs.
  • Distinguishes legacy and current persisted schemas.
  • Adds configurable transcript windowing with rolling summaries.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/test/java/ai/labs/eddi/modules/llm/impl/LlmTaskAuditLedgerTest.java Tests plain-call and cascade pricing.
src/test/java/ai/labs/eddi/modules/llm/impl/CascadeConfigValidatorTest.java Tests task-price validation.
src/test/java/ai/labs/eddi/engine/memory/ConversationMemoryUtilitiesTest.java Tests current snapshot stamping.
src/test/java/ai/labs/eddi/engine/internal/groups/PhaseExecutionEngineTest.java Updates context-builder mocking.
src/test/java/ai/labs/eddi/engine/internal/groups/MemberTurnExecutorTest.java Updates nested-cost attribution expectations.
src/test/java/ai/labs/eddi/engine/internal/groups/GroupCostLedgerTest.java Tests multiple child-cost aggregation.
src/test/java/ai/labs/eddi/engine/internal/groups/GroupConversationSchemaMigrationsTest.java Tests versionless document migration.
src/test/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilderWindowingTest.java Covers window rendering and summarization.
src/test/java/ai/labs/eddi/engine/internal/GroupConversationServiceExtendedTest.java Tests new-document schema stamping.
src/test/java/ai/labs/eddi/engine/internal/ConversationSchemaMigrationsTest.java Pins the snapshot legacy sentinel.
src/main/java/ai/labs/eddi/modules/llm/model/LlmConfiguration.java Adds task-level token prices.
src/main/java/ai/labs/eddi/modules/llm/impl/TokenPricing.java Centralizes token-cost arithmetic.
src/main/java/ai/labs/eddi/modules/llm/impl/LlmTask.java Records plain-call token costs.
src/main/java/ai/labs/eddi/modules/llm/impl/CascadingModelExecutor.java Reuses centralized pricing.
src/main/java/ai/labs/eddi/modules/llm/impl/CascadeConfigValidator.java Validates task-level prices.
src/main/java/ai/labs/eddi/engine/memory/model/ConversationMemorySnapshot.java Separates legacy/current versions.
src/main/java/ai/labs/eddi/engine/memory/ConversationMemoryUtilities.java Stamps current snapshot versions.
src/main/java/ai/labs/eddi/engine/internal/groups/PhaseExecutionEngine.java Passes window configuration into rendering.
src/main/java/ai/labs/eddi/engine/internal/groups/GroupCostLedger.java Aggregates child and system costs.
src/main/java/ai/labs/eddi/engine/internal/groups/GroupConversationSchemaMigrations.java Clarifies migration behavior.
src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java Implements transcript summaries and truncation.
src/main/java/ai/labs/eddi/engine/internal/GroupConversationService.java Runs summaries and stamps new conversations.
src/main/java/ai/labs/eddi/engine/internal/ConversationSchemaMigrations.java Documents snapshot migration semantics.
src/main/java/ai/labs/eddi/configs/groups/mongo/AgentGroupStore.java Warns about missing summarizer configuration.
src/main/java/ai/labs/eddi/configs/groups/model/GroupConversation.java Stores schema and rolling-summary state.
src/main/java/ai/labs/eddi/configs/groups/model/AgentGroupConfiguration.java Defines transcript-window configuration.
planning/group-collaboration-NEXT.md Marks prerequisite defects complete.
docs/langchain.md Documents task-level token prices.
docs/group-conversations.md Documents transcript windowing.
docs/changelog.md Records implementation decisions and verification.
Suppressed comments (2)

src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java:497

  • This four-argument overload passes only modelName to ChatModelRegistry; it supplies no apiKey, baseUrl, or other provider parameters. The existing conversation summarizer explicitly uses the five-argument overload because provider/model alone cannot authenticate, and ContextWindowConfig currently has no parameters field. Consequently the documented OpenAI example falls back to truncation whenever a summary is attempted. Add a secure provider-parameters source (supporting vault/global references) and pass those parameters to the five-argument overload.
            var result = summarizationService.summarizeWithUsage(content, WINDOW_SUMMARY_INSTRUCTIONS,
                    window.llmProvider(), window.llmModel());

src/main/java/ai/labs/eddi/engine/internal/groups/GroupContextBuilder.java:500

  • A successful LLM call can return an empty summary with nonzero token usage, but this early return bypasses cost recording. Because the boundary is not advanced, every later phase boundary retries and all those paid attempts remain invisible to maxCostPerDiscussion. Record the attempt's token cost before checking the summary text, and ensure retries at the same boundary accumulate as distinct spend rather than replacing one boundary-keyed value.
            if (result.summary().isBlank()) {
                LOGGER.warnf("Group %s: window summarization returned empty — keeping previous state, will retry next boundary", gc.getId());
                return;

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +475 to +476
int coverThrough = transcript.size() - window.maxRecentEntries();
int alreadyCovered = anonymous ? gc.getAnonymousSummaryUpToIndex() : gc.getSummaryUpToIndex();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 7d47990 — new summaryBoundary walks back from the tail counting entries that pass isSummarizable (one shared predicate with renderForSummarizer, which is the same exclusion set the scope filter applies minus the phase-dependent VOTE/BID check — at a phase boundary every ballot on the transcript belongs to a completed phase, so no phase check is needed). Pinned by boundaryCountsVisibleEntries_notRawOnes: with bookkeeping rows interleaved in the tail, the three newest visible entries stay verbatim.

// per member turn — that per-turn re-feeding is the quadratic
// cost the window exists to stop. A no-op unless the window is
// enabled and the transcript outgrew it since the last extension.
contextBuilder.updateWindowSummary(gc, phase, config.getContextWindow(), summarizationService);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in 7d47990 — the boundary call is now gated with GroupCostLedger.wouldExceedCeiling(gc, protocol), matching the convergence judge and dissent round. The pinning test needed two attempts: the first scenario was vacuous because the per-turn gate fired before any boundary could be reached (the mutation survived); the committed test builds a first phase that completes under the per-turn gate while blowing the ceiling cumulatively, so the second phase's boundary is reached with the ceiling blown and a summarizer call otherwise guaranteed. Removing the guard fails exactly that test.

…boundary (PR #636 findings)

- accumulateCost/recordSystemCost: !(x > 0) + isFinite instead of x <= 0 -
  NaN fails every comparison, slipped through, and silently disabled every
  dollar ceiling (NaN comparisons are all false)
- the I9 boundary summarizer is now ceiling-gated via wouldExceedCeiling,
  like the convergence judge and dissent round (mutation-checked)
- summaryBoundary counts VISIBLE entries back from the tail, not raw ones,
  so bookkeeping rows cannot eat the verbatim window
- blank llmProvider/llmModel normalize to null in the config choke point
- windowed filterByScope copies the live transcript under its monitor
- CodeQL: sanitize gc id + group name in the new WARN sites
- memberCosts Javadoc rewritten to the actual one-key-one-conversation
  invariant (judge/dissent keys predate the nested-child keys)
@ginccc
ginccc merged commit 5b84439 into main Aug 8, 2026
40 checks passed
@ginccc
ginccc deleted the fix/group-pre-feature-defects branch August 8, 2026 09:29
ginccc added a commit that referenced this pull request Aug 8, 2026
…ion, tool provenance

- AGENTS.md phase-8 row said 60+ MCP tools while every other doc now says
  80+ (actual 82)
- the opt-in-by-absence convention over-claimed: only artifactConfig and
  taskListConfig assemble tools; contextWindow/facilitator/humanMemberConfig
  gate behaviour, not tool assembly
- #636 carried the pre-feature defects, not one of the nine items — the
  changelog and planning header now say #637-#645 with #636 named separately
- the MCP table notes which group tools come from the HITL tool set, since
  they are not declared in McpGroupTools
pull Bot pushed a commit to Stars1233/EDDI that referenced this pull request Aug 12, 2026
Brings every user-facing doc in line with what shipped in PRs labsai#636-labsai#645.
Each claim verified against source, not against the plan.

- group-conversations.md: fixed a nonexistent REST endpoint and the stale
  HUMAN_DECIDES note; completed the REST (+21), MCP (+10), PhaseType,
  TaskStatus, ProtocolConfig and DynamicAgentConfig tables; new sections
  for per-phase controls, dissent and the 23 SSE events; documented the
  RETRO ceilings; fixed the orphaned task-cap paragraph, re-parented
  bid-based assignment under TASK_FORCE, unglued 8 headings
- README: 6 -> 7 styles, ten new capability bullets, MCP 60+ -> 80+,
  tests 11,000+ -> 14,000+, OpenAI-compatible docs row
- AGENTS: 7 styles, new 10c/10d roadmap rows, tests -> 14,000+, HITL row
  clarified, opt-in-by-absence convention documented in 4.2
- docs/README: 6.0.0 -> 6.2.0, MCP 48+ -> 80+, HITL + Open WebUI entries
- SUMMARY: hitl.md and open-webui-integration.md were missing entirely
- rag.md: gemini embedding provider and chroma vector store rows
- planning: the group-collaboration queue is empty; PRs recorded
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.

4 participants