Fix off-by-one in catch-eligibility: catcher must be AT the bought level
The pipeline widget, owner upgrade alerts, and the org routing/leak map all treated a position as eligible to catch a payment at the buyer's PRE-upgrade level (level >= depth). Verified against on-chain history: position 6, at exactly the pre-upgrade level (Ascensus) and qualified, was passed over on position 8's Fabrica buy - so the contract requires the catcher to be at the level being BOUGHT (depth+1), matching the "stay one level ahead" doctrine. - chain.js getOwnerUpgradeNeeds: eligible now pLevel >= depth+1; neededLevel reported as the bought level (was one low, so alerts would have stayed silent in exactly the situation they exist for) - chain.js getOrgRouting catcher(): same correction in the routing simulation - my.js pipeline: needLevel/eligible/summary-text ladder corrected; warnings now name the right level Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -556,7 +556,10 @@ function getOwnerUpgradeNeeds(ids) {
|
||||
(function walk(n, depth) {
|
||||
if (!n) return;
|
||||
if (depth >= 1 && (n.level || 1) === depth) {
|
||||
const eligible = pQual && pLevel >= depth;
|
||||
// catcher must be AT the level being bought (depth+1), not the buyer's
|
||||
// pre-upgrade level — verified on-chain: #6 was passed at exactly the
|
||||
// pre-upgrade level on #8's Fabrica buy (2026-08-14)
|
||||
const eligible = pQual && pLevel >= depth + 1;
|
||||
if (!eligible) items.push({ memberId: n.id, depth, amount: (costs.up[n.tier === 2 ? 2 : 1] || [])[depth - 1] || 0 });
|
||||
}
|
||||
walk(n.left, depth + 1); walk(n.right, depth + 1);
|
||||
@@ -566,7 +569,7 @@ function getOwnerUpgradeNeeds(ids) {
|
||||
const atMin = items.filter(i => i.depth === minDepth);
|
||||
needs.push({
|
||||
id, level: pLevel, levelName: levelName(pLevel), qualified: pQual,
|
||||
neededLevel: minDepth, neededLevelName: levelName(minDepth),
|
||||
neededLevel: minDepth + 1, neededLevelName: levelName(minDepth + 1),
|
||||
members: atMin.map(i => i.memberId),
|
||||
amountAtRisk: +atMin.reduce((s, i) => s + i.amount, 0).toFixed(2),
|
||||
reason: pQual ? 'upgrade' : 'qualify'
|
||||
@@ -592,7 +595,7 @@ function getOrgRouting(rootId, ownerIds) {
|
||||
if (!up || up === CROOT) return null;
|
||||
const u = M[up]; if (!u) return null;
|
||||
if (i < li) { up = u.uplineId; continue; }
|
||||
if ((u.level || 1) > li && (u.directCount || 0) >= 2) return up;
|
||||
if ((u.level || 1) > li + 1 && (u.directCount || 0) >= 2) return up;
|
||||
up = u.uplineId;
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user