Skip to content

fix(licenses): reset transition usage unless carry-over is enabled - #3255

Merged
johnyeocx merged 2 commits into
devfrom
john/license-transition-fixes
Sep 3, 2026
Merged

fix(licenses): reset transition usage unless carry-over is enabled#3255
johnyeocx merged 2 commits into
devfrom
john/license-transition-fixes

Conversation

@johnyeocx

@johnyeocx johnyeocx commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Run smaller license transitions synchronously and preserve explicit carry-over semantics across retained and pooled entitlements.

Co-authored-by: Cursor cursoragent@cursor.com


Stack created with GitHub Stacks CLIGive Feedback 💬


Summary by cubic

Resets license transition usage unless carry-over is enabled, and runs smaller transitions synchronously. Retained (same-definition) entitlements now reset to the incoming grant by default, pooled balances reset to the new grant, and usage carries only when carry_over_usages is enabled, the feature is allocated, or the entitlement has carry_from_previous set.

  • Adds carryOverUsages resolution and propagation through plan compute, batch transition setup, and the transition record.
  • Tracks retained (same-definition) entitlement transitions separately so they only replace when usage resets.
  • Reworks pooled replacement SQL to support both increment (carry) and set (reset) contribution patches.
  • Removes the same-ID replacement restriction and the entity filter so unused seats receive add/replace/delete in batch transitions.
  • Migration item replaces keep carrying usage after the default-reset change.
  • Customers under 1,000 entities get transitions run synchronously in the request instead of queued.

Written for commit 68c7e4c. Summary will update on new commits.

Review in cubic

Greptile Summary

This PR changes license transitions so usage resets unless carry-over is explicitly enabled, while preserving carry-over for allocated features, selected consumables, and migration edits.

  • [Bug fixes] Reset retained and pooled entitlement usage to the incoming grant when carry-over is disabled.
  • [Improvements] Propagate carry-over settings through immediate, scheduled, and batch license transitions.
  • [Improvements] Include active reusable seats when replacing or deleting license entitlements.
  • [Improvements] Run transitions synchronously for customers classified as small.

Confidence Score: 4/5

The PR does not appear safe to merge until synchronous execution is based on the actual transition workload rather than only the number of live entities.

A customer can have fewer than 1,000 live entities but many active unassigned seats; the new threshold then awaits a transition in the billing request even though replacement and deletion SQL process all of those seat entitlement rows.

Files Needing Attention: server/src/internal/billing/v2/execute/executeAutumnActions/executeCustomerLicenseTransitions.ts, server/src/internal/entities/repos/countEntitiesByInternalCustomerId.ts

Important Files Changed

Filename Overview
server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeCustomerEntitlementPatch.ts Adds explicit carry-over resolution and set-versus-increment balance patches for license transitions.
server/src/internal/billing/v2/actions/batchTransition/execute/sql/replaceCustomerEntitlementsBatch.ts Extends replacement SQL to reset retained and pooled entitlement state and to include active reusable seats.
server/src/internal/billing/v2/execute/executeAutumnActions/executeCustomerLicenseTransitions.ts Introduces synchronous execution for customers below the live-entity threshold, while the outstanding workload-estimation defect remains.
server/src/internal/entities/repos/countEntitiesByInternalCustomerId.ts Adds a capped live-entity count, but that count does not represent all seat rows processed by license transitions.
shared/models/billingModels/plan/customerLicensePlan.ts Carries explicit usage carry-over settings on the license transition model.

Reviews (2): Last reviewed commit: "fix(licenses): include unused seats in e..." | Re-trigger Greptile

Context used:

Run smaller license transitions synchronously and preserve explicit carry-over semantics across retained and pooled entitlements.

Co-authored-by: Cursor <cursoragent@cursor.com>
@johnyeocx
johnyeocx requested a review from ay-rod as a code owner September 3, 2026 14:39
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated
checkout Ignored Ignored Sep 3, 2026 3:42pm UTC
landing-page Ignored Ignored Sep 3, 2026 3:42pm UTC

Request Review

Comment on lines +24 to +34
const customerEntityCount = hasTransitions
? await countEntitiesByInternalCustomerId({
db: ctx.db,
internalCustomerId:
customerLicenseTransitions![0].incomingCustomerLicense
.internal_customer_id,
cap: SYNC_BATCH_TRANSITION_MAX_ENTITIES,
})
: 0;
const runSynchronously =
customerEntityCount < SYNC_BATCH_TRANSITION_MAX_ENTITIES;

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.

P1 Entity count understates transition size

If a customer has fewer than 1,000 live entities but thousands of active reusable seat assignments, this check runs the full transition inside the billing request because it counts entities instead of the assignment rows being updated, causing the request to block through many database batches and potentially time out rather than queueing the work.

Knowledge Base Used: Billing lifecycle and payment flows

Prompt To Fix With AI
This is a comment left during a code review.
Path: server/src/internal/billing/v2/execute/executeAutumnActions/executeCustomerLicenseTransitions.ts
Line: 24-34

Comment:
**Entity count understates transition size**

If a customer has fewer than 1,000 live entities but thousands of active reusable seat assignments, this check runs the full transition inside the billing request because it counts entities instead of the assignment rows being updated, causing the request to block through many database batches and potentially time out rather than queueing the work.

**Knowledge Base Used:** [Billing lifecycle and payment flows](https://app.greptile.com/autumn-org-2/-/custom-context/knowledge-base/useautumn/autumn/-/docs/billing-lifecycle.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@cubic-dev-ai cubic-dev-ai 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.

9 issues found across 31 files

Confidence score: 2/5

  • computeEntitlementPriceTransitions.ts, computeBatchMigrationOperations.ts, and batchTransition.ts can drop retained-only or same-definition changes before migration consumers process them, leaving usage unreset or license operations incomplete — propagate retained through transition detection and all migration consumers.
  • computeCustomerEntitlementPatch.ts omits carryOverUsages on changed-definition migration patches, which can reset live balances to the new grant instead of preserving usage — pass through the migration carry-over contract.
  • computeEntitlementPriceOperations.ts has reset edge cases for duplicate retained IDs and pooled equal-grant transitions, potentially leaving stale usage or resetting contribution cycles to the raw grant — include the target ID in retained resets and preserve carried balances when the grant is unchanged.
  • replaceCustomerEntitlementsBatch.ts can leave a stale effective_at marker after a pooled set, while the retained-item test and benchmark fixtures do not reliably validate reset behavior (retained-consumable-item-transition.test.ts, benchReplaceCustomerEntitlementsBatch.ts) — clear the marker and make the tests exercise pre-reset usage with valid pooled-balance data.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeEntitlementPriceOperations.ts">

<violation number="1" location="server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeEntitlementPriceOperations.ts:94">
P2: When a pooled transition carries usage and the incoming grant equals the outgoing grant, `customerEntitlementPatch.balance` is undefined, but this fallback resets both contribution cycles to the raw grant. Preserve the undefined patch instead of overwriting carried pooled contribution state.</violation>

<violation number="2" location="server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeEntitlementPriceOperations.ts:328">
P1: When a license has multiple IDs for the same retained definition, this reset omits rows already using `toEntitlement.id`. Include the target ID in retained reset operations instead of adding it only when no other candidate exists.</violation>
</file>

<file name="server/src/internal/billing/v2/actions/batchTransition/execute/sql/replaceCustomerEntitlementsBatch.ts">

<violation number="1" location="server/src/internal/billing/v2/actions/batchTransition/execute/sql/replaceCustomerEntitlementsBatch.ts:51">
P2: When a pooled `set` transition replaces a contribution with a pending `effective_at`, this branch leaves a stale deferred marker after making current and next amounts equal. Clear `effective_at` in the set assignment so the next promotion does not treat the already-applied transition as pending.</violation>
</file>

<file name="server/tests/integration/licenses/billing/transitions/scheduled-switch/item-transitions/retained-consumable-item-transition.test.ts">

<violation number="1" location="server/tests/integration/licenses/billing/transitions/scheduled-switch/item-transitions/retained-consumable-item-transition.test.ts:1">
P3: The header comment says these are "paid→free seat switches," but both parent plans are paid (fromParentPrice 50, toParentPrice 20) and both seat products carry a $10 price. This is a paid→paid downgrade; the paid→free case is the non-consumable sibling test. Update the comment so it doesn't mislead readers about what the test covers.</violation>

<violation number="2" location="server/tests/integration/licenses/billing/transitions/scheduled-switch/item-transitions/retained-consumable-item-transition.test.ts:130">
P2: The 'resets retained consumable usage at activation' assertion runs after the clock is advanced to `billingPeriod.end`, which is exactly when the monthly Messages entitlement resets anyway. So `usage: 0` would pass even if the transition carried usage into the new grant, making this test unable to verify the reset-by-default behavior it claims to cover. Verify the transition semantics independently of the monthly cycle reset (for example, assert at a mid-cycle activation or against a non-cycle-resetting entitlement) so a regression to carried usage would fail the test.</violation>
</file>

<file name="server/src/internal/billing/v2/actions/batchTransition/compute/transitions/computeEntitlementPriceTransitions.ts">

<violation number="1" location="server/src/internal/billing/v2/actions/batchTransition/compute/transitions/computeEntitlementPriceTransitions.ts:82">
P1: Same-definition survivors now land in `retained` instead of `transitions`, but the migration consumers weren't updated to read it. `computeBatchMigrationOperations.ts` (replaceEntitlements, toLicenseOps) and `checkUpdatePlanTransitionEligibility.ts` only iterate `link.transitions.transitions`/`.added`/`.deleted`, so version-bump and customize paths will silently stop emitting replace ops for unchanged entitlements. Fold `retained` into those consumers (with the carry-over gating) so the migration lane matches the batch-transition lane, or this drops the reset/repoint behavior they relied on.</violation>
</file>

<file name="server/tests/perf/benchReplaceCustomerEntitlementsBatch.ts">

<violation number="1" location="server/tests/perf/benchReplaceCustomerEntitlementsBatch.ts:212">
P3: The pooled noise is incomplete: seedNoise inserts pooled_balance_contributions rows whose `pooled_balance_id` (`noise_pool_*`) is never created, and never seeds any `pooled_balances` rows, so the pooled scenarios measure a pooled_balances table holding a single row. Seed real pool rows and link each noise contribution to a pool and to a noise customer_entitlement's `pooled_contribution_id` so the pooled query's contribution/pool CTEs are exercised against realistic volumes; otherwise drop the misleading contribution noise.</violation>
</file>

<file name="server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeCustomerEntitlementPatch.ts">

<violation number="1" location="server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeCustomerEntitlementPatch.ts:106">
P1: When the migration `groupFilterReplaceRows` path updates a changed entitlement definition, this call resets each live balance to the new grant because it omits `carryOverUsages`. Preserve the migration contract by passing an explicit enabled carry-over config there, or otherwise keep migration callers on delta semantics while applying the reset default only to license transitions.</violation>
</file>

<file name="server/src/internal/billing/v2/actions/batchTransition/batchTransition.ts">

<violation number="1" location="server/src/internal/billing/v2/actions/batchTransition/batchTransition.ts:46">
P1: Retained-only product changes are still discarded before `batchTransition` runs, so their usage is not reset. Include `retained` in the upstream no-op/transition detection as well.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

return;
}

retained.push({ fromEntitlementPrice, toEntitlementPrice });

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.

P1: Same-definition survivors now land in retained instead of transitions, but the migration consumers weren't updated to read it. computeBatchMigrationOperations.ts (replaceEntitlements, toLicenseOps) and checkUpdatePlanTransitionEligibility.ts only iterate link.transitions.transitions/.added/.deleted, so version-bump and customize paths will silently stop emitting replace ops for unchanged entitlements. Fold retained into those consumers (with the carry-over gating) so the migration lane matches the batch-transition lane, or this drops the reset/repoint behavior they relied on.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/compute/transitions/computeEntitlementPriceTransitions.ts, line 82:

<comment>Same-definition survivors now land in `retained` instead of `transitions`, but the migration consumers weren't updated to read it. `computeBatchMigrationOperations.ts` (replaceEntitlements, toLicenseOps) and `checkUpdatePlanTransitionEligibility.ts` only iterate `link.transitions.transitions`/`.added`/`.deleted`, so version-bump and customize paths will silently stop emitting replace ops for unchanged entitlements. Fold `retained` into those consumers (with the carry-over gating) so the migration lane matches the batch-transition lane, or this drops the reset/repoint behavior they relied on.</comment>

<file context>
@@ -73,13 +76,16 @@ export const computeEntitlementPriceTransitions = ({
+			return;
 		}
+
+		retained.push({ fromEntitlementPrice, toEntitlementPrice });
 	});
 
</file context>

const balance = computeBalancePatch({
fromInitialState,
toInitialState,
carryUsage: shouldCarryOverUsage({ toEntitlement, carryOverUsages }),

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.

P1: When the migration groupFilterReplaceRows path updates a changed entitlement definition, this call resets each live balance to the new grant because it omits carryOverUsages. Preserve the migration contract by passing an explicit enabled carry-over config there, or otherwise keep migration callers on delta semantics while applying the reset default only to license transitions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeCustomerEntitlementPatch.ts, line 106:

<comment>When the migration `groupFilterReplaceRows` path updates a changed entitlement definition, this call resets each live balance to the new grant because it omits `carryOverUsages`. Preserve the migration contract by passing an explicit enabled carry-over config there, or otherwise keep migration callers on delta semantics while applying the reset default only to license transitions.</comment>

<file context>
@@ -75,7 +100,11 @@ export const computeCustomerEntitlementPatch = ({
+	const balance = computeBalancePatch({
+		fromInitialState,
+		toInitialState,
+		carryUsage: shouldCarryOverUsage({ toEntitlement, carryOverUsages }),
+	});
 
</file context>


const hasEntitlementPriceTransitions =
entitlementPriceTransitions.transitions.length > 0 ||
entitlementPriceTransitions.retained.length > 0 ||

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.

P1: Retained-only product changes are still discarded before batchTransition runs, so their usage is not reset. Include retained in the upstream no-op/transition detection as well.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/batchTransition.ts, line 46:

<comment>Retained-only product changes are still discarded before `batchTransition` runs, so their usage is not reset. Include `retained` in the upstream no-op/transition detection as well.</comment>

<file context>
@@ -43,6 +43,7 @@ export const batchTransition = async ({
 
 	const hasEntitlementPriceTransitions =
 		entitlementPriceTransitions.transitions.length > 0 ||
+		entitlementPriceTransitions.retained.length > 0 ||
 		entitlementPriceTransitions.added.length > 0 ||
 		entitlementPriceTransitions.deleted.length > 0;
</file context>

continue;
}

const operation = computeReplaceOperation({

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.

P1: When a license has multiple IDs for the same retained definition, this reset omits rows already using toEntitlement.id. Include the target ID in retained reset operations instead of adding it only when no other candidate exists.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeEntitlementPriceOperations.ts, line 328:

<comment>When a license has multiple IDs for the same retained definition, this reset omits rows already using `toEntitlement.id`. Include the target ID in retained reset operations instead of adding it only when no other candidate exists.</comment>

<file context>
@@ -275,10 +295,44 @@ export const computeEntitlementPriceOperations = ({
+			continue;
+		}
+
+		const operation = computeReplaceOperation({
+			candidateOutgoingEntitlements,
+			transition,
</file context>

}

const incrementAmount =
const pooledContributionPatch =

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.

P2: When a pooled transition carries usage and the incoming grant equals the outgoing grant, customerEntitlementPatch.balance is undefined, but this fallback resets both contribution cycles to the raw grant. Preserve the undefined patch instead of overwriting carried pooled contribution state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/compute/operations/entitlementPriceOperations/computeEntitlementPriceOperations.ts, line 94:

<comment>When a pooled transition carries usage and the incoming grant equals the outgoing grant, `customerEntitlementPatch.balance` is undefined, but this fallback resets both contribution cycles to the raw grant. Preserve the undefined patch instead of overwriting carried pooled contribution state.</comment>

<file context>
@@ -82,10 +91,15 @@ const computeReplaceOperation = ({
 	}
 
-	const incrementAmount =
+	const pooledContributionPatch =
 		customerEntitlementPatch.balance?.type === "increment"
-			? customerEntitlementPatch.balance.amount
</file context>

next_cycle_contribution = contribution.next_cycle_contribution + ${patch.amount}`
: sql`
current_contribution = ${patch.amount},
next_cycle_contribution = ${patch.amount}`;

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.

P2: When a pooled set transition replaces a contribution with a pending effective_at, this branch leaves a stale deferred marker after making current and next amounts equal. Clear effective_at in the set assignment so the next promotion does not treat the already-applied transition as pending.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/internal/billing/v2/actions/batchTransition/execute/sql/replaceCustomerEntitlementsBatch.ts, line 51:

<comment>When a pooled `set` transition replaces a contribution with a pending `effective_at`, this branch leaves a stale deferred marker after making current and next amounts equal. Clear `effective_at` in the set assignment so the next promotion does not treat the already-applied transition as pending.</comment>

<file context>
@@ -22,68 +22,107 @@ const assignedSeatFilter = (
+				next_cycle_contribution = contribution.next_cycle_contribution + ${patch.amount}`
+			: sql`
+				current_contribution = ${patch.amount},
+				next_cycle_contribution = ${patch.amount}`;
+	const syntheticBalanceAssignment =
+		patch.type === "increment"
</file context>
Suggested change
next_cycle_contribution = ${patch.amount}`;
next_cycle_contribution = ${patch.amount},
effective_at = NULL`;

scenario.customerId,
scenario.entities[index].id,
);
const usage = 0;

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.

P2: The 'resets retained consumable usage at activation' assertion runs after the clock is advanced to billingPeriod.end, which is exactly when the monthly Messages entitlement resets anyway. So usage: 0 would pass even if the transition carried usage into the new grant, making this test unable to verify the reset-by-default behavior it claims to cover. Verify the transition semantics independently of the monthly cycle reset (for example, assert at a mid-cycle activation or against a non-cycle-resetting entitlement) so a regression to carried usage would fail the test.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tests/integration/licenses/billing/transitions/scheduled-switch/item-transitions/retained-consumable-item-transition.test.ts, line 130:

<comment>The 'resets retained consumable usage at activation' assertion runs after the clock is advanced to `billingPeriod.end`, which is exactly when the monthly Messages entitlement resets anyway. So `usage: 0` would pass even if the transition carried usage into the new grant, making this test unable to verify the reset-by-default behavior it claims to cover. Verify the transition semantics independently of the monthly cycle reset (for example, assert at a mid-cycle activation or against a non-cycle-resetting entitlement) so a regression to carried usage would fail the test.</comment>

<file context>
@@ -0,0 +1,162 @@
+			scenario.customerId,
+			scenario.entities[index].id,
+		);
+		const usage = 0;
+		expectBalanceCorrect({
+			customer: entity,
</file context>

@@ -0,0 +1,162 @@
/** Scheduled paid→free seat switches keep the same messages entitlement.

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.

P3: The header comment says these are "paid→free seat switches," but both parent plans are paid (fromParentPrice 50, toParentPrice 20) and both seat products carry a $10 price. This is a paid→paid downgrade; the paid→free case is the non-consumable sibling test. Update the comment so it doesn't mislead readers about what the test covers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tests/integration/licenses/billing/transitions/scheduled-switch/item-transitions/retained-consumable-item-transition.test.ts, line 1:

<comment>The header comment says these are "paid→free seat switches," but both parent plans are paid (fromParentPrice 50, toParentPrice 20) and both seat products carry a $10 price. This is a paid→paid downgrade; the paid→free case is the non-consumable sibling test. Update the comment so it doesn't mislead readers about what the test covers.</comment>

<file context>
@@ -0,0 +1,162 @@
+/** Scheduled paid→free seat switches keep the same messages entitlement.
+ * Activation resolves carry from the org transition rule only — the original
+ * attach's carry_over_usages is not persisted — so default is a usage reset. */
</file context>
Suggested change
/** Scheduled paidfree seat switches keep the same messages entitlement.
/** Scheduled paidpaid seat downgrades keep the same messages entitlement.

)
SELECT
'noise_contribution_' || i,
'noise_pool_' || i,

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.

P3: The pooled noise is incomplete: seedNoise inserts pooled_balance_contributions rows whose pooled_balance_id (noise_pool_*) is never created, and never seeds any pooled_balances rows, so the pooled scenarios measure a pooled_balances table holding a single row. Seed real pool rows and link each noise contribution to a pool and to a noise customer_entitlement's pooled_contribution_id so the pooled query's contribution/pool CTEs are exercised against realistic volumes; otherwise drop the misleading contribution noise.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/tests/perf/benchReplaceCustomerEntitlementsBatch.ts, line 212:

<comment>The pooled noise is incomplete: seedNoise inserts pooled_balance_contributions rows whose `pooled_balance_id` (`noise_pool_*`) is never created, and never seeds any `pooled_balances` rows, so the pooled scenarios measure a pooled_balances table holding a single row. Seed real pool rows and link each noise contribution to a pool and to a noise customer_entitlement's `pooled_contribution_id` so the pooled query's contribution/pool CTEs are exercised against realistic volumes; otherwise drop the misleading contribution noise.</comment>

<file context>
@@ -0,0 +1,547 @@
+		)
+		SELECT
+			'noise_contribution_' || i,
+			'noise_pool_' || i,
+			'noise_seat_' || i,
+			'noise_ce_' || i,
</file context>

Unused assignment CPs should receive add/replace/delete, and migration
item replaces must keep carrying usage after the default-reset change.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
vercel Bot temporarily deployed to Preview – autumn-vite September 3, 2026 15:42 Inactive
@johnyeocx
johnyeocx merged commit d6a3ff1 into dev Sep 3, 2026
19 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.

1 participant