sigrank 0.0.182 → 0.0.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/analytics/cascade.mjs +103 -25
- package/package.json +1 -1
- package/presentation/cli.mjs +7 -7
- package/presentation/tui.mjs +6 -6
- package/resources/class-tiers.md +75 -56
- package/tools/_framing.mjs +11 -10
- package/tools/_schemas.mjs +8 -8
- package/tools/describe-power-user.mjs +13 -14
- package/tools/diagnose-cascade.mjs +1 -1
- package/tools/get-leaderboard.mjs +1 -1
- package/tools/get-operator.mjs +1 -1
- package/tools/rank-paste.mjs +1 -1
- package/tools/self-improve.mjs +1 -1
package/analytics/cascade.mjs
CHANGED
|
@@ -61,7 +61,7 @@ export function cascade({ input, output, cacheCreate, cacheRead }) {
|
|
|
61
61
|
leverage: round(leverage, 1),
|
|
62
62
|
velocity: round(velocity, 3),
|
|
63
63
|
dev10x: round(dev10x, 2),
|
|
64
|
-
class: classify(
|
|
64
|
+
class: classify(total),
|
|
65
65
|
mode: detectMode({ input: i, output: o, cacheCreate: cw, cacheRead: cr }),
|
|
66
66
|
};
|
|
67
67
|
if (warnings.length > 0) result.warnings = warnings;
|
|
@@ -69,43 +69,121 @@ export function cascade({ input, output, cacheCreate, cacheRead }) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* CLASS_TIERS — the
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
72
|
+
* CLASS_TIERS — the 8 base tier names (K.01–K.08) for display: glyph, color,
|
|
73
|
+
* meaning. SINGLE SOURCE OF TRUTH for tier-level display info.
|
|
74
|
+
*
|
|
75
|
+
* The permanent class is an EXPERIENCE ladder keyed on TOTAL TOKENS. Each tier
|
|
76
|
+
* has 3 sub-stages (I/II/III) — 24 stages total. The 24 thresholds live in
|
|
77
|
+
* RS05_CLASS_THRESHOLDS below. classify() returns the full sub-stage string
|
|
78
|
+
* (e.g. "REFINER II"). Use tierOf() to extract the base tier name.
|
|
79
|
+
*
|
|
80
|
+
* TRANSMITTER is NOT on this ladder — it is a temporary peak badge (RS.08).
|
|
81
|
+
* The client does not evaluate the badge (owner is still calibrating it);
|
|
82
|
+
* the server does it on read.
|
|
83
|
+
*
|
|
84
|
+
* Mirrors the server's canon-ids.ts CLASS_TIERS (display) + ruleset.ts
|
|
85
|
+
* RS05_CLASS_THRESHOLDS (thresholds). Order is descending (ARCH+ → IGNITER).
|
|
77
86
|
*/
|
|
78
87
|
export const CLASS_TIERS = [
|
|
79
|
-
"TRANSMITTER",
|
|
80
88
|
"ARCH+",
|
|
81
89
|
"ARCH",
|
|
82
90
|
"POWER",
|
|
83
91
|
"BASE",
|
|
84
92
|
"SEEKER",
|
|
85
93
|
"REFINER",
|
|
94
|
+
"BEARER",
|
|
86
95
|
"IGNITER",
|
|
87
96
|
];
|
|
88
97
|
|
|
89
|
-
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
98
|
+
/**
|
|
99
|
+
* SIGNAL_CLASSES — the full 24 sub-stage names (8 tiers × 3 sub-stages I/II/III).
|
|
100
|
+
* Mirrors the server's SIGNAL_CLASSES set in lib/board/mappers.ts. The API
|
|
101
|
+
* returns class_tier as one of these 24 values. classify() returns one of these
|
|
102
|
+
* (or UNCLASSED). Use this for schema enums and validation.
|
|
103
|
+
*/
|
|
104
|
+
export const SIGNAL_CLASSES = [
|
|
105
|
+
"ARCH+ I", "ARCH+ II", "ARCH+ III",
|
|
106
|
+
"ARCH I", "ARCH II", "ARCH III",
|
|
107
|
+
"POWER I", "POWER II", "POWER III",
|
|
108
|
+
"BASE I", "BASE II", "BASE III",
|
|
109
|
+
"SEEKER I", "SEEKER II", "SEEKER III",
|
|
110
|
+
"REFINER I", "REFINER II", "REFINER III",
|
|
111
|
+
"BEARER I", "BEARER II", "BEARER III",
|
|
112
|
+
"IGNITER I", "IGNITER II", "IGNITER III",
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* RS05_CLASS_THRESHOLDS — 24 total-token breakpoints (8 tiers × 3 sub-stages).
|
|
117
|
+
* Mirrors the server's lib/analytics/ruleset.ts RS05_CLASS_THRESHOLDS exactly.
|
|
118
|
+
* Calibrated from the HCM cut (1,626 operators) using target distribution
|
|
119
|
+
* (Option C): IGNITER 10%, BEARER 12.5%, REFINER 15%, SEEKER 22.5%, BASE 20%,
|
|
120
|
+
* POWER 15%, ARCH 5%, ARCH+ 0% (aspirational). Each tier split into 3
|
|
121
|
+
* equal-population sub-stages. Update this one constant to stay in parity
|
|
122
|
+
* when the owner tweaks server-side.
|
|
123
|
+
*/
|
|
124
|
+
export const RS05_CLASS_THRESHOLDS = [
|
|
125
|
+
{ class: "ARCH+ I", totalMin: 7068201104627 },
|
|
126
|
+
{ class: "ARCH+ II", totalMin: 7068201104627 },
|
|
127
|
+
{ class: "ARCH+ III", totalMin: 7068201104627 },
|
|
128
|
+
{ class: "ARCH I", totalMin: 186207267611 },
|
|
129
|
+
{ class: "ARCH II", totalMin: 98543134083 },
|
|
130
|
+
{ class: "ARCH III", totalMin: 68766193943 },
|
|
131
|
+
{ class: "POWER I", totalMin: 39958782379 },
|
|
132
|
+
{ class: "POWER II", totalMin: 26955905621 },
|
|
133
|
+
{ class: "POWER III", totalMin: 19141226889 },
|
|
134
|
+
{ class: "BASE I", totalMin: 13960345961 },
|
|
135
|
+
{ class: "BASE II", totalMin: 10189224970 },
|
|
136
|
+
{ class: "BASE III", totalMin: 7747041813 },
|
|
137
|
+
{ class: "SEEKER I", totalMin: 5446673659 },
|
|
138
|
+
{ class: "SEEKER II", totalMin: 4014577247 },
|
|
139
|
+
{ class: "SEEKER III", totalMin: 2961798768 },
|
|
140
|
+
{ class: "REFINER I", totalMin: 2358346840 },
|
|
141
|
+
{ class: "REFINER II", totalMin: 1845750357 },
|
|
142
|
+
{ class: "REFINER III", totalMin: 1334876308 },
|
|
143
|
+
{ class: "BEARER I", totalMin: 984078167 },
|
|
144
|
+
{ class: "BEARER II", totalMin: 714619043 },
|
|
145
|
+
{ class: "BEARER III", totalMin: 431702990 },
|
|
146
|
+
{ class: "IGNITER I", totalMin: 216393332 },
|
|
147
|
+
{ class: "IGNITER II", totalMin: 88999166 },
|
|
148
|
+
{ class: "IGNITER III", totalMin: 0 },
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
/** The degenerate-case class returned when totalTokens is null/undefined
|
|
152
|
+
* (all-zero / empty session). Distinct from IGNITER III (which is a real
|
|
153
|
+
* low-experience tier) so callers can tell "no data" from "bottom tier". */
|
|
92
154
|
export const UNCLASSED = "UNCLASSED";
|
|
93
155
|
|
|
94
|
-
/**
|
|
95
|
-
*
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
156
|
+
/** Extract the base tier name from a sub-stage string (e.g. "ARCH+ I" → "ARCH+").
|
|
157
|
+
* Mirrors the server's tierOf() in components/sigrank/types.ts. Returns the
|
|
158
|
+
* input as-is if it's not a sub-stage string (e.g. UNCLASSED). */
|
|
159
|
+
export function tierOf(cls) {
|
|
160
|
+
if (cls === UNCLASSED || cls == null) return cls;
|
|
161
|
+
const parts = String(cls).split(" ");
|
|
162
|
+
if (parts.length >= 2 && ["I", "II", "III"].includes(parts[parts.length - 1])) {
|
|
163
|
+
return parts.slice(0, -1).join(" ");
|
|
164
|
+
}
|
|
165
|
+
return cls;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Extract the sub-stage from a sub-stage string (e.g. "ARCH+ I" → "I").
|
|
169
|
+
* Mirrors the server's stageOf(). Returns null for non-sub-stage strings. */
|
|
170
|
+
export function stageOf(cls) {
|
|
171
|
+
if (cls === UNCLASSED || cls == null) return null;
|
|
172
|
+
const parts = String(cls).split(" ");
|
|
173
|
+
const stage = parts[parts.length - 1];
|
|
174
|
+
return stage === "I" || stage === "II" || stage === "III" ? stage : null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Classify an operator's experience stage from total tokens (input + output +
|
|
178
|
+
* cacheCreate + cacheRead). Descending first-match-wins scan over
|
|
179
|
+
* RS05_CLASS_THRESHOLDS — mirrors the server's assignClass(totalTokens).
|
|
180
|
+
* Returns a full sub-stage string (e.g. "REFINER II") or UNCLASSED. */
|
|
181
|
+
export function classify(totalTokens) {
|
|
182
|
+
if (totalTokens == null || !Number.isFinite(totalTokens)) return UNCLASSED;
|
|
183
|
+
for (const t of RS05_CLASS_THRESHOLDS) {
|
|
184
|
+
if (totalTokens >= t.totalMin) return t.class;
|
|
185
|
+
}
|
|
186
|
+
return "IGNITER III";
|
|
109
187
|
}
|
|
110
188
|
|
|
111
189
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sigrank",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.184",
|
|
4
4
|
"author": "SunrisesIllNeverSee (https://github.com/SunrisesIllNeverSee)",
|
|
5
5
|
"description": "SigRank MCP server — the yield cascade + live leaderboard as MCP tools any agent can call",
|
|
6
6
|
"mcpName": "io.github.SunrisesIllNeverSee/sigrank-mcp",
|
package/presentation/cli.mjs
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* npx sigrank watch --window 7d watch one window only (optional filter)
|
|
16
16
|
*
|
|
17
17
|
* Color palette mirrors the SigRank web dark theme:
|
|
18
|
-
* gold =
|
|
18
|
+
* gold = rank #1 headline
|
|
19
19
|
* cyan = active metrics / your row highlight
|
|
20
20
|
* dim = secondary data, separators
|
|
21
21
|
* red = negative movement / delta
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { callTool, DEFAULT_API_BASE, pullActivePlatforms } from "../tools.mjs";
|
|
26
|
-
import { cascade, classify, CLASS_TIERS, UNCLASSED } from "../cascade.mjs";
|
|
26
|
+
import { cascade, classify, CLASS_TIERS, UNCLASSED, tierOf } from "../cascade.mjs";
|
|
27
27
|
import { ALL_PLATFORMS } from "../adapters.mjs";
|
|
28
28
|
import { ensureIdentity, keystorePath } from "../keystore.mjs";
|
|
29
29
|
import { submitSignedWindow } from "../submit.mjs";
|
|
@@ -90,21 +90,21 @@ const green = (str) => paint(c.green, str);
|
|
|
90
90
|
const red = (str) => paint(c.red, str);
|
|
91
91
|
|
|
92
92
|
// ── Class tier → color ─────────────────────────────────────────────────────
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
93
|
+
// Color is keyed on the BASE TIER (8 entries in CLASS_TIERS). classify() returns
|
|
94
|
+
// a full sub-stage string (e.g. "REFINER II") — tierOf() extracts the base tier
|
|
95
|
+
// for color lookup. TRANSMITTER is not a class. UNCLASSED for no-data.
|
|
96
96
|
const CLASS_COLOR = {
|
|
97
|
-
TRANSMITTER: (s) => paint(c.boldGold, s),
|
|
98
97
|
"ARCH+": (s) => paint(c.boldCyan, s),
|
|
99
98
|
ARCH: (s) => paint(c.cyan, s),
|
|
100
99
|
POWER: (s) => paint(c.boldWhite, s),
|
|
101
100
|
BASE: (s) => paint(c.white, s),
|
|
102
101
|
SEEKER: (s) => paint(c.magenta, s),
|
|
103
102
|
REFINER: (s) => paint(c.blue, s),
|
|
103
|
+
BEARER: (s) => paint(c.dim, s),
|
|
104
104
|
IGNITER: (s) => paint(c.dim, s),
|
|
105
105
|
[UNCLASSED]: (s) => paint(c.dim, s),
|
|
106
106
|
};
|
|
107
|
-
const colorClass = (cls) => (CLASS_COLOR[cls] ?? ((s) => s))(cls);
|
|
107
|
+
const colorClass = (cls) => (CLASS_COLOR[tierOf(cls)] ?? CLASS_COLOR[UNCLASSED] ?? ((s) => s))(cls);
|
|
108
108
|
// Guard: every canonical tier must have a color here.
|
|
109
109
|
for (const t of CLASS_TIERS) {
|
|
110
110
|
if (!CLASS_COLOR[t]) {
|
package/presentation/tui.mjs
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { callTool, DEFAULT_API_BASE, pullActivePlatforms } from "../tools.mjs";
|
|
16
16
|
import { ALL_PLATFORMS } from "../adapters.mjs";
|
|
17
|
-
import { cascade, CLASS_TIERS, UNCLASSED } from "../cascade.mjs";
|
|
17
|
+
import { cascade, CLASS_TIERS, UNCLASSED, tierOf } from "../cascade.mjs";
|
|
18
18
|
import { freshVerifierPillars } from "../tokenpull.mjs";
|
|
19
19
|
import { isSignedIn, isCodeChar } from "../connect.mjs";
|
|
20
20
|
import { loadIdentity, clearIdentity } from "../keystore.mjs";
|
|
@@ -201,21 +201,21 @@ const fmtMov = (n) =>
|
|
|
201
201
|
n == null || n === 0 ? dim("—") : n > 0 ? green(`+${n}`) : red(`${n}`);
|
|
202
202
|
|
|
203
203
|
// ── Class tier colors ────────────────────────────────────────────────────────
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
//
|
|
204
|
+
// Color is keyed on the BASE TIER (8 entries in CLASS_TIERS). classify() returns
|
|
205
|
+
// a full sub-stage string (e.g. "REFINER II") — tierOf() extracts the base tier
|
|
206
|
+
// for color lookup. TRANSMITTER is not a class — it's a temporary peak badge.
|
|
207
207
|
const CLS = {
|
|
208
|
-
TRANSMITTER: (s) => paint(c.boldGold, s),
|
|
209
208
|
"ARCH+": (s) => paint(c.boldCyan, s),
|
|
210
209
|
ARCH: (s) => paint(c.cyan, s),
|
|
211
210
|
POWER: (s) => paint(c.boldWhite, s),
|
|
212
211
|
BASE: (s) => paint(c.white, s),
|
|
213
212
|
SEEKER: (s) => paint(c.magenta, s),
|
|
214
213
|
REFINER: (s) => paint(c.blue, s),
|
|
214
|
+
BEARER: (s) => paint(c.dim, s),
|
|
215
215
|
IGNITER: (s) => paint(c.dim, s),
|
|
216
216
|
[UNCLASSED]: (s) => paint(c.dim, s),
|
|
217
217
|
};
|
|
218
|
-
const colorCls = (cls) => (CLS[cls] ?? ((s) => s))(cls);
|
|
218
|
+
const colorCls = (cls) => (CLS[tierOf(cls)] ?? CLS[UNCLASSED] ?? ((s) => s))(cls);
|
|
219
219
|
|
|
220
220
|
// Guard: every canonical tier must have a color, so a new tier added in
|
|
221
221
|
// analytics/cascade.mjs can't silently render uncolored here.
|
package/resources/class-tiers.md
CHANGED
|
@@ -1,62 +1,81 @@
|
|
|
1
1
|
# SigRank Class Tiers
|
|
2
2
|
|
|
3
|
-
Every operator is classified into one of
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`analytics/cascade.mjs`
|
|
8
|
-
output schemas, and this doc all read from that
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **Profile:**
|
|
54
|
-
|
|
55
|
-
|
|
3
|
+
Every operator is classified into one of **24 experience stages** — 8 tiers ×
|
|
4
|
+
3 sub-stages (I/II/III) — based on their **total tokens** (input + output +
|
|
5
|
+
cacheCreate + cacheRead). The ladder mirrors the server's
|
|
6
|
+
`RS05_CLASS_THRESHOLDS` (`lib/analytics/ruleset.ts` in sigrank-app) — the
|
|
7
|
+
client's `classify()` in `analytics/cascade.mjs` is the canonical local source
|
|
8
|
+
of truth. The TUI, CLI, MCP output schemas, and this doc all read from that
|
|
9
|
+
one list.
|
|
10
|
+
|
|
11
|
+
The class is an **experience** axis — it measures how much volume the operator
|
|
12
|
+
has accumulated. It is separate from the **cascade archetype** (the operator's
|
|
13
|
+
token-flow shape: kinetic loop, archival sponge, volatile ingestor, etc.) and
|
|
14
|
+
from the **TRANSMITTER peak badge** (a temporary state — see below).
|
|
15
|
+
|
|
16
|
+
A 25th value, **UNCLASSED**, is returned when total tokens are null or
|
|
17
|
+
non-finite (empty / all-zero session). It is distinct from IGNITER III so
|
|
18
|
+
callers can tell "no data" from "bottom tier".
|
|
19
|
+
|
|
20
|
+
## The 8 base tiers (K.01–K.08)
|
|
21
|
+
|
|
22
|
+
Each tier has 3 sub-stages (I/II/III) split by total-token thresholds. The
|
|
23
|
+
sub-stage is the granular experience level; the base tier is the display
|
|
24
|
+
grouping (color, glyph, meaning).
|
|
25
|
+
|
|
26
|
+
### ARCH+ (K.01) — total ≥ 7.07T
|
|
27
|
+
- **Sub-stages:** ARCH+ I (≥ 7.07T), ARCH+ II (≥ 7.07T), ARCH+ III (≥ 7.07T)
|
|
28
|
+
- **Profile:** Deepest field experience. Volume that became architecture.
|
|
29
|
+
- **Note:** Aspirational — currently 1 operator in the static board.
|
|
30
|
+
|
|
31
|
+
### ARCH (K.02) — total ≥ 68.8B
|
|
32
|
+
- **Sub-stages:** ARCH I (≥ 186B), ARCH II (≥ 98.5B), ARCH III (≥ 68.8B)
|
|
33
|
+
- **Profile:** System builders. Sustained volume, coherent output.
|
|
34
|
+
|
|
35
|
+
### POWER (K.03) — total ≥ 19.1B
|
|
36
|
+
- **Sub-stages:** POWER I (≥ 40.0B), POWER II (≥ 27.0B), POWER III (≥ 19.1B)
|
|
37
|
+
- **Profile:** Above the center. Volume compounding.
|
|
38
|
+
|
|
39
|
+
### BASE (K.04) — total ≥ 7.7B
|
|
40
|
+
- **Sub-stages:** BASE I (≥ 14.0B), BASE II (≥ 10.2B), BASE III (≥ 7.7B)
|
|
41
|
+
- **Profile:** The center of the field. The average operator's experience.
|
|
42
|
+
|
|
43
|
+
### SEEKER (K.05) — total ≥ 3.0B
|
|
44
|
+
- **Sub-stages:** SEEKER I (≥ 5.4B), SEEKER II (≥ 4.0B), SEEKER III (≥ 3.0B)
|
|
45
|
+
- **Profile:** Approaching the center. Experience accumulating.
|
|
46
|
+
|
|
47
|
+
### REFINER (K.06) — total ≥ 1.3B
|
|
48
|
+
- **Sub-stages:** REFINER I (≥ 2.4B), REFINER II (≥ 1.8B), REFINER III (≥ 1.3B)
|
|
49
|
+
- **Profile:** Practicing with purpose. Early sustained volume.
|
|
50
|
+
|
|
51
|
+
### BEARER (K.07) — total ≥ 432M
|
|
52
|
+
- **Sub-stages:** BEARER I (≥ 984M), BEARER II (≥ 715M), BEARER III (≥ 432M)
|
|
53
|
+
- **Profile:** Quiet accumulation. The first real volume.
|
|
54
|
+
|
|
55
|
+
### IGNITER (K.08) — total ≥ 0
|
|
56
|
+
- **Sub-stages:** IGNITER I (≥ 216M), IGNITER II (≥ 89.0M), IGNITER III (≥ 0)
|
|
57
|
+
- **Profile:** Dormant potential. The still soul. Waiting.
|
|
56
58
|
|
|
57
59
|
## UNCLASSED (no data)
|
|
58
60
|
- **Profile:** Empty session — all four pillars are zero.
|
|
59
|
-
- **
|
|
60
|
-
|
|
61
|
+
- **Fix:** Run some sessions; the stage will resolve once there is data.
|
|
62
|
+
|
|
63
|
+
## TRANSMITTER (peak badge, not a class)
|
|
64
|
+
|
|
65
|
+
TRANSMITTER is **not** on the experience ladder. It is a temporary peak badge
|
|
66
|
+
(RS.08) that any experience tier can earn during a high-frequency,
|
|
67
|
+
high-resonance window. An operator "transmits" when they hit both:
|
|
68
|
+
|
|
69
|
+
- **High frequency:** token throughput (total tokens in window) ≥ 1B
|
|
70
|
+
- **High resonance:** SIGNA RATE (composite signal quality) ≥ 85
|
|
71
|
+
|
|
72
|
+
The badge is per-window (daily/weekly) and lapses when frequency or resonance
|
|
73
|
+
drops. The server evaluates it via `evaluateTransmitterBadge()` in
|
|
74
|
+
`lib/analytics/transmitter-badge.ts`; the client does not evaluate the badge
|
|
75
|
+
locally (the owner is still calibrating the thresholds). The server is the
|
|
76
|
+
authority.
|
|
77
|
+
|
|
78
|
+
---
|
|
61
79
|
|
|
62
|
-
Tiers are recalculated on every submission. Your
|
|
80
|
+
Tiers are recalculated on every submission. Your stage can change between
|
|
81
|
+
windows (7d, 30d, 90d, all-time) as total tokens accumulate.
|
package/tools/_framing.mjs
CHANGED
|
@@ -15,28 +15,27 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { DEFAULT_API_BASE } from "./_helpers.mjs";
|
|
18
|
-
import { CLASS_TIERS, UNCLASSED } from "../analytics/cascade.mjs";
|
|
18
|
+
import { CLASS_TIERS, UNCLASSED, tierOf } from "../analytics/cascade.mjs";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Map a class tier to a power-user band. The 8
|
|
21
|
+
* Map a class tier to a power-user band. The 8 experience tiers collapse into 5
|
|
22
22
|
* behavioral bands + UNCLASSED so the framing stays short without writing 8
|
|
23
23
|
* bespoke messages. Band order matches CLASS_TIERS cut order (descending).
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
* ARCH+, ARCH → high (power-user archetype)
|
|
25
|
+
* ARCH+, ARCH → high (deep experience, power-user archetype)
|
|
27
26
|
* POWER, BASE → mid (building momentum)
|
|
28
|
-
* SEEKER, REFINER → early (
|
|
29
|
-
* IGNITER
|
|
27
|
+
* SEEKER, REFINER → early (accumulating volume, finding patterns)
|
|
28
|
+
* BEARER, IGNITER → entry (first volume, or dormant)
|
|
30
29
|
* UNCLASSED / unknown → nodata
|
|
31
30
|
*/
|
|
32
31
|
const BAND = {
|
|
33
|
-
TRANSMITTER: "apex",
|
|
34
32
|
"ARCH+": "high",
|
|
35
33
|
ARCH: "high",
|
|
36
34
|
POWER: "mid",
|
|
37
35
|
BASE: "mid",
|
|
38
36
|
SEEKER: "early",
|
|
39
37
|
REFINER: "early",
|
|
38
|
+
BEARER: "entry",
|
|
40
39
|
IGNITER: "entry",
|
|
41
40
|
[UNCLASSED]: "nodata",
|
|
42
41
|
};
|
|
@@ -46,10 +45,12 @@ const BAND = {
|
|
|
46
45
|
* silently relabeling every no-data operator as the bottom legacy tier. */
|
|
47
46
|
export const FALLBACK_CLASS = UNCLASSED;
|
|
48
47
|
|
|
49
|
-
/** Map a class tier
|
|
50
|
-
* branch on band without re-deriving the
|
|
48
|
+
/** Map a class tier (full sub-stage string or base tier) to its power-user
|
|
49
|
+
* band. Exported so tool handlers can branch on band without re-deriving the
|
|
50
|
+
* tier→band mapping. Uses tierOf() to extract the base tier from sub-stage
|
|
51
|
+
* strings (e.g. "REFINER II" → "REFINER" → "early"). */
|
|
51
52
|
export function bandOf(klass) {
|
|
52
|
-
return BAND[klass] ?? "nodata";
|
|
53
|
+
return BAND[tierOf(klass)] ?? "nodata";
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/**
|
package/tools/_schemas.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* tools/_schemas.mjs — MCP tool annotation + input/output schema objects.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { SIGNAL_CLASSES, UNCLASSED } from "../analytics/cascade.mjs";
|
|
6
6
|
|
|
7
7
|
// Smithery quality: output schemas + annotations
|
|
8
8
|
// MCP tool annotations hint to clients about side-effects, read-only status, etc.
|
|
@@ -15,13 +15,13 @@ export const ANNOTATIONS = {
|
|
|
15
15
|
|
|
16
16
|
// The canonical class-tier enum, single-sourced from analytics/cascade.mjs.
|
|
17
17
|
// Every output schema that exposes a `class` field uses this so the enum can
|
|
18
|
-
// never drift between tools
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
export const CLASS_ENUM = [...
|
|
18
|
+
// never drift between tools. SIGNAL_CLASSES is the 24 sub-stage names (8 tiers
|
|
19
|
+
// × 3 sub-stages I/II/III) that classify() emits and the API returns.
|
|
20
|
+
// UNCLASSED is included for the degenerate no-data case. Exported so tool
|
|
21
|
+
// files that declare their own output schema (optimize-efficiency.mjs,
|
|
22
|
+
// describe-power-user.mjs) import the same enum instead of re-inlining a
|
|
23
|
+
// stale tier list.
|
|
24
|
+
export const CLASS_ENUM = [...SIGNAL_CLASSES, UNCLASSED];
|
|
25
25
|
|
|
26
26
|
// Common output schema for cascade results (rank_paste, simulate_change, etc.)
|
|
27
27
|
// Field names match the actual cascade() output in analytics/cascade.mjs:
|
|
@@ -9,7 +9,7 @@ import { DEFAULT_API_BASE } from "./_helpers.mjs";
|
|
|
9
9
|
export const TOOL_DEF = {
|
|
10
10
|
name: "describe_power_user",
|
|
11
11
|
description:
|
|
12
|
-
"Returns an explanatory description of what makes an AI power user, anchored in SigRank's metrics and operator classes. Explains the yield metric, leverage, velocity, and how the 8
|
|
12
|
+
"Returns an explanatory description of what makes an AI power user, anchored in SigRank's metrics and operator classes. Explains the yield metric, leverage, velocity, and how the 8 experience tiers (ARCH+ / ARCH / POWER / BASE / SEEKER / REFINER / BEARER / IGNITER, each with 3 sub-stages I/II/III, plus UNCLASSED for no-data) map to power-user behavior patterns. Use this when users ask 'what is an AI power user?' or 'what makes a good AI user?' or 'describe advanced AI user behavior'. Intent: DESCRIBE_POWER_USER (Informational).",
|
|
13
13
|
annotations: { title: "Describe power user", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.idempotentHint },
|
|
14
14
|
inputSchema: {
|
|
15
15
|
type: "object",
|
|
@@ -57,20 +57,19 @@ export async function handleDescribePowerUser() {
|
|
|
57
57
|
leverage: "Leverage (Cr/I) measures how much you reuse prior work vs starting fresh. High leverage = you're building on cached results, not re-explaining everything.",
|
|
58
58
|
velocity: "Velocity (O/I) measures how much output you get per token spent. High velocity = you're productive, not just active.",
|
|
59
59
|
},
|
|
60
|
-
// The 8
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
// list is retired — the classifier never emitted those names.
|
|
60
|
+
// The 8 base tiers + UNCLASSED, in descending cut order (matches
|
|
61
|
+
// analytics/cascade.mjs CLASS_TIERS). Each tier has 3 sub-stages (I/II/III)
|
|
62
|
+
// — 24 stages total. TRANSMITTER is a peak badge, not a class.
|
|
64
63
|
class_tiers: [
|
|
65
|
-
{ class: "
|
|
66
|
-
{ class: "ARCH
|
|
67
|
-
{ class: "
|
|
68
|
-
{ class: "
|
|
69
|
-
{ class: "
|
|
70
|
-
{ class: "
|
|
71
|
-
{ class: "
|
|
72
|
-
{ class: "IGNITER", meaning: "Entry —
|
|
73
|
-
{ class: UNCLASSED, meaning: "No cascade data yet — run sessions and re-rank to see your tier." },
|
|
64
|
+
{ class: "ARCH+", sub_stages: ["ARCH+ I", "ARCH+ II", "ARCH+ III"], meaning: "Deepest field experience — volume that became architecture. The AI power user archetype." },
|
|
65
|
+
{ class: "ARCH", sub_stages: ["ARCH I", "ARCH II", "ARCH III"], meaning: "System builder — sustained volume, coherent output, heavy cache reuse." },
|
|
66
|
+
{ class: "POWER", sub_stages: ["POWER I", "POWER II", "POWER III"], meaning: "Above the center — volume compounding, building momentum." },
|
|
67
|
+
{ class: "BASE", sub_stages: ["BASE I", "BASE II", "BASE III"], meaning: "The center of the field — the average operator's experience. Building momentum." },
|
|
68
|
+
{ class: "SEEKER", sub_stages: ["SEEKER I", "SEEKER II", "SEEKER III"], meaning: "Approaching the center — experience accumulating, reuse patterns forming." },
|
|
69
|
+
{ class: "REFINER", sub_stages: ["REFINER I", "REFINER II", "REFINER III"], meaning: "Practicing with purpose — early sustained volume, refining context reuse." },
|
|
70
|
+
{ class: "BEARER", sub_stages: ["BEARER I", "BEARER II", "BEARER III"], meaning: "Quiet accumulation — the first real volume. Session continuity starting." },
|
|
71
|
+
{ class: "IGNITER", sub_stages: ["IGNITER I", "IGNITER II", "IGNITER III"], meaning: "Entry — dormant potential. First sessions, minimal accumulated volume." },
|
|
72
|
+
{ class: UNCLASSED, sub_stages: null, meaning: "No cascade data yet — run sessions and re-rank to see your tier." },
|
|
74
73
|
],
|
|
75
74
|
link: "https://signalaf.com/score — check your class tier and yield",
|
|
76
75
|
shareable_url: `${DEFAULT_API_BASE}/score`,
|
|
@@ -55,7 +55,7 @@ export async function handleDiagnoseCascade(args) {
|
|
|
55
55
|
diagnosis.push({
|
|
56
56
|
metric: "cache_leverage",
|
|
57
57
|
severity: "critical",
|
|
58
|
-
finding: `Cache leverage is ${leverage}× — you're reading only ${leverage}× your fresh input from cache.
|
|
58
|
+
finding: `Cache leverage is ${leverage}× — you're reading only ${leverage}× your fresh input from cache. Top-tier operators hit 200×+.`,
|
|
59
59
|
recommendation:
|
|
60
60
|
"Increase context reuse: load prior session context, use longer conversation threads, reference earlier outputs.",
|
|
61
61
|
estimated_yield_impact: `+${Math.round((1 - leverage / 50) * 100)}% Υ potential`,
|
|
@@ -8,7 +8,7 @@ import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
|
|
|
8
8
|
export const TOOL_DEF = {
|
|
9
9
|
name: "get_leaderboard",
|
|
10
10
|
description:
|
|
11
|
-
"Fetches the live public SigRank leaderboard from signalaf.com. Reads all ranked operators sorted by yield (Υ = Cache Reads × Output / Input²) and returns an array of operator summaries. Each entry contains: codename (public display name), yield (Υ, the headline efficiency metric), leverage ratio (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), class tier (one of
|
|
11
|
+
"Fetches the live public SigRank leaderboard from signalaf.com. Reads all ranked operators sorted by yield (Υ = Cache Reads × Output / Input²) and returns an array of operator summaries. Each entry contains: codename (public display name), yield (Υ, the headline efficiency metric), leverage ratio (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), class tier (one of 24 experience stages: 8 tiers × 3 sub-stages, e.g. ARCH+ I, REFINER II, IGNITER III), and rank position (integer, 1-based). Returns an empty array if no operators have submitted yet. Use this to see where operators stand overall, to find specific codenames for get_operator lookups, or to display the current rankings. Do NOT use this to check your own rank if you already know your codename — use get_operator instead for a single-operator profile with per-window breakdowns. After calling this, follow up with get_operator to get detailed metrics for any operator of interest.",
|
|
12
12
|
annotations: { title: "Get leaderboard", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
|
|
13
13
|
inputSchema: {
|
|
14
14
|
type: "object",
|
package/tools/get-operator.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { OPERATOR_OUTPUT, ANNOTATIONS } from "./_schemas.mjs";
|
|
|
7
7
|
export const TOOL_DEF = {
|
|
8
8
|
name: "get_operator",
|
|
9
9
|
description:
|
|
10
|
-
"Fetches one operator's live profile from the SigRank board by their codename. Reads the operator's current submission data from signalaf.com and returns their detailed metrics: yield (Υ), leverage ratio (Cr/I), velocity (O/I), class tier (one of
|
|
10
|
+
"Fetches one operator's live profile from the SigRank board by their codename. Reads the operator's current submission data from signalaf.com and returns their detailed metrics: yield (Υ), leverage ratio (Cr/I), velocity (O/I), class tier (one of 24 experience stages: 8 tiers × 3 sub-stages, e.g. ARCH+ I, REFINER II, IGNITER III), rank position (integer, 1-based), and per-window breakdowns for each time range (7d, 30d, 90d, all-time) with the four canonical pillars (input, output, cacheCreate, cacheRead) per window. Returns an error if the codename is not found on the board. Use this to look up any operator who has submitted to the board — codenames are public and visible on the leaderboard. Do NOT use this to browse all operators — use get_leaderboard for that. After calling this, you can use simulate_change to model what would happen if the operator adjusted their token mix.",
|
|
11
11
|
annotations: { title: "Get operator profile", ...ANNOTATIONS.readOnlyHint, ...ANNOTATIONS.openWorldHint },
|
|
12
12
|
inputSchema: {
|
|
13
13
|
type: "object",
|
package/tools/rank-paste.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { MAX_INPUT, withParseWarnings } from "./_helpers.mjs";
|
|
|
10
10
|
export const TOOL_DEF = {
|
|
11
11
|
name: "rank_paste",
|
|
12
12
|
description:
|
|
13
|
-
'Computes the SigRank yield cascade from a paste of token counts. Parses the input, runs the full cascade math locally (no network calls), and returns: yield (Υ, the headline efficiency metric, Υ = Cache Reads × Output / Input²), snr (signal-to-noise ratio), leverage (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), dev10x (10xDEV score), class (operator
|
|
13
|
+
'Computes the SigRank yield cascade from a paste of token counts. Parses the input, runs the full cascade math locally (no network calls), and returns: yield (Υ, the headline efficiency metric, Υ = Cache Reads × Output / Input²), snr (signal-to-noise ratio), leverage (Cr/I = cache reads divided by input), velocity (O/I = output divided by input), dev10x (10xDEV score), class (operator experience stage — 24 stages = 8 tiers × 3 sub-stages I/II/III, e.g. ARCH+ I, REFINER II, IGNITER III, or UNCLASSED for empty input), mode (detected working mode), and a deterministic prose "card" summarizing the result in plain English. Accepts two input formats: (1) JSON object {"input":N,"output":N,"cacheCreate":N,"cacheRead":N} or (2) four whitespace-separated numbers in order: input output cacheCreate cacheRead. Returns an error if the input is malformed or has negative values. Use this for a quick one-off ranking without submitting to the board. Do NOT use this to submit your score — use submit_paste instead, which both ranks and publishes. Do NOT use this if you want to rank all four time windows at once — use rank_windows for that. After calling this, use submit_paste to publish the result if you want to appear on the leaderboard.',
|
|
14
14
|
annotations: {
|
|
15
15
|
title: "Rank a paste",
|
|
16
16
|
...ANNOTATIONS.readOnlyHint,
|
package/tools/self-improve.mjs
CHANGED
|
@@ -159,7 +159,7 @@ export async function handleSelfImprove(args, ctx) {
|
|
|
159
159
|
diagnosis.push({
|
|
160
160
|
metric: "cache_leverage",
|
|
161
161
|
severity: "critical",
|
|
162
|
-
finding: `Cache leverage is ${leverage}× —
|
|
162
|
+
finding: `Cache leverage is ${leverage}× — top-tier operators hit 200×+.`,
|
|
163
163
|
recommendation:
|
|
164
164
|
"Increase context reuse: load prior session context, use longer threads.",
|
|
165
165
|
});
|