sigrank 0.0.181 → 0.0.183

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.
@@ -3,12 +3,15 @@
3
3
  */
4
4
 
5
5
  import { cascade, parsePillars } from "../analytics/cascade.mjs";
6
- import { ANNOTATIONS } from "./_schemas.mjs";
6
+ import { ANNOTATIONS, CLASS_ENUM } from "./_schemas.mjs";
7
7
  import { MAX_INPUT, withParseWarnings } from "./_helpers.mjs";
8
+ import { LEADERBOARD_METRIC } from "../lib/constants.mjs";
8
9
  import {
9
10
  _improvementSuggestion,
10
11
  _competitiveLayer,
11
12
  _competitiveSummary,
13
+ FALLBACK_CLASS,
14
+ bandOf,
12
15
  } from "./_framing.mjs";
13
16
 
14
17
  export const TOOL_DEF = {
@@ -43,7 +46,7 @@ export const TOOL_DEF = {
43
46
  yield_: { type: "number" },
44
47
  leverage: { type: "number" },
45
48
  velocity: { type: "number" },
46
- class: { type: "string", enum: ["Burner", "Builder", "10xer"] },
49
+ class: { type: "string", enum: CLASS_ENUM },
47
50
  },
48
51
  },
49
52
  suggestions: {
@@ -92,7 +95,7 @@ export async function handleOptimizeEfficiency(args, ctx) {
92
95
  };
93
96
  }
94
97
 
95
- const klass = metrics.class || "Burner";
98
+ const klass = metrics.class || FALLBACK_CLASS;
96
99
  const l = metrics.leverage || 0;
97
100
  const v = metrics.velocity || 0;
98
101
  const y = metrics.yield_ || 0;
@@ -114,7 +117,14 @@ export async function handleOptimizeEfficiency(args, ctx) {
114
117
  power_user_practice: "Power users maximize output per session — they ask AI to generate, transform, and produce, not just explain.",
115
118
  });
116
119
  }
117
- if (l >= 5 && v >= 1 && klass !== "10xer") {
120
+ // Top-band tiers (apex/high) already have leverage + velocity — the
121
+ // "extend session" suggestion is for mid/early/entry operators whose
122
+ // leverage and velocity are both solid but not yet at the top. The legacy
123
+ // `klass !== "10xer"` guard never matched because the classifier emits the
124
+ // 8-tier dev10x names, not "10xer" — so this branch fired for EVERY
125
+ // operator including top-tier ones. Now keyed off the canonical bands.
126
+ const TOP_BANDS = new Set(["apex", "high"]);
127
+ if (l >= 5 && v >= 1 && !TOP_BANDS.has(bandOf(klass))) {
118
128
  suggestions.push({
119
129
  action: "Extend session length to compound cached context further",
120
130
  why: "Your leverage (" + l.toFixed(1) + "×) and velocity (" + v.toFixed(2) + ") are solid. Longer sessions with consistent context will push your yield higher.",
@@ -132,7 +142,7 @@ export async function handleOptimizeEfficiency(args, ctx) {
132
142
  const summary = `Your Υ Yield is ${y.toLocaleString()} (${klass}). ${_improvementSuggestion(klass, metrics)}`;
133
143
 
134
144
  // Competitive layer per SHARED_DESIGN_DECISIONS.md §3/§4/§5
135
- const board = await ctx.fetchJson("/api/v1/leaderboard?metric=yield_");
145
+ const board = await ctx.fetchJson(`/api/v1/leaderboard?metric=${LEADERBOARD_METRIC}`);
136
146
  const competitive = _competitiveLayer(metrics, board);
137
147
  const competitiveSummary = _competitiveSummary(metrics, board);
138
148
 
@@ -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 ratio (Cr/I = cache reads divided by input), Velocity (O/I = output divided by input), 10xDEV score, operator class tier (Burner / Builder / 10xer), 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.',
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,
@@ -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}× — TRANSMITTER-class operators hit 200×+.`,
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
  });
@@ -10,6 +10,7 @@ import {
10
10
  uploadStamp,
11
11
  withParseWarnings,
12
12
  } from "./_helpers.mjs";
13
+ import { TERMS_VERSION, PRIVACY_VERSION, isRankedAck } from "../lib/constants.mjs";
13
14
 
14
15
  export const TOOL_DEF = {
15
16
  name: "submit_paste",
@@ -73,8 +74,14 @@ export async function handleSubmitPaste(args, ctx) {
73
74
  };
74
75
  }
75
76
 
76
- // Submit the RAW paste so the server re-parses + re-scores authoritatively — the
77
- // MCP's local cascade is only a preview; the board stays the single source of truth.
77
+ // Privacy: send ONLY the 4 parsed token numbers (canonical "input output
78
+ // cacheCreate cacheRead" form), never the raw user text. parsePillars above
79
+ // already validated the input — we reconstruct from the parsed pillars so
80
+ // no conversation content or prose can leak to the server. The server's
81
+ // ingestMeta() re-parses these 4 numbers authoritatively (Strategy 3:
82
+ // four bare numbers). This makes every submit path — signed and paste —
83
+ // send only token counts.
84
+ const canonicalPaste = `${pillars.input} ${pillars.output} ${pillars.cacheCreate} ${pillars.cacheRead}`;
78
85
  const stamp = uploadStamp({
79
86
  codename,
80
87
  pillars: c.pillars,
@@ -88,10 +95,10 @@ export async function handleSubmitPaste(args, ctx) {
88
95
  },
89
96
  body: JSON.stringify({
90
97
  codename,
91
- raw_paste: String(args?.text || ""),
98
+ raw_paste: canonicalPaste,
92
99
  consent_acknowledged: true,
93
- terms_version: "2026-07-21",
94
- privacy_version: "2026-07-21",
100
+ terms_version: TERMS_VERSION,
101
+ privacy_version: PRIVACY_VERSION,
95
102
  ...stamp,
96
103
  }),
97
104
  });
@@ -104,11 +111,7 @@ export async function handleSubmitPaste(args, ctx) {
104
111
  detail: `HTTP ${res.status} (non-JSON response)`,
105
112
  };
106
113
  }
107
- const ranked = !!(
108
- res.ok &&
109
- ack.verification_tier === "verified" &&
110
- ack.persisted === true
111
- );
114
+ const ranked = isRankedAck(res, ack);
112
115
  return {
113
116
  ...c,
114
117
  card,
@@ -12,6 +12,7 @@ import {
12
12
  uploadStamp,
13
13
  WINDOW_TYPE,
14
14
  } from "./_helpers.mjs";
15
+ import { TERMS_VERSION, PRIVACY_VERSION, isRankedAck } from "../lib/constants.mjs";
15
16
 
16
17
  export const TOOL_DEF = {
17
18
  name: "tokenpull_submit",
@@ -131,8 +132,8 @@ export async function handleTokenpullSubmit(args, ctx) {
131
132
  window_type: windowType,
132
133
  telemetry: { platform: { primary: "multi" } },
133
134
  consent_acknowledged: true,
134
- terms_version: "2026-07-21",
135
- privacy_version: "2026-07-21",
135
+ terms_version: TERMS_VERSION,
136
+ privacy_version: PRIVACY_VERSION,
136
137
  ...stamp,
137
138
  }),
138
139
  });
@@ -142,7 +143,11 @@ export async function handleTokenpullSubmit(args, ctx) {
142
143
  } catch {
143
144
  ack = { status: "parse_error", httpStatus: res.status };
144
145
  }
145
- const ranked = ack?.ranked ?? ack?.accepted ?? false;
146
+ // Fix 4: was `ack?.ranked ?? ack?.accepted ?? false` — a looser predicate
147
+ // than the single-platform branch below, which would mark a non-persisted
148
+ // 202 as ranked. Now both branches use the shared isRankedAck() so every
149
+ // submit path agrees on what "ranked" means.
150
+ const ranked = isRankedAck(res, ack);
146
151
  out.push({
147
152
  window: wk,
148
153
  pillars: sum,
@@ -198,8 +203,8 @@ export async function handleTokenpullSubmit(args, ctx) {
198
203
  window_type: windowType,
199
204
  telemetry: { platform: { primary: pulled.platform } },
200
205
  consent_acknowledged: true,
201
- terms_version: "2026-07-21",
202
- privacy_version: "2026-07-21",
206
+ terms_version: TERMS_VERSION,
207
+ privacy_version: PRIVACY_VERSION,
203
208
  ...stamp,
204
209
  }),
205
210
  });
@@ -211,11 +216,7 @@ export async function handleTokenpullSubmit(args, ctx) {
211
216
  }
212
217
  // ranked = actually on the board (verified + persisted), not just received — parity
213
218
  // with submit_verified (submit/index.mjs). An unenrolled/revoked device gets 202 but is NEVER ranked.
214
- const ranked = !!(
215
- res.ok &&
216
- ack.verification_tier === "verified" &&
217
- ack.persisted === true
218
- );
219
+ const ranked = isRankedAck(res, ack);
219
220
  out.push({
220
221
  window: w.window,
221
222
  pillars: w.pillars,
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { execFileAsync } from "./_helpers.mjs";
6
6
  import { ANNOTATIONS } from "./_schemas.mjs";
7
+ import { TOKSCALE_CLIENT_MAP } from "../lib/constants.mjs";
7
8
 
8
9
  export const TOOL_DEF = {
9
10
  name: "tokscale_breakdown",
@@ -36,48 +37,7 @@ export const TOOL_DEF = {
36
37
  },
37
38
  };
38
39
 
39
- const TOKSCALE_CLIENT_MAP = {
40
- claude: "claude",
41
- codex: "codex",
42
- "devin-cli": "devin",
43
- "devin-desktop": "devin",
44
- gemini: "gemini",
45
- amp: "amp",
46
- kimi: "kimi",
47
- qwen: "qwen",
48
- goose: "goose",
49
- kilo: "kilo",
50
- kilocode: "kilo",
51
- hermes: "hermes",
52
- droid: "droid",
53
- codebuff: "codebuff",
54
- copilot: "copilot",
55
- opencode: "opencode",
56
- openclaw: "openclaw",
57
- pi: "pi",
58
- cursor: "other",
59
- roocode: "other",
60
- mux: "other",
61
- crush: "other",
62
- antigravity: "other",
63
- "antigravity-cli": "other",
64
- zed: "other",
65
- kiro: "other",
66
- trae: "other",
67
- warp: "other",
68
- cline: "other",
69
- gjc: "other",
70
- grok: "other",
71
- jcode: "other",
72
- commandcode: "other",
73
- micode: "other",
74
- junie: "other",
75
- zcode: "other",
76
- opencodereview: "other",
77
- codebuddy: "other",
78
- workbuddy: "other",
79
- synthetic: null,
80
- };
40
+ // TOKSCALE_CLIENT_MAP is imported from lib/constants.mjs (single source of truth).
81
41
 
82
42
  /**
83
43
  * Run `tokscale models --json` and return a model-level breakdown per platform.