Retire the rotation queue's voice; team links pick the nearest open spot in their own leg
The queue's AUTO-ADVANCE post announced a rotation event this morning when a member had built his own leg (the Triple Play). The queue stopped placing anyone when the public link moved to the chain walk; what was left of it was three Telegram messages, a classifier that called any join under a former queue member a "rotation join" and swept the newcomer into the queue, and a preference inside the team-link picker for queue positions over the nearest open one (15 members affected). Verified offline over the full snapshot first: all 889 personal links already target the member or a position inside their own subtree; the walk starts at the member's own children and cannot leave the leg. Now: the three messages are gone (counters still update silently); a join is a rotation join only if the company link could have produced it (the company link always offers the shallowest open position, so a deeper referrer rules it out; 'invite-<id>' submissions are leg joins outright); nothing is auto-added to the queue; and the team link picks the nearest open position in the member's own leg, in tree order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -762,14 +762,26 @@ function memberIdByAccount(address) {
|
||||
function nextOpenPosition(rootId, exclude) {
|
||||
if (!state || !state.snapshotAt) return null;
|
||||
const skip = exclude || new Set();
|
||||
const q = [rootId]; const seen = new Set();
|
||||
const q = [[rootId, 0]]; const seen = new Set();
|
||||
while (q.length) {
|
||||
const id = q.shift(); if (seen.has(id)) continue; seen.add(id);
|
||||
const [id, depth] = q.shift(); if (seen.has(id)) continue; seen.add(id);
|
||||
const m = state.members[id]; if (!m) continue;
|
||||
// excluded positions are never offered as the target, but their subtree
|
||||
// is still traversed (founders can reserve a position's open slots)
|
||||
if (!skip.has(id) && (m.directCount || 0) < 2) return { id, directCount: m.directCount || 0, level: levelName(m.level || 1) };
|
||||
if (m.l) q.push(m.l); if (m.r) q.push(m.r);
|
||||
if (!skip.has(id) && (m.directCount || 0) < 2) return { id, depth, directCount: m.directCount || 0, level: levelName(m.level || 1) };
|
||||
if (m.l) q.push([m.l, depth + 1]); if (m.r) q.push([m.r, depth + 1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// How deep a position sits under a root (0 = the root itself); null when it is not under it.
|
||||
function depthFrom(rootId, id) {
|
||||
if (!state || !state.members) return null;
|
||||
const q = [[rootId, 0]]; const seen = new Set();
|
||||
while (q.length) {
|
||||
const [cur, depth] = q.shift(); if (seen.has(cur)) continue; seen.add(cur);
|
||||
if (Number(cur) === Number(id)) return depth;
|
||||
const m = state.members[cur]; if (!m) continue;
|
||||
if (m.l) q.push([m.l, depth + 1]); if (m.r) q.push([m.r, depth + 1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -829,4 +841,4 @@ async function getIncome(id) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { startIndexer, getPayoutsPublic, verifyMember, memberLookup, memberPublic, getIncome, getOwnerUpgradeNeeds, getOrgRouting, getOrgShare, getCoachingScan, getMatrixTree, isInTeam, nextOpenPosition, memberIdByAccount, liveDirects, balanceOf, CONTRACT };
|
||||
module.exports = { startIndexer, getPayoutsPublic, verifyMember, memberLookup, memberPublic, getIncome, getOwnerUpgradeNeeds, getOrgRouting, getOrgShare, getCoachingScan, getMatrixTree, isInTeam, nextOpenPosition, depthFrom, memberIdByAccount, liveDirects, balanceOf, CONTRACT };
|
||||
|
||||
Reference in New Issue
Block a user