Skip to content

feat: send previousDomains on full refresh to stabilize domain names#111

Merged
jonathanpopham merged 2 commits intosupermodeltools:mainfrom
jonathanpopham:feat/send-previous-domains
Apr 10, 2026
Merged

feat: send previousDomains on full refresh to stabilize domain names#111
jonathanpopham merged 2 commits intosupermodeltools:mainfrom
jonathanpopham:feat/send-previous-domains

Conversation

@jonathanpopham
Copy link
Copy Markdown
Contributor

@jonathanpopham jonathanpopham commented Apr 10, 2026

Problem

Every supermodel analyze --force produces different domain names because the LLM classifies from scratch. SharedKernel becomes CoreUtilities, DataServices becomes DataModel, etc.

Fix

When Generate runs and a prior shards.json cache exists, extract domain names + subdomain counts and pass them as the previousDomains query param to the API (v0.12.0). The LLM is seeded to reuse those names.

4 files changed, 30 lines added.

Production test on Directus (17,877 nodes)

Run 1 (fresh) Run 2 (seeded)
ArtificialIntelligence
DataModel
CoreServices
ServerInfrastucture → ServerInfrastructure (typo fix)
CliCommands
DirectusApp

83% exact match. The one "change" was the LLM correcting a typo in the domain name it generated on run 1.

Closes #110

Summary by CodeRabbit

  • Improvements
    • Domain analysis now includes cached historical domain information to improve accuracy for incremental re-scans.
    • Analysis requests will include prior domain history when available, improving continuity between runs.
    • Background processing now consistently passes domain-history data through the analysis pipeline without changing user-facing behavior.

When Generate runs with --force and a prior shards.json cache exists,
extract domain names + subdomain counts and pass them as the
previousDomains query param. The API (v0.12.0) seeds the LLM prompt
to reuse those names where the same groupings still apply.

Tested on Directus (17,877 nodes) against production:
- Run 1 (fresh): ArtificialIntelligence, DataModel, CoreServices,
  ServerInfrastucture, CliCommands, DirectusApp
- Run 2 (seeded): 83% name reuse (5/6 identical, 1 typo corrected
  by LLM: ServerInfrastucture → ServerInfrastructure)

Closes supermodeltools#110
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

Walkthrough

This PR adds a previousDomains parameter to shard analysis: the shards handler reads prior cached domains, converts them to PreviousDomain entries, and passes them to Client.AnalyzeShards. The API client now accepts and encodes previousDomains into the analyze endpoint; other callers pass nil.

Changes

Cohort / File(s) Summary
API Layer
internal/api/client.go
Added PreviousDomain type and extended Client.AnalyzeShards(...) to accept previousDomains []PreviousDomain. If provided, marshals and appends previousDomains as a URL-escaped JSON query param to the analyze endpoint before uploading and polling.
Shards Handler (full refresh)
internal/shards/handler.go
When generating shards, reads prior ShardIR from cache, extracts domain names and subdomain counts into a []PreviousDomain, and passes it to AnalyzeShards to seed the analysis.
Other Call Sites
internal/analyze/handler.go, internal/shards/daemon.go
Updated all AnalyzeShards invocations to include the new fourth argument (nil) where no cached domains are available.

Sequence Diagram

sequenceDiagram
    participant Handler as Shards Handler
    participant Cache as Cache Layer
    participant Client as API Client
    participant API as Analysis API
    participant LLM as LLM Analyzer

    Handler->>Cache: Read cached `ShardIR` (cacheFile)
    Cache-->>Handler: Return cached analysis result
    Handler->>Handler: Extract domains → `[]PreviousDomain`
    Handler->>Client: AnalyzeShards(ctx, zipPath, idemKey, prevDomains)
    Client->>Client: Marshal `previousDomains` to JSON
    Client->>Client: Append `previousDomains` query param to endpoint
    Client->>API: POST /analyze?previousDomains=[...]
    API->>LLM: Seed LLM with domain names & counts
    LLM-->>API: Return generated analysis
    API-->>Client: Return analysis result
    Client-->>Handler: Return `ShardIR`
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • greynewell

Poem

🌱 Domains once drifted, names adrift at sea,

now cached whispers guide the LLM's decree.
From ShardIR we pull what we've known before,
so SharedKernel stays steady, not something new to explore. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: sending previousDomains on full refresh to stabilize domain names, which is the core objective of this PR.
Description check ✅ Passed The description provides context (problem/fix), concrete production test results, and references the linked issue, though it doesn't follow the template structure with explicit test plan checkboxes.
Linked Issues check ✅ Passed The PR successfully implements the requirement from #110: extracting domain names and subdomain counts from cache and passing them as previousDomains to the API, with production testing demonstrating 83% exact match rate.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #110 objectives: updating AnalyzeShards signature, adding PreviousDomain type, and modifying callers to pass previous domains from cache.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/api/client.go`:
- Around line 119-123: The struct PreviousDomain has a goimports formatting
issue (likely missing/extra blank line or import grouping) causing CI to fail;
fix by running goimports -w on the file or manually adjust spacing/newlines
around the PreviousDomain declaration so imports and code are properly
formatted, then re-run goimports/gofmt to ensure the file compiles cleanly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d38d8090-4f83-40c3-bcb1-4d201d1c79c2

📥 Commits

Reviewing files that changed from the base of the PR and between af77745 and 15062ad.

📒 Files selected for processing (4)
  • internal/analyze/handler.go
  • internal/api/client.go
  • internal/shards/daemon.go
  • internal/shards/handler.go

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/api/client.go`:
- Line 128: Update the comment that currently reads "If previousDomains is
non-nil, passes them as a query param to seed domain names." to accurately
reflect the actual trigger used in the code: only send previousDomains when the
slice has elements (len(previousDomains) > 0). Locate the comment near the code
that checks previousDomains and sends it as a query parameter (look for the
previousDomains variable and the conditional that builds the query) and change
the wording to mention "non-empty slice" or "len(previousDomains) > 0" so it
matches the implementation.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 953e7abb-803e-4613-80d0-b90f90c3dccc

📥 Commits

Reviewing files that changed from the base of the PR and between 15062ad and bd92a9b.

📒 Files selected for processing (1)
  • internal/api/client.go

// required for sidecar rendering (IDs, labels, properties preserved).
func (c *Client) AnalyzeShards(ctx context.Context, zipPath, idempotencyKey string) (*ShardIR, error) {
job, err := c.pollUntilComplete(ctx, zipPath, idempotencyKey)
// If previousDomains is non-nil, passes them as a query param to seed domain names.
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 | 🟡 Minor

Fix comment mismatch on the trigger condition.

Line 128 says "non-nil", but the code sends previousDomains only when the slice is non-empty (len(previousDomains) > 0). That wording can mislead future readers.

✏️ Suggested doc fix
-// If previousDomains is non-nil, passes them as a query param to seed domain names.
+// If previousDomains is non-empty, passes them as a query param to seed domain names.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If previousDomains is non-nil, passes them as a query param to seed domain names.
// If previousDomains is non-empty, passes them as a query param to seed domain names.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/api/client.go` at line 128, Update the comment that currently reads
"If previousDomains is non-nil, passes them as a query param to seed domain
names." to accurately reflect the actual trigger used in the code: only send
previousDomains when the slice has elements (len(previousDomains) > 0). Locate
the comment near the code that checks previousDomains and sends it as a query
parameter (look for the previousDomains variable and the conditional that builds
the query) and change the wording to mention "non-empty slice" or
"len(previousDomains) > 0" so it matches the implementation.

@jonathanpopham jonathanpopham marked this pull request as ready for review April 10, 2026 21:32
@jonathanpopham jonathanpopham merged commit 9562f84 into supermodeltools:main Apr 10, 2026
7 checks passed
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.

feat: send previousDomains on full refresh to stabilize domain names

1 participant