polymath-society 0.2.11 → 0.2.13

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.
Files changed (36) hide show
  1. package/dist/cli.js +109 -49
  2. package/dist/engine/chat-loops.js +23 -2
  3. package/dist/engine/exp-allfacets.js +23 -2
  4. package/dist/engine/exp-person.js +23 -2
  5. package/dist/engine/exp-pipeline.js +22 -1
  6. package/dist/engine/ingest-export.js +2 -2
  7. package/dist/engine/peak-demos.js +23 -2
  8. package/dist/engine/person-dimension-summary.js +23 -2
  9. package/dist/engine/person-facet-lines.js +23 -2
  10. package/dist/engine/person-headline.js +23 -2
  11. package/dist/engine/person-report.js +23 -2
  12. package/dist/engine/person-self-image.js +23 -2
  13. package/dist/engine/public-report.js +25 -4
  14. package/dist/engine/run-analysis.js +23 -2
  15. package/dist/engine/run-tagger.js +22 -1
  16. package/dist/index.js +37 -8
  17. package/dist/pipeline/coding-agglomerate.js +25 -4
  18. package/dist/pipeline/coding-aggregate.js +3 -3
  19. package/dist/pipeline/coding-build.js +3 -3
  20. package/dist/pipeline/coding-coaching.js +25 -4
  21. package/dist/pipeline/coding-day-digest.js +25 -4
  22. package/dist/pipeline/coding-delegation.js +25 -4
  23. package/dist/pipeline/coding-expertise.js +25 -4
  24. package/dist/pipeline/coding-flow.js +3 -3
  25. package/dist/pipeline/coding-focus.js +22 -1
  26. package/dist/pipeline/coding-frontier-detail.js +25 -4
  27. package/dist/pipeline/coding-frontier.js +3 -3
  28. package/dist/pipeline/coding-gap-dist.js +3 -3
  29. package/dist/pipeline/coding-gap.js +25 -4
  30. package/dist/pipeline/coding-grade.js +40 -5
  31. package/dist/pipeline/coding-nutshell.js +25 -4
  32. package/dist/pipeline/coding-projects.js +3 -3
  33. package/dist/pipeline/coding-walkthrough.js +41 -5
  34. package/dist/web/app.js +65 -2
  35. package/dist/web/styles.css +1 -1
  36. package/package.json +1 -1
@@ -530,7 +530,7 @@ var growthLens = {
530
530
  {
531
531
  key: "implementation",
532
532
  name: "Observed execution improvement",
533
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
533
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
534
534
  rungs: [
535
535
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
536
536
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -530,7 +530,7 @@ var growthLens = {
530
530
  {
531
531
  key: "implementation",
532
532
  name: "Observed execution improvement",
533
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
533
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
534
534
  rungs: [
535
535
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
536
536
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -530,7 +530,7 @@ var growthLens = {
530
530
  {
531
531
  key: "implementation",
532
532
  name: "Observed execution improvement",
533
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
533
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
534
534
  rungs: [
535
535
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
536
536
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -530,7 +530,7 @@ var growthLens = {
530
530
  {
531
531
  key: "implementation",
532
532
  name: "Observed execution improvement",
533
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
533
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
534
534
  rungs: [
535
535
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
536
536
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -530,7 +530,7 @@ var growthLens = {
530
530
  {
531
531
  key: "implementation",
532
532
  name: "Observed execution improvement",
533
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
533
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
534
534
  rungs: [
535
535
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
536
536
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -616,7 +616,7 @@ var growthLens = {
616
616
  {
617
617
  key: "implementation",
618
618
  name: "Observed execution improvement",
619
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
619
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
620
620
  rungs: [
621
621
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
622
622
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -1096,6 +1096,25 @@ import { spawn } from "child_process";
1096
1096
  import { promises as fs4 } from "fs";
1097
1097
  import path5 from "path";
1098
1098
 
1099
+ // ../coding-core/dist/env.js
1100
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1101
+ var warned = false;
1102
+ function claudeCliEnv(base = process.env) {
1103
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1104
+ return base;
1105
+ const present = AUTH_VARS.filter((k) => base[k]);
1106
+ if (!present.length)
1107
+ return base;
1108
+ if (!warned) {
1109
+ warned = true;
1110
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1111
+ }
1112
+ const scrubbed = { ...base };
1113
+ for (const k of AUTH_VARS)
1114
+ delete scrubbed[k];
1115
+ return scrubbed;
1116
+ }
1117
+
1099
1118
  // ../../lib/agents/shared/adapter.ts
1100
1119
  function extractJson(text2) {
1101
1120
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1200,7 +1219,9 @@ var cliAdapter = {
1200
1219
  await new Promise((resolve2, reject) => {
1201
1220
  const child = spawn(CLAUDE_BIN, args, {
1202
1221
  cwd: inv.cwd ?? inv.addDir,
1203
- env: process.env,
1222
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1223
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1224
+ env: claudeCliEnv(),
1204
1225
  stdio: ["ignore", "pipe", "pipe"],
1205
1226
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1206
1227
  // its own children that otherwise orphan and pile up — the root cause of
@@ -142,6 +142,25 @@ import { spawn } from "child_process";
142
142
  import { promises as fs2 } from "fs";
143
143
  import path2 from "path";
144
144
 
145
+ // ../coding-core/dist/env.js
146
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
147
+ var warned = false;
148
+ function claudeCliEnv(base = process.env) {
149
+ if (process.env.POLYMATH_USE_API_KEY === "1")
150
+ return base;
151
+ const present = AUTH_VARS.filter((k) => base[k]);
152
+ if (!present.length)
153
+ return base;
154
+ if (!warned) {
155
+ warned = true;
156
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
157
+ }
158
+ const scrubbed = { ...base };
159
+ for (const k of AUTH_VARS)
160
+ delete scrubbed[k];
161
+ return scrubbed;
162
+ }
163
+
145
164
  // ../../lib/agents/shared/adapter.ts
146
165
  function extractJson(text2) {
147
166
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -246,7 +265,9 @@ var cliAdapter = {
246
265
  await new Promise((resolve2, reject) => {
247
266
  const child = spawn(CLAUDE_BIN, args, {
248
267
  cwd: inv.cwd ?? inv.addDir,
249
- env: process.env,
268
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
269
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
270
+ env: claudeCliEnv(),
250
271
  stdio: ["ignore", "pipe", "pipe"],
251
272
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
252
273
  // its own children that otherwise orphan and pile up — the root cause of
@@ -15635,11 +15656,11 @@ var ENGINE_DATA = process.env.POLYMATH_DATA_DIR ? path10.resolve(process.env.POL
15635
15656
 
15636
15657
  // ../../lib/calibration/index.ts
15637
15658
  var DEFAULT_CALIBRATION = {
15638
- version: "2026-07-14.2",
15659
+ version: "2026-07-15.1",
15639
15660
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
15640
15661
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
15641
15662
  // without this being updated (and re-pushed to the server).
15642
- rubricVersion: "f51b3a93a3",
15663
+ rubricVersion: "7983c01d53",
15643
15664
  // Canonical scale = the one the product owner set for the public report
15644
15665
  // (11=0.01% … 8=2%), extended downward from the old report ladder. The old
15645
15666
  // CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
@@ -16180,7 +16201,7 @@ var growthLens = {
16180
16201
  {
16181
16202
  key: "implementation",
16182
16203
  name: "Observed execution improvement",
16183
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
16204
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
16184
16205
  rungs: [
16185
16206
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
16186
16207
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -265,6 +265,25 @@ import { spawn } from "child_process";
265
265
  import { promises as fs4 } from "fs";
266
266
  import path5 from "path";
267
267
 
268
+ // ../coding-core/dist/env.js
269
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
270
+ var warned = false;
271
+ function claudeCliEnv(base = process.env) {
272
+ if (process.env.POLYMATH_USE_API_KEY === "1")
273
+ return base;
274
+ const present = AUTH_VARS.filter((k) => base[k]);
275
+ if (!present.length)
276
+ return base;
277
+ if (!warned) {
278
+ warned = true;
279
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
280
+ }
281
+ const scrubbed = { ...base };
282
+ for (const k of AUTH_VARS)
283
+ delete scrubbed[k];
284
+ return scrubbed;
285
+ }
286
+
268
287
  // ../../lib/agents/shared/adapter.ts
269
288
  function extractJson(text2) {
270
289
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -369,7 +388,9 @@ var cliAdapter = {
369
388
  await new Promise((resolve2, reject) => {
370
389
  const child = spawn(CLAUDE_BIN, args, {
371
390
  cwd: inv.cwd ?? inv.addDir,
372
- env: process.env,
391
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
392
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
393
+ env: claudeCliEnv(),
373
394
  stdio: ["ignore", "pipe", "pipe"],
374
395
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
375
396
  // its own children that otherwise orphan and pile up — the root cause of
@@ -15797,7 +15818,7 @@ var growthLens = {
15797
15818
  {
15798
15819
  key: "implementation",
15799
15820
  name: "Observed execution improvement",
15800
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
15821
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
15801
15822
  rungs: [
15802
15823
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
15803
15824
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -242,6 +242,25 @@ import { spawn } from "child_process";
242
242
  import { promises as fs3 } from "fs";
243
243
  import path4 from "path";
244
244
 
245
+ // ../coding-core/dist/env.js
246
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
247
+ var warned = false;
248
+ function claudeCliEnv(base = process.env) {
249
+ if (process.env.POLYMATH_USE_API_KEY === "1")
250
+ return base;
251
+ const present = AUTH_VARS.filter((k) => base[k]);
252
+ if (!present.length)
253
+ return base;
254
+ if (!warned) {
255
+ warned = true;
256
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
257
+ }
258
+ const scrubbed = { ...base };
259
+ for (const k of AUTH_VARS)
260
+ delete scrubbed[k];
261
+ return scrubbed;
262
+ }
263
+
245
264
  // ../../lib/agents/shared/adapter.ts
246
265
  function extractJson(text2) {
247
266
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -346,7 +365,9 @@ var cliAdapter = {
346
365
  await new Promise((resolve2, reject) => {
347
366
  const child = spawn(CLAUDE_BIN, args, {
348
367
  cwd: inv.cwd ?? inv.addDir,
349
- env: process.env,
368
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
369
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
370
+ env: claudeCliEnv(),
350
371
  stdio: ["ignore", "pipe", "pipe"],
351
372
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
352
373
  // its own children that otherwise orphan and pile up — the root cause of
package/dist/index.js CHANGED
@@ -1794,6 +1794,25 @@ import path3 from "path";
1794
1794
  // src/grade/cliAdapter.ts
1795
1795
  import { spawn } from "child_process";
1796
1796
 
1797
+ // ../coding-core/dist/env.js
1798
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1799
+ var warned = false;
1800
+ function claudeCliEnv(base2 = process.env) {
1801
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1802
+ return base2;
1803
+ const present = AUTH_VARS.filter((k) => base2[k]);
1804
+ if (!present.length)
1805
+ return base2;
1806
+ if (!warned) {
1807
+ warned = true;
1808
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1809
+ }
1810
+ const scrubbed = { ...base2 };
1811
+ for (const k of AUTH_VARS)
1812
+ delete scrubbed[k];
1813
+ return scrubbed;
1814
+ }
1815
+
1797
1816
  // src/grade/adapter.ts
1798
1817
  function extractJson(text2) {
1799
1818
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1945,7 +1964,9 @@ var cliAdapter = {
1945
1964
  await new Promise((resolve2, reject) => {
1946
1965
  const child = spawn(bin, args, {
1947
1966
  cwd: inv.cwd ?? inv.addDir,
1948
- env: process.env,
1967
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1968
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1969
+ env: claudeCliEnv(),
1949
1970
  stdio: ["ignore", "pipe", "pipe"],
1950
1971
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1951
1972
  // children that otherwise orphan and pile up).
@@ -2198,7 +2219,7 @@ var CODING_CRITERIA = [
2198
2219
  label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
2199
2220
  graded: true,
2200
2221
  definition: "Under genuine ambiguity (an obvious path sitting right there, no answer key): did the USER see that the obvious path was subtly wrong \u2014 or that something decisive was invisible \u2014 and do the non-obvious thing that made it right, AND were they right? The graded unit is the whole move: the CATCH (noticing the fork) -> the QUESTION (formulating it) -> the CALL (resolving it). The move surfaces three interchangeable ways, scored identically: a REFRAME (collapse a mess to its real axis), a QUESTION (pose the hard thing nobody posed), or an INSTRUMENT (build the code/chart/structure that makes the truth legible, then read it). Tag the SUBSTANCE, not the medium \u2014 a chart built (technical act) to make a human-intensity call legible is a JUDGMENT catch.",
2201
- read: "FOUR LEVERS set the height: (1) INVISIBILITY \u2014 how non-obvious there was anything to catch; a sharp operator in the flow drives past it (the DOMINANT lever); (2) DIFFICULTY of forming the catch; (3) STAKES \u2014 'without this, things silently go wrong' is the 9-10 condition; (4) SOUNDNESS \u2014 did the call hold. THREE OVERRIDING GATES: (a) OBVIOUSNESS KILLS IT \u2014 a correct, even load-bearing catch a sharp operator reaches anyway scores LOW ('you're evaluating the person not the AI' is correct but obvious -> ~5; 'compute in the OAuth dead-time' is real but fairly obvious -> ~6). (b) LEVERAGE BEATS INSIGHT \u2014 a move whose payoff is a HIGHER RATE OF FUTURE INSIGHT (building the tool that lets him set his own boundaries; timestamp-by-timestamp structure to instruct the grader precisely) raises the bandwidth of the loop that produces every later catch, and can outrank a clean one-off reframe. (c) SOUNDNESS GATE \u2014 a confident WRONG call to a noticed fork is an ANTI-SIGNAL; an honest 'not sure, here's a range' is NOT penalized. HUNT THE FORK BLIND \u2014 reconstruct what continuing-without-noticing looked like, then check whether/why he diverged; do NOT hand yourself the fork pre-formed or you score everyone's problem-finding a 10. TAG every instance: kind = systems | judgment | both (+ optional register: human/product/measurement). Reasoning and instrument-building are the SAME criterion. ANCHORS: 10 = 'OCEAN won't change, measure effectiveness of actions' (reframe that redefines the measure) / 'don't hurt Natalie, not long-term compatible' (lived judgment, requires being the person) / 'plot it sorted, let me set the boundaries' (leverage \u2014 builds the bandwidth tool); 9 = 'word count IS the proxy \u2014 sitting there is unfakeable focus' / 'uncertainty collapses in that direction'; 8 = 'a better metric is the difficulty of content + original synthesis' (hard opening question); 7 = 'this candidate seems too strong for his judgement to be real' (real non-obvious catch, modest stakes); 6 = 'compute in the OAuth dead-time' / 'why overcomplicate it, single agent' (real but obvious); 5 = 'you're evaluating the person not the AI' (correct but obvious).",
2222
+ read: "FOUR LEVERS set the height: (1) INVISIBILITY \u2014 how non-obvious there was anything to catch; a sharp operator in the flow drives past it (the DOMINANT lever); (2) DIFFICULTY of forming the catch; (3) STAKES \u2014 'without this, things silently go wrong' is the 9-10 condition; (4) SOUNDNESS \u2014 did the call hold. THREE OVERRIDING GATES: (a) OBVIOUSNESS KILLS IT \u2014 a correct, even load-bearing catch a sharp operator reaches anyway scores LOW ('you're evaluating the person not the AI' is correct but obvious -> ~5; 'compute in the OAuth dead-time' is real but fairly obvious -> ~6). (b) LEVERAGE BEATS INSIGHT \u2014 a move whose payoff is a HIGHER RATE OF FUTURE INSIGHT (building the tool that lets him set his own boundaries; timestamp-by-timestamp structure to instruct the grader precisely) raises the bandwidth of the loop that produces every later catch, and can outrank a clean one-off reframe. (c) SOUNDNESS GATE \u2014 a confident WRONG call to a noticed fork is an ANTI-SIGNAL; an honest 'not sure, here's a range' is NOT penalized. HUNT THE FORK BLIND \u2014 reconstruct what continuing-without-noticing looked like, then check whether/why he diverged; do NOT hand yourself the fork pre-formed or you score everyone's problem-finding a 10. TAG every instance: kind = systems | judgment | both (+ optional register: human/product/measurement). Reasoning and instrument-building are the SAME criterion. ANCHORS: 10 = 'OCEAN won't change, measure effectiveness of actions' (reframe that redefines the measure) / a human-stakes call where the person overrode the analytically-clean answer on knowledge only they could have about someone involved, and was right (lived judgment, requires being the person) / 'plot it sorted, let me set the boundaries' (leverage \u2014 builds the bandwidth tool); 9 = 'word count IS the proxy \u2014 sitting there is unfakeable focus' / 'uncertainty collapses in that direction'; 8 = 'a better metric is the difficulty of content + original synthesis' (hard opening question); 7 = 'this candidate seems too strong for his judgement to be real' (real non-obvious catch, modest stakes); 6 = 'compute in the OAuth dead-time' / 'why overcomplicate it, single agent' (real but obvious); 5 = 'you're evaluating the person not the AI' (correct but obvious).",
2202
2223
  rungs: [
2203
2224
  { level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
2204
2225
  { level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
@@ -2650,11 +2671,11 @@ var LocalGradeProvider = class {
2650
2671
 
2651
2672
  // ../../lib/calibration/index.ts
2652
2673
  var DEFAULT_CALIBRATION = {
2653
- version: "2026-07-14.2",
2674
+ version: "2026-07-15.1",
2654
2675
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
2655
2676
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
2656
2677
  // without this being updated (and re-pushed to the server).
2657
- rubricVersion: "f51b3a93a3",
2678
+ rubricVersion: "7983c01d53",
2658
2679
  // Canonical scale = the one the product owner set for the public report
2659
2680
  // (11=0.01% … 8=2%), extended downward from the old report ladder. The old
2660
2681
  // CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
@@ -3263,7 +3284,9 @@ var cliAdapter2 = {
3263
3284
  await new Promise((resolve2, reject) => {
3264
3285
  const child = spawn3(CLAUDE_BIN, args, {
3265
3286
  cwd: inv.cwd ?? inv.addDir,
3266
- env: process.env,
3287
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
3288
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
3289
+ env: claudeCliEnv(),
3267
3290
  stdio: ["ignore", "pipe", "pipe"],
3268
3291
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
3269
3292
  // its own children that otherwise orphan and pile up — the root cause of
@@ -19632,7 +19655,7 @@ var growthLens = {
19632
19655
  {
19633
19656
  key: "implementation",
19634
19657
  name: "Observed execution improvement",
19635
- definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament (often OCD-like), so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
19658
+ definition: "The slope itself: whether diagnosed problems get attacked with experiments and whether the change in BEHAVIOR lands and sticks. Graded from dated evidence on ACTIONS, not feelings: a recurring feeling, urge, or complaint is expected base temperament and is NOT a mark against implementation \u2014 only a recurring unchanged behavior is. Credit a changed action even when the underlying feeling repeats verbatim (e.g. still dreads cold outreach but now sends it daily). A COMPULSION OR URGE IS TEMPERAMENT, NOT AN ACTION: a perfectionism / over-analysis / decision-paralysis loop is the behavioral face of base temperament, so if the person INCREASINGLY OVERRIDES it and still ships, that is temperament being managed better over time \u2014 a RISING slope, NOT a recurring unchanged action \u2014 and must NOT cap the score. Only count such a loop against implementation if the ACTION genuinely shows NO improvement across the window (still loses whole days with no rising ability to override and ship). A FIX THAT NEEDED A FORCING FUNCTION STILL COUNTS, FULLY: a change triggered by a deadline, a painful lesson, or 'getting burnt' that then LANDS and STICKS is a real fix on a legitimate route \u2014 learning from consequence is how humans change \u2014 so do NOT dock a landed, sticky fix for needing a catalyst; the catalyst is not a defect. Judge the slope over LONG horizons (weeks\u2192months across the dated record), NEVER within a single day or conversation \u2014 behavior change takes time, so the absence of same-day change is NOT a failure and must NEVER buckle the score. GRADE THE AGGREGATE SLOPE, not the one unfixed thread: humans cannot fix everything, and very few fix anything at all \u2014 so fixing several genuinely hard, DISTINCT stuck-points and making them stick across the window is exceptional and scores HIGH (9-10), and one stubborn temperament loop that is being increasingly overridden does NOT pull an otherwise broad, rising, sticky record down. The real question: across the record, did the problems they identified earlier become LESS of an issue in their later ACTIONS? Internal baselines (neuroticism, needing people to feel happy) are not the unit here \u2014 grade the actions.",
19636
19659
  rungs: [
19637
19660
  { level: 3, marker: "The same BEHAVIORS recur across the window, unchanged \u2014 recognition (if any) never becomes a change in action. (A recurring feeling alongside changed behavior does NOT belong here \u2014 that is a fix, scored higher.)" },
19638
19661
  { level: 5, marker: "Occasionally a fix happens \u2014 intends to solve, and sometimes it lands, but not usually." },
@@ -23367,8 +23390,9 @@ function startServer(opts) {
23367
23390
  if (req.method === "GET" && route === "/auth/callback") {
23368
23391
  try {
23369
23392
  const id = await completeLogin(dataDir, new URL(url, serverUrl).searchParams);
23393
+ const back = host === "127.0.0.1" ? serverUrl.replace("//127.0.0.1:", "//localhost:") : serverUrl;
23370
23394
  res.writeHead(200, { "content-type": MIME[".html"] });
23371
- res.end(`<!doctype html><meta charset="utf-8"><title>Signed in</title><body style="font-family:system-ui;padding:40px"><p>Signed in as <b>${id.email.replace(/</g, "&lt;")}</b>.</p><p><a href="/">Back to your report</a> (or just close this tab \u2014 the report page picks it up on its own).</p></body>`);
23395
+ res.end(`<!doctype html><meta charset="utf-8"><title>Signed in</title><body style="font-family:system-ui;padding:40px"><p>Signed in as <b>${id.email.replace(/</g, "&lt;")}</b>.</p><p><a href="${back}/">Back to your report</a> (or just close this tab \u2014 the report page picks it up on its own).</p></body>`);
23372
23396
  } catch (e) {
23373
23397
  res.writeHead(400, { "content-type": MIME[".html"] });
23374
23398
  res.end(`<!doctype html><meta charset="utf-8"><title>Sign-in failed</title><body style="font-family:system-ui;padding:40px"><p><b>Sign-in failed.</b></p><p>${String(e.message).replace(/</g, "&lt;")}</p><p><a href="/auth/login">Try again</a></p></body>`);
@@ -23532,7 +23556,12 @@ function startServer(opts) {
23532
23556
  }).catch(() => {
23533
23557
  });
23534
23558
  resolve2({
23535
- url: serverUrl,
23559
+ // The DISPLAYED/opened URL says localhost — friendlier than 127.0.0.1
23560
+ // (owner call 2026-07-15); same server, same loopback. serverUrl itself
23561
+ // stays on the bound host because the Google sign-in redirect is
23562
+ // allow-listed for http://127.0.0.1:*/** in Supabase — auth flows
23563
+ // through 127.0.0.1 no matter which name the person's tab uses.
23564
+ url: host === "127.0.0.1" ? `http://localhost:${port}` : serverUrl,
23536
23565
  port,
23537
23566
  close: () => new Promise((r) => server.close(() => r())),
23538
23567
  setProfile: (p) => {