polymath-society 0.2.5 → 0.2.6

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.
@@ -134,9 +134,8 @@ var require_secure_json_parse = __commonJS({
134
134
  });
135
135
 
136
136
  // ../../scripts/coding-gap.mts
137
- import { promises as fs9 } from "fs";
138
- import os2 from "os";
139
- import path12 from "path";
137
+ import { promises as fs11 } from "fs";
138
+ import path13 from "path";
140
139
 
141
140
  // ../../lib/agents/shared/agent.ts
142
141
  import { readFileSync } from "fs";
@@ -2151,8 +2150,8 @@ function getErrorMap() {
2151
2150
 
2152
2151
  // ../../node_modules/zod/v3/helpers/parseUtil.js
2153
2152
  var makeIssue = (params) => {
2154
- const { data, path: path13, errorMaps, issueData } = params;
2155
- const fullPath = [...path13, ...issueData.path || []];
2153
+ const { data, path: path14, errorMaps, issueData } = params;
2154
+ const fullPath = [...path14, ...issueData.path || []];
2156
2155
  const fullIssue = {
2157
2156
  ...issueData,
2158
2157
  path: fullPath
@@ -2268,11 +2267,11 @@ var errorUtil;
2268
2267
 
2269
2268
  // ../../node_modules/zod/v3/types.js
2270
2269
  var ParseInputLazyPath = class {
2271
- constructor(parent, value, path13, key) {
2270
+ constructor(parent, value, path14, key) {
2272
2271
  this._cachedPath = [];
2273
2272
  this.parent = parent;
2274
2273
  this.data = value;
2275
- this._path = path13;
2274
+ this._path = path14;
2276
2275
  this._key = key;
2277
2276
  }
2278
2277
  get path() {
@@ -15059,39 +15058,39 @@ function createOpenAI(options = {}) {
15059
15058
  });
15060
15059
  const createChatModel = (modelId, settings = {}) => new OpenAIChatLanguageModel(modelId, settings, {
15061
15060
  provider: `${providerName}.chat`,
15062
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15061
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15063
15062
  headers: getHeaders,
15064
15063
  compatibility,
15065
15064
  fetch: options.fetch
15066
15065
  });
15067
15066
  const createCompletionModel = (modelId, settings = {}) => new OpenAICompletionLanguageModel(modelId, settings, {
15068
15067
  provider: `${providerName}.completion`,
15069
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15068
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15070
15069
  headers: getHeaders,
15071
15070
  compatibility,
15072
15071
  fetch: options.fetch
15073
15072
  });
15074
15073
  const createEmbeddingModel = (modelId, settings = {}) => new OpenAIEmbeddingModel(modelId, settings, {
15075
15074
  provider: `${providerName}.embedding`,
15076
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15075
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15077
15076
  headers: getHeaders,
15078
15077
  fetch: options.fetch
15079
15078
  });
15080
15079
  const createImageModel = (modelId, settings = {}) => new OpenAIImageModel(modelId, settings, {
15081
15080
  provider: `${providerName}.image`,
15082
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15081
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15083
15082
  headers: getHeaders,
15084
15083
  fetch: options.fetch
15085
15084
  });
15086
15085
  const createTranscriptionModel = (modelId) => new OpenAITranscriptionModel(modelId, {
15087
15086
  provider: `${providerName}.transcription`,
15088
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15087
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15089
15088
  headers: getHeaders,
15090
15089
  fetch: options.fetch
15091
15090
  });
15092
15091
  const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
15093
15092
  provider: `${providerName}.speech`,
15094
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15093
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15095
15094
  headers: getHeaders,
15096
15095
  fetch: options.fetch
15097
15096
  });
@@ -15112,7 +15111,7 @@ function createOpenAI(options = {}) {
15112
15111
  const createResponsesModel = (modelId) => {
15113
15112
  return new OpenAIResponsesLanguageModel(modelId, {
15114
15113
  provider: `${providerName}.responses`,
15115
- url: ({ path: path13 }) => `${baseURL}${path13}`,
15114
+ url: ({ path: path14 }) => `${baseURL}${path14}`,
15116
15115
  headers: getHeaders,
15117
15116
  fetch: options.fetch
15118
15117
  });
@@ -16271,7 +16270,7 @@ function computeWorkstyle(inp) {
16271
16270
 
16272
16271
  // ../../lib/calibration/index.ts
16273
16272
  var DEFAULT_CALIBRATION = {
16274
- version: "2026-07-12.2",
16273
+ version: "2026-07-14.2",
16275
16274
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
16276
16275
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
16277
16276
  // without this being updated (and re-pushed to the server).
@@ -16360,7 +16359,7 @@ var DEFAULT_CALIBRATION = {
16360
16359
  }
16361
16360
  ],
16362
16361
  codingTiers: {
16363
- push: { median: 300, sigma: 1.121, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail shape from its actions-per-prompt distribution. AVERAGE over substantial days, cumulative not spiky." },
16362
+ push: { median: 300, sigma: 0.91, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail: a 1-in-1,000 user AVERAGES ~5k directed words/day (near-daily heavy dictation, clearly below the ~10k single-day record). AVERAGE over substantial days, cumulative not spiky." },
16364
16363
  focus: { median: 0.08, sigma: 0.559, tag: "estimated \u2014 proxy-anchored", source: "median: Anthropic 20h/week engaged-user figure implies ~1h/day of true rapid exchange against an 8h working day; ceiling anchored to the ~4h/day deep-work limit (45% share = 1-in-1,000). AVERAGE share, cumulative not spiky." },
16365
16364
  orchestration: { tag: "estimated \u2014 behavior bands", source: "no published concurrency distribution exists; ceiling anchored to the Claude Code lead's documented 10-15 parallel sessions" }
16366
16365
  },
@@ -16393,12 +16392,18 @@ var DEFAULT_CALIBRATION = {
16393
16392
  line: "the Claude Code lead runs 10\u201315 sessions at once; his #1 tip is 3\u20135 git worktrees in parallel"
16394
16393
  },
16395
16394
  throughput: {
16396
- // Top-0.1% words/day reference lines, anchored to the throughput ladder
16397
- // (THROUGHPUT_LADDER in throughput.ts): score 10 "world-class sustained" =
16398
- // 9k/day, score 11 "superhuman ceiling" = 12k/day. Calibrated to the person's
16399
- // own anchors, not a wild guess but still a target, not a measured population.
16400
- topAvgWordsPerDay: 9e3,
16401
- topPeakWordsPerDay: 12e3,
16395
+ // Two DIFFERENT kinds of line (2026-07-14.2): topAvg is a PERCENTILE
16396
+ // claim — what a 1-in-1,000 user AVERAGES over substantial days (5k/day:
16397
+ // near-daily heavy dictation; a measured top dictating power user
16398
+ // averages ~3.9k). topPeak is NOT a percentileit is the CEILING
16399
+ // reference, the wildest single days on record (~10k: a 14-16h
16400
+ // launch-day marathon), rendered as "wildest single days", never
16401
+ // "top X% peak". An avg-percentile and a peak-percentile can't both be
16402
+ // shown at a same-ish value (avg≈peak reads broken — user call), and a
16403
+ // peak PERCENTILE line is unknowable anyway; the record framing is
16404
+ // honest and keeps the visual gap.
16405
+ topAvgWordsPerDay: 5e3,
16406
+ topPeakWordsPerDay: 1e4,
16402
16407
  benchLabel: "top 0.1%",
16403
16408
  // No published "words typed/day" for heavy users — the real story is OUTPUT.
16404
16409
  loopsHeadline: ">1,000,000 lines of Rust at 99.8% tests passing",
@@ -16733,7 +16738,7 @@ async function compileCodingProfile() {
16733
16738
  sRow(
16734
16739
  "How hard you push",
16735
16740
  aggregate?.throughput?.score ?? tCeiling,
16736
- `you peak at ~${peakWords.toLocaleString()} words of pure direction in a single day \u2014 the very top sustain ~${BEST.throughput.topAvgWordsPerDay.toLocaleString()} every day, week after week, and crest past ${BEST.throughput.topPeakWordsPerDay.toLocaleString()}`
16741
+ `you peak at ~${peakWords.toLocaleString()} words of pure direction in a single day \u2014 the very top sustain ~${BEST.throughput.topAvgWordsPerDay.toLocaleString()} every day, week after week; the wildest single days on record push ~${BEST.throughput.topPeakWordsPerDay.toLocaleString()}`
16737
16742
  ),
16738
16743
  sRow(
16739
16744
  "How well you use AI",
@@ -16809,6 +16814,10 @@ async function readCodingAsset(name17) {
16809
16814
  );
16810
16815
  }
16811
16816
 
16817
+ // ../../lib/agents/coding/docsDir.ts
16818
+ import { promises as fs9 } from "fs";
16819
+ import path12 from "path";
16820
+
16812
16821
  // ../../lib/agents/coding/materialize.ts
16813
16822
  import { promises as fs8 } from "fs";
16814
16823
  var SYSTEM_REMINDER_RE2 = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
@@ -16945,6 +16954,93 @@ async function materializeSession(file2) {
16945
16954
  return { text: lines.join("\n"), humanTurns, humanChars };
16946
16955
  }
16947
16956
 
16957
+ // ../../lib/agents/coding/docsDir.ts
16958
+ async function writeScoreboard(codingDir, docs) {
16959
+ const gradesDir = path12.join(codingDir, "grades");
16960
+ let files = [];
16961
+ try {
16962
+ files = (await fs9.readdir(gradesDir)).filter((f) => f.endsWith(".json")).sort();
16963
+ } catch {
16964
+ return;
16965
+ }
16966
+ const byCriterion = /* @__PURE__ */ new Map();
16967
+ for (const f of files) {
16968
+ let g;
16969
+ try {
16970
+ g = JSON.parse(await fs9.readFile(path12.join(gradesDir, f), "utf8"));
16971
+ } catch {
16972
+ continue;
16973
+ }
16974
+ for (const c of g.criteria ?? []) {
16975
+ const s = c.score ?? c.bestEstimate;
16976
+ if (s == null) continue;
16977
+ const line = `L${s}${c.score == null ? "~" : ""} \xB7 ${(g.date ?? "").slice(0, 10)} \xB7 ${(g.title ?? g.sessionId ?? "").replace(/\n.*/s, "").slice(0, 60)} \xB7 ${g.sessionId} \u2014 ${(c.instance ?? "").slice(0, 110)}`;
16978
+ (byCriterion.get(c.key) ?? byCriterion.set(c.key, []).get(c.key)).push({ s, line });
16979
+ }
16980
+ }
16981
+ if (!byCriterion.size) return;
16982
+ const blocks = [...byCriterion.entries()].sort(([a], [b]) => a < b ? -1 : 1).map(
16983
+ ([key, rows]) => `## ${key}
16984
+ ${rows.sort((a, b) => b.s - a.s).map((r) => r.line).join("\n")}`
16985
+ );
16986
+ await fs9.writeFile(
16987
+ path12.join(docs, "_scoreboard.md"),
16988
+ `# Scoreboard \u2014 every graded session per criterion, best first.
16989
+ # Lx~ = estimate. Format: level \xB7 date \xB7 title \xB7 sessionId \u2014 graded instance.
16990
+
16991
+ ${blocks.join("\n\n")}
16992
+ `
16993
+ );
16994
+ }
16995
+ async function ensureCodingDocs(codingDir, sessions) {
16996
+ const docs = path12.join(codingDir, "docs");
16997
+ await fs9.mkdir(docs, { recursive: true });
16998
+ const user = sessions.filter((s) => s.sessionId && !s.duplicateOf && (!("klass" in s) || s.klass === "interactive"));
16999
+ let written = 0;
17000
+ for (const s of user) {
17001
+ const out = path12.join(docs, `${s.sessionId}.txt`);
17002
+ try {
17003
+ await fs9.access(out);
17004
+ continue;
17005
+ } catch {
17006
+ }
17007
+ const mat = await materializeSession(s.file).catch(() => null);
17008
+ if (!mat?.text) continue;
17009
+ await fs9.writeFile(out, mat.text);
17010
+ written++;
17011
+ }
17012
+ const rows = user.sort((a, b) => (a.start ?? "") < (b.start ?? "") ? -1 : 1).map((s) => `${(s.start ?? "").slice(0, 10)} \xB7 ${(s.title ?? "").replace(/\n.*/s, "").slice(0, 80)} \xB7 ${s.sessionId}`);
17013
+ await fs9.writeFile(path12.join(docs, "_map.md"), rows.join("\n") + "\n");
17014
+ await writeScoreboard(codingDir, docs);
17015
+ if (written) console.log(`[docs] materialized ${written} new transcript(s) \u2192 ${docs}`);
17016
+ return docs;
17017
+ }
17018
+ function sourceLookupNote() {
17019
+ return `
17020
+
17021
+ SOURCE LOOKUP \u2014 you have Read/Grep/Glob over the working directory, which holds EVERYTHING known about this person's coding work. MAPS FIRST, grep second (the engine rule): docs/_scoreboard.md ranks every graded session per criterion, best first \u2014 one glance shows where the spikes/flair are, so start there when hunting peaks or checking whether a high mark is consistent or a one-off; day-digest.json is the day-by-day story of what they did in order \u2014 read the relevant days to get the arc before searching; docs/_map.md lists every session (date \xB7 title \xB7 sessionId). Then drill down: walkthroughs/<sessionId>.json is that session's phase-by-phase account (cheap, already distilled), grades/<sessionId>.json its graded findings with quotes, and docs/<sessionId>.txt the FULL transcript (">> " = the person, "[AI]" = the model) \u2014 the ground truth, read it when the distilled layers can't settle it. Other artifacts (flow.json, delegation/, expertise/, aggregate.json) are there too if a claim depends on them. The digest you were given is the spine \u2014 use lookups when a CLAIM-MOVING question cannot be settled from it (a moment you are about to headline, a promotion/depth call, an ambiguous engagement, whether detail was vision or boilerplate). VERIFY every verbatim quote you cite by finding it in the transcript first; if you cannot find it, do not use it. Look up what changes the output \u2014 do not re-read the whole corpus.`;
17022
+ }
17023
+
17024
+ // ../../lib/agents/coding/promptCache.ts
17025
+ import { createHash as createHash2 } from "crypto";
17026
+ import { promises as fs10 } from "fs";
17027
+ function promptSha(parts) {
17028
+ const h = createHash2("sha256");
17029
+ for (const p of parts) {
17030
+ h.update(p ?? "");
17031
+ h.update("\0");
17032
+ }
17033
+ return h.digest("hex").slice(0, 16);
17034
+ }
17035
+ async function reusableOutput(outPath, sha, valid, key = "promptSha") {
17036
+ try {
17037
+ const o = JSON.parse(await fs10.readFile(outPath, "utf8"));
17038
+ if (o[key] === sha && valid(o)) return o;
17039
+ } catch {
17040
+ }
17041
+ return null;
17042
+ }
17043
+
16948
17044
  // ../../scripts/coding-gap.mts
16949
17045
  var CODING = CODING_DIR;
16950
17046
  var CONFIG = {
@@ -16958,7 +17054,7 @@ var CLAUDE_AUTO_CAP = /* @__PURE__ */ new Set(["queue-ahead", "deferred-tools",
16958
17054
  var CLAUDE_AUTO_MCP = /^(visualize|Claude[_ ]?Preview|ccd[_ ]?session|ccd[_ ]?session[_ ]?mgmt|mcp[_ ]?registry)$/i;
16959
17055
  async function entrypointOf(file2) {
16960
17056
  try {
16961
- const head = (await fs9.readFile(file2, "utf8")).slice(0, 2e4);
17057
+ const head = (await fs11.readFile(file2, "utf8")).slice(0, 2e4);
16962
17058
  if (/[\/."]\.?conductor/i.test(head)) return "conductor";
16963
17059
  const m = /"entrypoint":"([^"]+)"/.exec(head);
16964
17060
  return m ? m[1] : "unknown";
@@ -16980,14 +17076,14 @@ var MOBILE_WEB = /^claude-(web|mobile|ios|android)$/;
16980
17076
  function sumTool(recs, name17) {
16981
17077
  return recs.reduce((a, s) => a + (s.toolCounts?.[name17] ?? 0), 0);
16982
17078
  }
16983
- var LOCK = path12.join(CODING, ".gap.lock");
17079
+ var LOCK = path13.join(CODING, ".gap.lock");
16984
17080
  var lockHeld = false;
16985
17081
  async function acquireLock() {
16986
17082
  try {
16987
- await fs9.writeFile(LOCK, String(process.pid), { flag: "wx" });
17083
+ await fs11.writeFile(LOCK, String(process.pid), { flag: "wx" });
16988
17084
  lockHeld = true;
16989
17085
  } catch {
16990
- const pid = await fs9.readFile(LOCK, "utf8").catch(() => "?");
17086
+ const pid = await fs11.readFile(LOCK, "utf8").catch(() => "?");
16991
17087
  throw new Error(`another coding-gap run appears active (pid ${pid}, ${LOCK}). Wait for it or delete the lock if it's stale \u2014 concurrent runs overwrite each other's gap.json.`);
16992
17088
  }
16993
17089
  }
@@ -16996,9 +17092,9 @@ async function main() {
16996
17092
  const p = await compileCodingProfile();
16997
17093
  const techniquesAsset = await readCodingAsset("TECHNIQUES.md");
16998
17094
  const techniques = techniquesAsset.text;
16999
- console.log(` rubric: ${techniquesAsset.path} (${(await fs9.stat(techniquesAsset.path)).mtime.toISOString()})`);
17095
+ console.log(` rubric: ${techniquesAsset.path} (${(await fs11.stat(techniquesAsset.path)).mtime.toISOString()})`);
17000
17096
  const writing = (await readCodingAsset("WRITING.md")).text;
17001
- const all = JSON.parse(await fs9.readFile(path12.join(CODING, "sessions.json"), "utf8"));
17097
+ const all = JSON.parse(await fs11.readFile(path13.join(CODING, "sessions.json"), "utf8"));
17002
17098
  const interactive = all.filter((s) => s.klass === "interactive" && s.start);
17003
17099
  const latestMs = Math.max(...interactive.map((s) => Date.parse(s.start)));
17004
17100
  const cutoffMs = latestMs - 14 * 864e5;
@@ -17055,7 +17151,7 @@ async function main() {
17055
17151
  return m ? `--- "${s.title}" \xB7 ${(s.start || "").slice(0, 10)} ---
17056
17152
  ${m.text.slice(0, 3e3)}` : "";
17057
17153
  }))).filter(Boolean);
17058
- const SYS = "You are a Claude Code power-user coach. You judge ONE person against the COMPLETE catalog of best ways to use Claude Code (the rubric below, sourced from Boris Cherny + first-party Claude Code features) and write a comprehensive, honest gap analysis, ORDERED most-difference-making \u2192 least. Rules: (1) Go through the whole catalog and surface the techniques they are NOT doing (or under-using) that would genuinely help \u2014 respecting each tip's [EMPHASIZE]/[DE-EMPHASIZE]/[GATE] curation. (2) ORDER by differenceRank (1 = biggest unlock for THIS person). Follow the rubric's PRIME DIRECTIVE: if usage.parallelism.alreadyParallel is FALSE \u2192 'Do more in parallel' is rank 1; else \u2192 'Invest in your CLAUDE.md / tune your context' is rank 1. Then Plan mode, then 'Give Claude test cases so it can auto-verify and run longer' (Boris's 'most important thing' \u2014 rank it high, right after plan mode), then subagents, and the rest per the rubric order, skipping any that don't apply. (3) GATE the conditional tips on the STRUCTURAL usage facts, NOT on keywords \u2014 and a tip whose gate FAILS is OMITTED from recommendations entirely, never included as a softened/conditional card (recommending something their data says doesn't apply, or that they already do, reads as not having looked): loops require real PR/branch volume in usage.collaboration, else OMIT; the Chrome tip requires ~zero browser-driving in usage.chrome, else OMIT and credit in alreadyStrong; forking uses the RECENT count in usage.forking \u2014 if they fork in the recent window they already do it, OMIT and credit; remote/mobile/EC2 fires only when usage.surface.workstationBound is TRUE; plan mode by usage.planMode; subagents by usage.subagents. If they already do a thing, it goes in alreadyStrong, NOT in recommendations. (4) \u26D4 CRITICAL \u2014 this person BUILDS Claude Code tooling, so their transcripts are full of the words 'worktree', 'pull request', 'fork', 'plan mode', 'by the way', 'teleport'. A keyword in the transcript is NOT evidence they use the feature. Rely on the STRUCTURAL facts only. (5) Ground every recommendation in a RECEIPT \u2014 a structural fact from their usage or a concrete session pain point \u2014 and CONVINCE with a specific case for how it helps THIS person, not a generic benefit. (6) Tailor every action to the Claude Desktop Mac app; NEVER give terminal-only `claude -p` advice. (7) Honor config.deliberateChoices (they stay on `main` on purpose \u2014 do NOT tell them to hand-juggle worktrees; parallel SESSIONS instead) and config.claudeAutoTools (never tell them to 'use' a tool Claude drives itself; for 'explain with visuals' the user just ASKS for a visual \u2014 do not name the tool). (8) Also name what they ALREADY do well. (9) SELF-CONTAINED but not verbose \u2014 lead with the PROBLEM, then the SOLUTION, then HOW to use it in their context. Plain language, no jargon, no enumerating multiple dates. An essay-like rec is a failed rec; so is a cryptic one. Follow this writing rubric strictly:\n\n" + writing;
17154
+ const SYS = "You are a Claude Code power-user coach. You judge ONE person against the COMPLETE catalog of best ways to use Claude Code (the rubric below, sourced from Boris Cherny + first-party Claude Code features) and write a comprehensive, honest gap analysis, ORDERED most-difference-making \u2192 least. Rules: (1) Go through the whole catalog and surface the techniques they are NOT doing (or under-using) that would genuinely help \u2014 respecting each tip's [EMPHASIZE]/[DE-EMPHASIZE]/[GATE] curation. (2) ORDER by differenceRank (1 = biggest unlock for THIS person). Follow the rubric's PRIME DIRECTIVE: if usage.parallelism.alreadyParallel is FALSE \u2192 'Do more in parallel' is rank 1; else \u2192 'Invest in your CLAUDE.md / tune your context' is rank 1. Then Plan mode, then 'Give Claude test cases so it can auto-verify and run longer' (Boris's 'most important thing' \u2014 rank it high, right after plan mode), then subagents, and the rest per the rubric order, skipping any that don't apply. (3) GATE the conditional tips on the STRUCTURAL usage facts, NOT on keywords \u2014 and a tip whose gate FAILS is OMITTED from recommendations entirely, never included as a softened/conditional card (recommending something their data says doesn't apply, or that they already do, reads as not having looked): loops require real PR/branch volume in usage.collaboration, else OMIT; the Chrome tip requires ~zero browser-driving in usage.chrome, else OMIT and credit in alreadyStrong; forking uses the RECENT count in usage.forking \u2014 if they fork in the recent window they already do it, OMIT and credit; remote/mobile/EC2 fires only when usage.surface.workstationBound is TRUE; plan mode by usage.planMode; subagents by usage.subagents. If they already do a thing, it goes in alreadyStrong, NOT in recommendations. (4) \u26D4 CRITICAL \u2014 this person BUILDS Claude Code tooling, so their transcripts are full of the words 'worktree', 'pull request', 'fork', 'plan mode', 'by the way', 'teleport'. A keyword in the transcript is NOT evidence they use the feature. Rely on the STRUCTURAL facts only. (5) Ground every recommendation in a RECEIPT \u2014 a structural fact from their usage or a concrete session pain point \u2014 and CONVINCE with a specific case for how it helps THIS person, not a generic benefit. (6) Tailor every action to the Claude Desktop Mac app; NEVER give terminal-only `claude -p` advice. (7) Honor config.deliberateChoices (they stay on `main` on purpose \u2014 do NOT tell them to hand-juggle worktrees; parallel SESSIONS instead) and config.claudeAutoTools (never tell them to 'use' a tool Claude drives itself; for 'explain with visuals' the user just ASKS for a visual \u2014 do not name the tool). (8) Also name what they ALREADY do well. (9) SELF-CONTAINED but not verbose \u2014 lead with the PROBLEM, then the SOLUTION, then HOW to use it in their context. Plain language, no jargon, no enumerating multiple dates. An essay-like rec is a failed rec; so is a cryptic one. Follow this writing rubric strictly:\n\n" + writing + sourceLookupNote();
17059
17155
  const prompt = `THE RUBRIC \u2014 the complete catalog of best ways to use Claude Code. Judge the person against ALL of it, and ORDER by differenceRank per its PRIME DIRECTIVE:
17060
17156
 
17061
17157
  ${techniques}
@@ -17076,18 +17172,23 @@ Produce the gap analysis. Be thorough: cover every relevant catalog item they're
17076
17172
  }
17077
17173
  \`\`\`
17078
17174
  \`differenceRank\` is a strict 1..N ordering (1 = highest). Assign it per the PRIME DIRECTIVE and the rubric's general order; the report renders recommendations sorted by it. \`payoff\` (1-5) is a secondary strength cue. Recommend ONLY from the catalog.`;
17079
- console.log("gap \u2014 1 Sonnet pass over the full TECHNIQUES.md catalog + structural usage");
17175
+ const sha = promptSha([SYS, prompt, "sonnet"]);
17176
+ if (!process.argv.includes("--refresh")) {
17177
+ const prev = await reusableOutput(path13.join(CODING, "gap.json"), sha, (o) => Array.isArray(o.recommendations) && o.recommendations.length > 0);
17178
+ if (prev) {
17179
+ console.log(`[gap] inputs unchanged \u2014 reusing output from ${prev.generatedAt} (--refresh to regenerate)`);
17180
+ return;
17181
+ }
17182
+ }
17183
+ await ensureCodingDocs(CODING, all);
17184
+ console.log("gap \u2014 1 Sonnet pass over the full TECHNIQUES.md catalog + structural usage (+source lookups)");
17080
17185
  console.log(` signals: alreadyParallel=${alreadyParallel} planModeCalls=${planModeUses} forks=${forkCopies}/${all.length} featureBranches=${featureBranches.length} workstationBound=${workstationBound} chrome=${chromeToolUse}`);
17081
- const sandbox = await fs9.mkdtemp(path12.join(os2.tmpdir(), "gap-"));
17082
17186
  let out = { recommendations: [], alreadyStrong: [] };
17083
17187
  try {
17084
- const run2 = await invokeAgent({ prompt, systemPrompt: SYS, addDir: sandbox, allowedTools: ["Read"], maxTurns: 4, timeoutMs: 6e5, model: "sonnet" });
17188
+ const run2 = await invokeAgent({ prompt, systemPrompt: SYS, addDir: CODING, allowedTools: ["Read", "Grep", "Glob"], maxTurns: 10, timeoutMs: 6e5, model: "sonnet" });
17085
17189
  out = run2.json || out;
17086
17190
  } catch (e) {
17087
17191
  console.log("ERR", e.message.slice(0, 160));
17088
- } finally {
17089
- await fs9.rm(sandbox, { recursive: true, force: true }).catch(() => {
17090
- });
17091
17192
  }
17092
17193
  if (Array.isArray(out.recommendations)) {
17093
17194
  out.recommendations = out.recommendations.map((r, i) => ({ r, i })).sort((a, b) => (a.r.differenceRank ?? 99) - (b.r.differenceRank ?? 99) || (b.r.payoff ?? 0) - (a.r.payoff ?? 0) || a.i - b.i).map((x) => x.r);
@@ -17095,14 +17196,14 @@ Produce the gap analysis. Be thorough: cover every relevant catalog item they're
17095
17196
  if (!Array.isArray(out.recommendations) || out.recommendations.length === 0) {
17096
17197
  throw new Error("gap run produced 0 recommendations \u2014 refusing to overwrite the existing gap.json. Re-run the builder.");
17097
17198
  }
17098
- const result = { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...out };
17099
- await fs9.writeFile(path12.join(CODING, "gap.json"), JSON.stringify(result, null, 2));
17199
+ const result = { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), promptSha: sha, ...out };
17200
+ await fs11.writeFile(path13.join(CODING, "gap.json"), JSON.stringify(result, null, 2));
17100
17201
  console.log(`WROTE ${CODING}/gap.json \u2014 recommendations:${(out.recommendations || []).length} \xB7 alreadyStrong:${(out.alreadyStrong || []).length}`);
17101
17202
  }
17102
17203
  main().catch((e) => {
17103
17204
  console.error(e);
17104
17205
  process.exitCode = 1;
17105
17206
  }).finally(() => {
17106
- if (lockHeld) fs9.rm(LOCK, { force: true }).catch(() => {
17207
+ if (lockHeld) fs11.rm(LOCK, { force: true }).catch(() => {
17107
17208
  });
17108
17209
  });
@@ -15637,6 +15637,9 @@ function invokeAgent(inv, opts = {}) {
15637
15637
  return withLimitRetry(once, { label });
15638
15638
  }
15639
15639
 
15640
+ // ../../lib/agents/coding/grade-calibration.ts
15641
+ var GRADE_CALIBRATION = "\n\nSCORE CALIBRATION \u2014 graders systematically COMPRESS to the middle: real peaks get hedged down to 6-7, and routine sessions get polite 5-6s instead of null. Both are failures; fight them explicitly. Work each criterion in EXACTLY this order:\nSTEP 1 \xB7 EVIDENCE GATE \u2014 find the 1-3 verbatim '>> ' quotes that bear on the criterion. INCLUDE a criterion whenever genuine evidence is present (do not MISS quiet evidence \u2014 check every thread of the session, not just the dominant one). But with NO quotable moment the score is null, full stop: a session can be long, competent, and productive while being null on most criteria. Routine hand-holding earns null, never a 5 \u2014 and null is never a deduction.\nSTEP 2 \xB7 LADDER MATCH \u2014 with quotes in hand, read the criterion's rungs and pick the ONE rung whose marker best describes the quoted moment; name that rung in 'why'. AWARD THE RUNG THE EVIDENCE MATCHES: if your own 'why' describes rung N's criteria, give rung N \u2014 never deny it for lacking the NEXT rung's criteria.\nSTEP 3 \xB7 THE SINGLE BEST MOMENT IS THE SCORE \u2014 set the score by the strongest quoted moment, as if it were the whole session. NEVER average a peak down because the surrounding session is routine (the high-water rule), and never raise a score for volume, effort, or topic prestige without a matching moment.\nSTEP 4 \xB7 ANTI-HEDGE \u2014 if the moment genuinely matches an L8-10 anchor (an override the AI conceded, a shipped-and-verified capability, an 'oh shit, they're right' call, a first-principles redefinition that held), the score IS 8-10. Hedging a real L9 to a 7 is exactly as wrong as inventing a 6 for nothing. The middle is NOT a safe default: commit high on anchor-matching evidence, or go null.\nSTEP 5 \xB7 'CONSERVATIVE' \u2260 SUBTRACT \u2014 when a criterion's ladder says to grade conservatively, that means DO NOT EXCEED the rung whose marker the evidence matches; it NEVER means subtracting rungs from matched evidence. Evidence that matches a rung's marker gets that rung under a conservative reading too.";
15642
+
15640
15643
  // ../../lib/agents/shared/chunk.ts
15641
15644
  function chunkText(text2, max) {
15642
15645
  if (text2.length <= max) return [text2];
@@ -15985,14 +15988,28 @@ function rubric() {
15985
15988
  ${(c.rungs ?? []).map((r) => ` ${r.level} \u2014 ${r.marker}`).join("\n")}`
15986
15989
  ).join("\n\n");
15987
15990
  }
15991
+ function rubricCompact() {
15992
+ return GRADED_CRITERIA.map((c) => {
15993
+ const anchors = /ANCHORS?:/.exec(c.read) ? c.read.slice(c.read.search(/ANCHORS?:/)) : "";
15994
+ return `CRITERION "${c.key}" \u2014 ${c.label} [score 1\u201311, or null if not shown]
15995
+ ${c.definition}
15996
+ ${anchors ? ` ${anchors}
15997
+ ` : ""} LADDER:
15998
+ ${(c.rungs ?? []).map((r) => ` ${r.level} \u2014 ${r.marker}`).join("\n")}`;
15999
+ }).join("\n\n");
16000
+ }
16001
+ var HAIKU_SCORE_MAP_ID = "haiku+1@2026-07-14";
16002
+ var mapSmallScore = (v) => v != null && v >= 4 ? Math.min(10, v + 1) : v;
16003
+ var HAIKU_CALIBRATION = "\n\nWork each criterion in TWO STEPS, in order:\nSTEP A \u2014 QUOTE the 1-3 strongest verbatim '>> ' lines bearing on the criterion, checking every thread of the session, not just the dominant one. No quotable moment = null (routine hand-holding is null, never a 5; null is never a deduction).\nSTEP B \u2014 score by the SINGLE BEST quoted moment as if it were the whole session: pick the rung whose marker it matches and AWARD THAT RUNG \u2014 never deny rung N for lacking rung N+1, never average a peak down because the rest is routine, never raise for volume or topic prestige. Evidence matching an L8-10 anchor scores 8-10; the middle is not a safe default. Include every criterion genuinely present (don't MISS quiet evidence) \u2014 but rate strength strictly: weak-but-present is low, not mid.";
15988
16004
  var SYSTEM = "You grade how a person WORKS from one of their coding-agent sessions (Claude Code). You read mostly THEIR words; the model's code and output are compressed to context and you ignore the mechanical scaffolding. You never flatter: most sessions are routine hand-holding and should score low or null on most criteria. A score is a placement on the ladder backed by VERBATIM quotes of the user's own lines \u2014 never a vibe.\n\nSTANDING RULES (apply to every criterion):\n1. ABSENCE IS NEVER A DEDUCTION. If a criterion had no chance to show, its score is null \u2014 NOT a low. Don't invent a number for routine work.\n2. HIGH-WATER MARK. Taste and abstraction are PEAK measures \u2014 one genuinely brilliant move in a session counts, even surrounded by routine work. Never grade the person at their worst; a lone weak moment among strong ones is a slip, not the score.\n3. LOW-EFFORT-UNTIL-NEEDED IS THE IDEAL. A terse or vague prompt on routine work is correct economy \u2014 never penalize a vague ask, never reward word-count.\n4. DISCOUNT THE LITERAL HARSHNESS OF SELF-TALK. 'you idiot', 'you stupid cunt never again', 'this is retarded' \u2014 aimed at self or AI \u2014 are DRIVE and high standards, not defects. Grade the demonstrated behavior.\n5. PER-CONVERSATION CEILING IS 10. Never output 11 \u2014 that is the aggregator's job (it needs cross-conversation consistency / a stacked day this single session can't show). Scores run 2\u201310.\n6. LOG THE SPIKES IN HIGH DETAIL. When a moment is genuinely good (a flare \u2014 a sharp taste call, an out-reasons-the-tool insight, a real systems override), name it CONCRETELY and quote it. The 'instance' + 'why' are the high-detail record of exactly what was cool and why it placed where it did.";
15989
- function gradeSystemPrompt() {
15990
- return `${SYSTEM}
16005
+ function gradeSystemPrompt(model) {
16006
+ const small = /haiku/i.test(model ?? "");
16007
+ return `${SYSTEM}${small ? HAIKU_CALIBRATION : GRADE_CALIBRATION}
15991
16008
 
15992
16009
  Grade ONE coding session (provided in the user message) along the criteria below. ">> " lines are the USER's own words (the signal). ALL bracketed lines are machine context, never the user: "[AI: \u2026]" is the model working, "[bg task: \u2026]" / "[cmd output: \u2026]" are harness notifications, "[mode \u2192 \u2026]" marks a mode switch (context only \u2014 do not grade or quote them). ">> (queued \u2026)" is the user queuing work while the AI runs.
15993
16010
 
15994
16011
  CRITERIA:
15995
- ${rubric()}
16012
+ ${small ? rubricCompact() : rubric()}
15996
16013
 
15997
16014
  RULES:
15998
16015
  - Score ONLY what the user's moves genuinely show. Null is the right answer for most criteria in most sessions \u2014 do not force a number. Absence is never a deduction.
@@ -16058,7 +16075,7 @@ async function gradeSession(rec, opts = { outDir: "" }) {
16058
16075
  const seg = chunks.length > 1 ? ` This is SEGMENT ${ci + 1} of ${chunks.length} of one longer session \u2014 grade only what THIS segment shows; null for criteria not shown here (segments are merged afterward).` : "";
16059
16076
  const run2 = await invokeAgent({
16060
16077
  prompt: buildPrompt(rec, chunks[ci], seg),
16061
- systemPrompt: gradeSystemPrompt(),
16078
+ systemPrompt: gradeSystemPrompt(opts.model),
16062
16079
  addDir: sandbox,
16063
16080
  allowedTools: ["Read"],
16064
16081
  maxTurns: 6,
@@ -16074,6 +16091,13 @@ async function gradeSession(rec, opts = { outDir: "" }) {
16074
16091
  if (perChunk.length === 0) return null;
16075
16092
  const criteria = perChunk.length > 1 ? peakMergeByKey(perChunk, "key", "quotes") : perChunk[0];
16076
16093
  if (criteria.length === 0) return null;
16094
+ const small = /haiku/i.test(opts.model ?? "");
16095
+ if (small) for (const c of criteria) {
16096
+ c.score = mapSmallScore(c.score);
16097
+ c.low = mapSmallScore(c.low);
16098
+ c.high = mapSmallScore(c.high);
16099
+ c.bestEstimate = mapSmallScore(c.bestEstimate);
16100
+ }
16077
16101
  const grade = {
16078
16102
  sessionId: rec.sessionId,
16079
16103
  title: rec.title,
@@ -16082,7 +16106,7 @@ async function gradeSession(rec, opts = { outDir: "" }) {
16082
16106
  gradedAt: (/* @__PURE__ */ new Date()).toISOString(),
16083
16107
  rubricVersion: RUBRIC_FINGERPRINT,
16084
16108
  criteria,
16085
- meta: { costUsd, durationMs, calls: chunks.length }
16109
+ meta: { costUsd, durationMs, calls: chunks.length, ...small ? { scoreMap: HAIKU_SCORE_MAP_ID } : {} }
16086
16110
  };
16087
16111
  await fs5.mkdir(opts.outDir, { recursive: true });
16088
16112
  await fs5.writeFile(path9.join(opts.outDir, `${rec.sessionId}.json`), JSON.stringify(grade, null, 2));
@@ -16128,7 +16152,7 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
16128
16152
 
16129
16153
  // ../../lib/calibration/index.ts
16130
16154
  var DEFAULT_CALIBRATION = {
16131
- version: "2026-07-12.2",
16155
+ version: "2026-07-14.2",
16132
16156
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
16133
16157
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
16134
16158
  // without this being updated (and re-pushed to the server).
@@ -16217,7 +16241,7 @@ var DEFAULT_CALIBRATION = {
16217
16241
  }
16218
16242
  ],
16219
16243
  codingTiers: {
16220
- push: { median: 300, sigma: 1.121, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail shape from its actions-per-prompt distribution. AVERAGE over substantial days, cumulative not spiky." },
16244
+ push: { median: 300, sigma: 0.91, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail: a 1-in-1,000 user AVERAGES ~5k directed words/day (near-daily heavy dictation, clearly below the ~10k single-day record). AVERAGE over substantial days, cumulative not spiky." },
16221
16245
  focus: { median: 0.08, sigma: 0.559, tag: "estimated \u2014 proxy-anchored", source: "median: Anthropic 20h/week engaged-user figure implies ~1h/day of true rapid exchange against an 8h working day; ceiling anchored to the ~4h/day deep-work limit (45% share = 1-in-1,000). AVERAGE share, cumulative not spiky." },
16222
16246
  orchestration: { tag: "estimated \u2014 behavior bands", source: "no published concurrency distribution exists; ceiling anchored to the Claude Code lead's documented 10-15 parallel sessions" }
16223
16247
  },
@@ -16250,12 +16274,18 @@ var DEFAULT_CALIBRATION = {
16250
16274
  line: "the Claude Code lead runs 10\u201315 sessions at once; his #1 tip is 3\u20135 git worktrees in parallel"
16251
16275
  },
16252
16276
  throughput: {
16253
- // Top-0.1% words/day reference lines, anchored to the throughput ladder
16254
- // (THROUGHPUT_LADDER in throughput.ts): score 10 "world-class sustained" =
16255
- // 9k/day, score 11 "superhuman ceiling" = 12k/day. Calibrated to the person's
16256
- // own anchors, not a wild guess but still a target, not a measured population.
16257
- topAvgWordsPerDay: 9e3,
16258
- topPeakWordsPerDay: 12e3,
16277
+ // Two DIFFERENT kinds of line (2026-07-14.2): topAvg is a PERCENTILE
16278
+ // claim — what a 1-in-1,000 user AVERAGES over substantial days (5k/day:
16279
+ // near-daily heavy dictation; a measured top dictating power user
16280
+ // averages ~3.9k). topPeak is NOT a percentileit is the CEILING
16281
+ // reference, the wildest single days on record (~10k: a 14-16h
16282
+ // launch-day marathon), rendered as "wildest single days", never
16283
+ // "top X% peak". An avg-percentile and a peak-percentile can't both be
16284
+ // shown at a same-ish value (avg≈peak reads broken — user call), and a
16285
+ // peak PERCENTILE line is unknowable anyway; the record framing is
16286
+ // honest and keeps the visual gap.
16287
+ topAvgWordsPerDay: 5e3,
16288
+ topPeakWordsPerDay: 1e4,
16259
16289
  benchLabel: "top 0.1%",
16260
16290
  // No published "words typed/day" for heavy users — the real story is OUTPUT.
16261
16291
  loopsHeadline: ">1,000,000 lines of Rust at 99.8% tests passing",
@@ -16305,7 +16335,7 @@ var GRADES2 = path11.join(CODING, "grades");
16305
16335
  var LOGS = path11.join(GRADES2, "logs");
16306
16336
  async function main() {
16307
16337
  const sessions = JSON.parse(await fs6.readFile(path11.join(CODING, "sessions.json"), "utf8"));
16308
- const { gradable, thin, trivial } = partition(sessions.filter((s) => !s.duplicateOf));
16338
+ const { gradable, thin, trivial } = partition(sessions.filter((s) => s.klass === "interactive" && !s.duplicateOf));
16309
16339
  const ranked = gradable.slice().sort((a, b) => b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns));
16310
16340
  console.log(`[coding-grade] ${sessions.length} sessions \u2192 ${gradable.length} gradable \xB7 ${thin.length} thin \xB7 ${trivial.length} trivial (skipped)`);
16311
16341
  await fs6.mkdir(LOGS, { recursive: true });
@@ -15608,6 +15608,17 @@ function invokeAgent(inv, opts = {}) {
15608
15608
  return withLimitRetry(once, { label });
15609
15609
  }
15610
15610
 
15611
+ // ../../lib/agents/coding/promptCache.ts
15612
+ import { createHash } from "crypto";
15613
+ function promptSha(parts) {
15614
+ const h = createHash("sha256");
15615
+ for (const p of parts) {
15616
+ h.update(p ?? "");
15617
+ h.update("\0");
15618
+ }
15619
+ return h.digest("hex").slice(0, 16);
15620
+ }
15621
+
15611
15622
  // ../../lib/agents/engine/self-image-ref.ts
15612
15623
  import { promises as fs4 } from "fs";
15613
15624
 
@@ -15659,9 +15670,9 @@ ${parts.join("\n\n")}`;
15659
15670
  import path11 from "path";
15660
15671
 
15661
15672
  // ../../lib/calibration/fingerprint.ts
15662
- import { createHash } from "node:crypto";
15673
+ import { createHash as createHash2 } from "node:crypto";
15663
15674
  function rubricFingerprint(criteria) {
15664
- return createHash("sha256").update(JSON.stringify(criteria)).digest("hex").slice(0, 10);
15675
+ return createHash2("sha256").update(JSON.stringify(criteria)).digest("hex").slice(0, 10);
15665
15676
  }
15666
15677
 
15667
15678
  // ../../lib/agents/coding/criteria.ts
@@ -15810,7 +15821,7 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
15810
15821
 
15811
15822
  // ../../lib/calibration/index.ts
15812
15823
  var DEFAULT_CALIBRATION = {
15813
- version: "2026-07-12.2",
15824
+ version: "2026-07-14.2",
15814
15825
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
15815
15826
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
15816
15827
  // without this being updated (and re-pushed to the server).
@@ -15899,7 +15910,7 @@ var DEFAULT_CALIBRATION = {
15899
15910
  }
15900
15911
  ],
15901
15912
  codingTiers: {
15902
- push: { median: 300, sigma: 1.121, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail shape from its actions-per-prompt distribution. AVERAGE over substantial days, cumulative not spiky." },
15913
+ push: { median: 300, sigma: 0.91, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail: a 1-in-1,000 user AVERAGES ~5k directed words/day (near-daily heavy dictation, clearly below the ~10k single-day record). AVERAGE over substantial days, cumulative not spiky." },
15903
15914
  focus: { median: 0.08, sigma: 0.559, tag: "estimated \u2014 proxy-anchored", source: "median: Anthropic 20h/week engaged-user figure implies ~1h/day of true rapid exchange against an 8h working day; ceiling anchored to the ~4h/day deep-work limit (45% share = 1-in-1,000). AVERAGE share, cumulative not spiky." },
15904
15915
  orchestration: { tag: "estimated \u2014 behavior bands", source: "no published concurrency distribution exists; ceiling anchored to the Claude Code lead's documented 10-15 parallel sessions" }
15905
15916
  },
@@ -15932,12 +15943,18 @@ var DEFAULT_CALIBRATION = {
15932
15943
  line: "the Claude Code lead runs 10\u201315 sessions at once; his #1 tip is 3\u20135 git worktrees in parallel"
15933
15944
  },
15934
15945
  throughput: {
15935
- // Top-0.1% words/day reference lines, anchored to the throughput ladder
15936
- // (THROUGHPUT_LADDER in throughput.ts): score 10 "world-class sustained" =
15937
- // 9k/day, score 11 "superhuman ceiling" = 12k/day. Calibrated to the person's
15938
- // own anchors, not a wild guess but still a target, not a measured population.
15939
- topAvgWordsPerDay: 9e3,
15940
- topPeakWordsPerDay: 12e3,
15946
+ // Two DIFFERENT kinds of line (2026-07-14.2): topAvg is a PERCENTILE
15947
+ // claim — what a 1-in-1,000 user AVERAGES over substantial days (5k/day:
15948
+ // near-daily heavy dictation; a measured top dictating power user
15949
+ // averages ~3.9k). topPeak is NOT a percentileit is the CEILING
15950
+ // reference, the wildest single days on record (~10k: a 14-16h
15951
+ // launch-day marathon), rendered as "wildest single days", never
15952
+ // "top X% peak". An avg-percentile and a peak-percentile can't both be
15953
+ // shown at a same-ish value (avg≈peak reads broken — user call), and a
15954
+ // peak PERCENTILE line is unknowable anyway; the record framing is
15955
+ // honest and keeps the visual gap.
15956
+ topAvgWordsPerDay: 5e3,
15957
+ topPeakWordsPerDay: 1e4,
15941
15958
  benchLabel: "top 0.1%",
15942
15959
  // No published "words typed/day" for heavy users — the real story is OUTPUT.
15943
15960
  loopsHeadline: ">1,000,000 lines of Rust at 99.8% tests passing",
@@ -15996,10 +16013,20 @@ async function main() {
15996
16013
  `Self-sufficiency: across ${del.sessions || "?"} sessions, ${del.pctCorrect}% of delegation moments ideal, ${del.doomLoops || 0} doom-loops (got stuck and needed rescue ${del.doomLoops || 0} times)`
15997
16014
  ].join("\n");
15998
16015
  const siRef = selfImageReference(await loadSelfImage());
16016
+ const promptStr = prompt(days, metrics, siRef);
16017
+ const sha = promptSha([SYS, promptStr, "sonnet"]);
16018
+ if (!process.argv.includes("--refresh")) {
16019
+ const cur = await readJson("aggregate.json", null);
16020
+ if (cur?.bigPicture && cur.bigPictureSha === sha) {
16021
+ console.log(`[nutshell] inputs unchanged \u2014 reusing bigPicture (--refresh to regenerate)`);
16022
+ console.log("\nbigPicture:\n" + cur.bigPicture);
16023
+ return;
16024
+ }
16025
+ }
15999
16026
  const sandbox = await fs5.mkdtemp(path12.join(os2.tmpdir(), "nut-"));
16000
16027
  let bigPicture = "";
16001
16028
  try {
16002
- const run2 = await invokeAgent({ prompt: prompt(days, metrics, siRef), systemPrompt: SYS, addDir: sandbox, allowedTools: ["Read"], maxTurns: 3, timeoutMs: 24e4, model: "sonnet" });
16029
+ const run2 = await invokeAgent({ prompt: promptStr, systemPrompt: SYS, addDir: sandbox, allowedTools: ["Read"], maxTurns: 3, timeoutMs: 24e4, model: "sonnet" });
16003
16030
  bigPicture = String(run2.json?.bigPicture || "").trim();
16004
16031
  } catch (e) {
16005
16032
  console.log("ERR", e.message.slice(0, 120));
@@ -16017,6 +16044,7 @@ async function main() {
16017
16044
  process.exit(1);
16018
16045
  }
16019
16046
  fresh.bigPicture = bigPicture;
16047
+ fresh.bigPictureSha = sha;
16020
16048
  await fs5.writeFile(path12.join(CODING, "aggregate.json"), JSON.stringify(fresh, null, 2));
16021
16049
  console.log(`WROTE ${CODING}/aggregate.json bigPicture (${bigPicture.length} chars)`);
16022
16050
  console.log("\nbigPicture:\n" + bigPicture);