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.
- package/dist/cli.js +109 -49
- package/dist/engine/chat-loops.js +23 -2
- package/dist/engine/exp-allfacets.js +23 -2
- package/dist/engine/exp-person.js +23 -2
- package/dist/engine/exp-pipeline.js +22 -1
- package/dist/engine/ingest-export.js +2 -2
- package/dist/engine/peak-demos.js +23 -2
- package/dist/engine/person-dimension-summary.js +23 -2
- package/dist/engine/person-facet-lines.js +23 -2
- package/dist/engine/person-headline.js +23 -2
- package/dist/engine/person-report.js +23 -2
- package/dist/engine/person-self-image.js +23 -2
- package/dist/engine/public-report.js +25 -4
- package/dist/engine/run-analysis.js +23 -2
- package/dist/engine/run-tagger.js +22 -1
- package/dist/index.js +37 -8
- package/dist/pipeline/coding-agglomerate.js +25 -4
- package/dist/pipeline/coding-aggregate.js +3 -3
- package/dist/pipeline/coding-build.js +3 -3
- package/dist/pipeline/coding-coaching.js +25 -4
- package/dist/pipeline/coding-day-digest.js +25 -4
- package/dist/pipeline/coding-delegation.js +25 -4
- package/dist/pipeline/coding-expertise.js +25 -4
- package/dist/pipeline/coding-flow.js +3 -3
- package/dist/pipeline/coding-focus.js +22 -1
- package/dist/pipeline/coding-frontier-detail.js +25 -4
- package/dist/pipeline/coding-frontier.js +3 -3
- package/dist/pipeline/coding-gap-dist.js +3 -3
- package/dist/pipeline/coding-gap.js +25 -4
- package/dist/pipeline/coding-grade.js +40 -5
- package/dist/pipeline/coding-nutshell.js +25 -4
- package/dist/pipeline/coding-projects.js +3 -3
- package/dist/pipeline/coding-walkthrough.js +41 -5
- package/dist/web/app.js +65 -2
- package/dist/web/styles.css +1 -1
- package/package.json +1 -1
|
@@ -287,7 +287,7 @@ var CODING_CRITERIA = [
|
|
|
287
287
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
288
288
|
graded: true,
|
|
289
289
|
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.",
|
|
290
|
-
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) /
|
|
290
|
+
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).",
|
|
291
291
|
rungs: [
|
|
292
292
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
293
293
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -394,11 +394,11 @@ var IDLE_CAP_MS = 12 * 6e4;
|
|
|
394
394
|
|
|
395
395
|
// ../../lib/calibration/index.ts
|
|
396
396
|
var DEFAULT_CALIBRATION = {
|
|
397
|
-
version: "2026-07-
|
|
397
|
+
version: "2026-07-15.1",
|
|
398
398
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
399
399
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
400
400
|
// without this being updated (and re-pushed to the server).
|
|
401
|
-
rubricVersion: "
|
|
401
|
+
rubricVersion: "7983c01d53",
|
|
402
402
|
// Canonical scale = the one the product owner set for the public report
|
|
403
403
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
404
404
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -146,6 +146,25 @@ import { spawn } from "child_process";
|
|
|
146
146
|
import { promises as fs2 } from "fs";
|
|
147
147
|
import path2 from "path";
|
|
148
148
|
|
|
149
|
+
// ../coding-core/dist/env.js
|
|
150
|
+
var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
|
|
151
|
+
var warned = false;
|
|
152
|
+
function claudeCliEnv(base = process.env) {
|
|
153
|
+
if (process.env.POLYMATH_USE_API_KEY === "1")
|
|
154
|
+
return base;
|
|
155
|
+
const present = AUTH_VARS.filter((k) => base[k]);
|
|
156
|
+
if (!present.length)
|
|
157
|
+
return base;
|
|
158
|
+
if (!warned) {
|
|
159
|
+
warned = true;
|
|
160
|
+
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.`);
|
|
161
|
+
}
|
|
162
|
+
const scrubbed = { ...base };
|
|
163
|
+
for (const k of AUTH_VARS)
|
|
164
|
+
delete scrubbed[k];
|
|
165
|
+
return scrubbed;
|
|
166
|
+
}
|
|
167
|
+
|
|
149
168
|
// ../../lib/agents/shared/adapter.ts
|
|
150
169
|
function extractJson(text2) {
|
|
151
170
|
const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
|
|
@@ -250,7 +269,9 @@ var cliAdapter = {
|
|
|
250
269
|
await new Promise((resolve2, reject) => {
|
|
251
270
|
const child = spawn(CLAUDE_BIN, args, {
|
|
252
271
|
cwd: inv.cwd ?? inv.addDir,
|
|
253
|
-
|
|
272
|
+
// scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
|
|
273
|
+
// claude CLI away from their claude.ai login (coding-core/env.ts)
|
|
274
|
+
env: claudeCliEnv(),
|
|
254
275
|
stdio: ["ignore", "pipe", "pipe"],
|
|
255
276
|
// Own process group, so a timeout can kill the WHOLE tree (claude spawns
|
|
256
277
|
// its own children that otherwise orphan and pile up — the root cause of
|
|
@@ -15652,7 +15673,7 @@ var CODING_CRITERIA = [
|
|
|
15652
15673
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
15653
15674
|
graded: true,
|
|
15654
15675
|
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.",
|
|
15655
|
-
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) /
|
|
15676
|
+
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).",
|
|
15656
15677
|
rungs: [
|
|
15657
15678
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
15658
15679
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -16270,11 +16291,11 @@ function computeWorkstyle(inp) {
|
|
|
16270
16291
|
|
|
16271
16292
|
// ../../lib/calibration/index.ts
|
|
16272
16293
|
var DEFAULT_CALIBRATION = {
|
|
16273
|
-
version: "2026-07-
|
|
16294
|
+
version: "2026-07-15.1",
|
|
16274
16295
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
16275
16296
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
16276
16297
|
// without this being updated (and re-pushed to the server).
|
|
16277
|
-
rubricVersion: "
|
|
16298
|
+
rubricVersion: "7983c01d53",
|
|
16278
16299
|
// Canonical scale = the one the product owner set for the public report
|
|
16279
16300
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
16280
16301
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
|
|
|
151
151
|
import { promises as fs2 } from "fs";
|
|
152
152
|
import path2 from "path";
|
|
153
153
|
|
|
154
|
+
// ../coding-core/dist/env.js
|
|
155
|
+
var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
|
|
156
|
+
var warned = false;
|
|
157
|
+
function claudeCliEnv(base = process.env) {
|
|
158
|
+
if (process.env.POLYMATH_USE_API_KEY === "1")
|
|
159
|
+
return base;
|
|
160
|
+
const present = AUTH_VARS.filter((k) => base[k]);
|
|
161
|
+
if (!present.length)
|
|
162
|
+
return base;
|
|
163
|
+
if (!warned) {
|
|
164
|
+
warned = true;
|
|
165
|
+
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.`);
|
|
166
|
+
}
|
|
167
|
+
const scrubbed = { ...base };
|
|
168
|
+
for (const k of AUTH_VARS)
|
|
169
|
+
delete scrubbed[k];
|
|
170
|
+
return scrubbed;
|
|
171
|
+
}
|
|
172
|
+
|
|
154
173
|
// ../../lib/agents/shared/adapter.ts
|
|
155
174
|
function extractJson(text2) {
|
|
156
175
|
const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
|
|
@@ -255,7 +274,9 @@ var cliAdapter = {
|
|
|
255
274
|
await new Promise((resolve2, reject) => {
|
|
256
275
|
const child = spawn(CLAUDE_BIN, args, {
|
|
257
276
|
cwd: inv.cwd ?? inv.addDir,
|
|
258
|
-
|
|
277
|
+
// scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
|
|
278
|
+
// claude CLI away from their claude.ai login (coding-core/env.ts)
|
|
279
|
+
env: claudeCliEnv(),
|
|
259
280
|
stdio: ["ignore", "pipe", "pipe"],
|
|
260
281
|
// Own process group, so a timeout can kill the WHOLE tree (claude spawns
|
|
261
282
|
// its own children that otherwise orphan and pile up — the root cause of
|
|
@@ -15732,7 +15753,7 @@ var CODING_CRITERIA = [
|
|
|
15732
15753
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
15733
15754
|
graded: true,
|
|
15734
15755
|
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.",
|
|
15735
|
-
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) /
|
|
15756
|
+
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).",
|
|
15736
15757
|
rungs: [
|
|
15737
15758
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
15738
15759
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -16162,6 +16183,19 @@ function aiWindowCutoff(sessions, opts = {}) {
|
|
|
16162
16183
|
const floorStart = gradableStarts[floor - 1];
|
|
16163
16184
|
return floorStart < windowCutoff ? floorStart : windowCutoff;
|
|
16164
16185
|
}
|
|
16186
|
+
var MAX_GRADED_DEFAULT = 150;
|
|
16187
|
+
function maxGraded() {
|
|
16188
|
+
const n = Number(process.env.POLYMATH_MAX_GRADED);
|
|
16189
|
+
return Number.isFinite(n) && n >= 0 ? n : MAX_GRADED_DEFAULT;
|
|
16190
|
+
}
|
|
16191
|
+
function substanceRank(a, b) {
|
|
16192
|
+
return b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns);
|
|
16193
|
+
}
|
|
16194
|
+
function capGradable(gradable) {
|
|
16195
|
+
const sorted = gradable.slice().sort(substanceRank);
|
|
16196
|
+
const cap = maxGraded();
|
|
16197
|
+
return cap > 0 && sorted.length > cap ? sorted.slice(0, cap) : sorted;
|
|
16198
|
+
}
|
|
16165
16199
|
|
|
16166
16200
|
// ../../lib/agents/coding/profile.ts
|
|
16167
16201
|
import path10 from "path";
|
|
@@ -16175,11 +16209,11 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
|
|
|
16175
16209
|
|
|
16176
16210
|
// ../../lib/calibration/index.ts
|
|
16177
16211
|
var DEFAULT_CALIBRATION = {
|
|
16178
|
-
version: "2026-07-
|
|
16212
|
+
version: "2026-07-15.1",
|
|
16179
16213
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
16180
16214
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
16181
16215
|
// without this being updated (and re-pushed to the server).
|
|
16182
|
-
rubricVersion: "
|
|
16216
|
+
rubricVersion: "7983c01d53",
|
|
16183
16217
|
// Canonical scale = the one the product owner set for the public report
|
|
16184
16218
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
16185
16219
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -16362,9 +16396,10 @@ async function main() {
|
|
|
16362
16396
|
const { gradable: allGradable, thin, trivial } = partition(live);
|
|
16363
16397
|
const cutoff = aiWindowCutoff(live);
|
|
16364
16398
|
const gradable = cutoff ? allGradable.filter((s) => (s.start ?? "") >= cutoff) : allGradable;
|
|
16365
|
-
const ranked = gradable
|
|
16399
|
+
const ranked = capGradable(gradable);
|
|
16366
16400
|
console.log(`[coding-grade] ${sessions.length} sessions \u2192 ${allGradable.length} gradable \xB7 ${thin.length} thin \xB7 ${trivial.length} trivial (skipped)`);
|
|
16367
16401
|
if (cutoff) console.log(`[coding-grade] AI window: grading sessions since ${cutoff.slice(0, 10)} \u2014 ${gradable.length} of ${allGradable.length} gradable (POLYMATH_AI_WINDOW_DAYS=0 for full history)`);
|
|
16402
|
+
if (ranked.length < gradable.length) console.log(`[coding-grade] cap: grading the ${ranked.length} richest of ${gradable.length} gradable sessions (POLYMATH_MAX_GRADED=${maxGraded()}; 0 = uncapped) \u2014 the rest still feed every deterministic number`);
|
|
16368
16403
|
await fs6.mkdir(LOGS, { recursive: true });
|
|
16369
16404
|
const limit = ALL ? ranked.length : N;
|
|
16370
16405
|
const picked = [];
|
|
@@ -147,6 +147,25 @@ import { spawn } from "child_process";
|
|
|
147
147
|
import { promises as fs2 } from "fs";
|
|
148
148
|
import path2 from "path";
|
|
149
149
|
|
|
150
|
+
// ../coding-core/dist/env.js
|
|
151
|
+
var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
|
|
152
|
+
var warned = false;
|
|
153
|
+
function claudeCliEnv(base = process.env) {
|
|
154
|
+
if (process.env.POLYMATH_USE_API_KEY === "1")
|
|
155
|
+
return base;
|
|
156
|
+
const present = AUTH_VARS.filter((k) => base[k]);
|
|
157
|
+
if (!present.length)
|
|
158
|
+
return base;
|
|
159
|
+
if (!warned) {
|
|
160
|
+
warned = true;
|
|
161
|
+
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.`);
|
|
162
|
+
}
|
|
163
|
+
const scrubbed = { ...base };
|
|
164
|
+
for (const k of AUTH_VARS)
|
|
165
|
+
delete scrubbed[k];
|
|
166
|
+
return scrubbed;
|
|
167
|
+
}
|
|
168
|
+
|
|
150
169
|
// ../../lib/agents/shared/adapter.ts
|
|
151
170
|
function extractJson(text2) {
|
|
152
171
|
const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
|
|
@@ -251,7 +270,9 @@ var cliAdapter = {
|
|
|
251
270
|
await new Promise((resolve2, reject) => {
|
|
252
271
|
const child = spawn(CLAUDE_BIN, args, {
|
|
253
272
|
cwd: inv.cwd ?? inv.addDir,
|
|
254
|
-
|
|
273
|
+
// scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
|
|
274
|
+
// claude CLI away from their claude.ai login (coding-core/env.ts)
|
|
275
|
+
env: claudeCliEnv(),
|
|
255
276
|
stdio: ["ignore", "pipe", "pipe"],
|
|
256
277
|
// Own process group, so a timeout can kill the WHOLE tree (claude spawns
|
|
257
278
|
// its own children that otherwise orphan and pile up — the root cause of
|
|
@@ -15710,7 +15731,7 @@ var CODING_CRITERIA = [
|
|
|
15710
15731
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
15711
15732
|
graded: true,
|
|
15712
15733
|
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.",
|
|
15713
|
-
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) /
|
|
15734
|
+
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).",
|
|
15714
15735
|
rungs: [
|
|
15715
15736
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
15716
15737
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -15821,11 +15842,11 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
|
|
|
15821
15842
|
|
|
15822
15843
|
// ../../lib/calibration/index.ts
|
|
15823
15844
|
var DEFAULT_CALIBRATION = {
|
|
15824
|
-
version: "2026-07-
|
|
15845
|
+
version: "2026-07-15.1",
|
|
15825
15846
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
15826
15847
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
15827
15848
|
// without this being updated (and re-pushed to the server).
|
|
15828
|
-
rubricVersion: "
|
|
15849
|
+
rubricVersion: "7983c01d53",
|
|
15829
15850
|
// Canonical scale = the one the product owner set for the public report
|
|
15830
15851
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
15831
15852
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -49,7 +49,7 @@ var CODING_CRITERIA = [
|
|
|
49
49
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
50
50
|
graded: true,
|
|
51
51
|
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.",
|
|
52
|
-
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) /
|
|
52
|
+
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).",
|
|
53
53
|
rungs: [
|
|
54
54
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
55
55
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -205,11 +205,11 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
|
|
|
205
205
|
|
|
206
206
|
// ../../lib/calibration/index.ts
|
|
207
207
|
var DEFAULT_CALIBRATION = {
|
|
208
|
-
version: "2026-07-
|
|
208
|
+
version: "2026-07-15.1",
|
|
209
209
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
210
210
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
211
211
|
// without this being updated (and re-pushed to the server).
|
|
212
|
-
rubricVersion: "
|
|
212
|
+
rubricVersion: "7983c01d53",
|
|
213
213
|
// Canonical scale = the one the product owner set for the public report
|
|
214
214
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
215
215
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
|
|
|
151
151
|
import { promises as fs2 } from "fs";
|
|
152
152
|
import path2 from "path";
|
|
153
153
|
|
|
154
|
+
// ../coding-core/dist/env.js
|
|
155
|
+
var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
|
|
156
|
+
var warned = false;
|
|
157
|
+
function claudeCliEnv(base = process.env) {
|
|
158
|
+
if (process.env.POLYMATH_USE_API_KEY === "1")
|
|
159
|
+
return base;
|
|
160
|
+
const present = AUTH_VARS.filter((k) => base[k]);
|
|
161
|
+
if (!present.length)
|
|
162
|
+
return base;
|
|
163
|
+
if (!warned) {
|
|
164
|
+
warned = true;
|
|
165
|
+
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.`);
|
|
166
|
+
}
|
|
167
|
+
const scrubbed = { ...base };
|
|
168
|
+
for (const k of AUTH_VARS)
|
|
169
|
+
delete scrubbed[k];
|
|
170
|
+
return scrubbed;
|
|
171
|
+
}
|
|
172
|
+
|
|
154
173
|
// ../../lib/agents/shared/adapter.ts
|
|
155
174
|
function extractJson(text2) {
|
|
156
175
|
const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
|
|
@@ -255,7 +274,9 @@ var cliAdapter = {
|
|
|
255
274
|
await new Promise((resolve2, reject) => {
|
|
256
275
|
const child = spawn(CLAUDE_BIN, args, {
|
|
257
276
|
cwd: inv.cwd ?? inv.addDir,
|
|
258
|
-
|
|
277
|
+
// scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
|
|
278
|
+
// claude CLI away from their claude.ai login (coding-core/env.ts)
|
|
279
|
+
env: claudeCliEnv(),
|
|
259
280
|
stdio: ["ignore", "pipe", "pipe"],
|
|
260
281
|
// Own process group, so a timeout can kill the WHOLE tree (claude spawns
|
|
261
282
|
// its own children that otherwise orphan and pile up — the root cause of
|
|
@@ -15916,6 +15937,19 @@ function aiWindowCutoff(sessions, opts = {}) {
|
|
|
15916
15937
|
const floorStart = gradableStarts[floor - 1];
|
|
15917
15938
|
return floorStart < windowCutoff ? floorStart : windowCutoff;
|
|
15918
15939
|
}
|
|
15940
|
+
var MAX_GRADED_DEFAULT = 150;
|
|
15941
|
+
function maxGraded() {
|
|
15942
|
+
const n = Number(process.env.POLYMATH_MAX_GRADED);
|
|
15943
|
+
return Number.isFinite(n) && n >= 0 ? n : MAX_GRADED_DEFAULT;
|
|
15944
|
+
}
|
|
15945
|
+
function substanceRank(a, b) {
|
|
15946
|
+
return b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns);
|
|
15947
|
+
}
|
|
15948
|
+
function capGradable(gradable) {
|
|
15949
|
+
const sorted = gradable.slice().sort(substanceRank);
|
|
15950
|
+
const cap = maxGraded();
|
|
15951
|
+
return cap > 0 && sorted.length > cap ? sorted.slice(0, cap) : sorted;
|
|
15952
|
+
}
|
|
15919
15953
|
|
|
15920
15954
|
// ../../lib/agents/coding/profile.ts
|
|
15921
15955
|
import path10 from "path";
|
|
@@ -15961,7 +15995,7 @@ var CODING_CRITERIA = [
|
|
|
15961
15995
|
label: "Abstraction \u2014 seeing the load-bearing thing, and being right",
|
|
15962
15996
|
graded: true,
|
|
15963
15997
|
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.",
|
|
15964
|
-
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) /
|
|
15998
|
+
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).",
|
|
15965
15999
|
rungs: [
|
|
15966
16000
|
{ level: 2, marker: "A fork existed; defers the call to the AI, or takes the obvious branch; vague." },
|
|
15967
16001
|
{ level: 4, marker: "Notices something, but the question is vague or obvious \u2014 anyone in the seat asks it." },
|
|
@@ -16069,11 +16103,11 @@ var TRANSCRIPT_LINE_RE = new RegExp(`^\\s*(${NOTE})((,| and) ${NOTE})*\\s*$|^\\s
|
|
|
16069
16103
|
|
|
16070
16104
|
// ../../lib/calibration/index.ts
|
|
16071
16105
|
var DEFAULT_CALIBRATION = {
|
|
16072
|
-
version: "2026-07-
|
|
16106
|
+
version: "2026-07-15.1",
|
|
16073
16107
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
16074
16108
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
16075
16109
|
// without this being updated (and re-pushed to the server).
|
|
16076
|
-
rubricVersion: "
|
|
16110
|
+
rubricVersion: "7983c01d53",
|
|
16077
16111
|
// Canonical scale = the one the product owner set for the public report
|
|
16078
16112
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
16079
16113
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -16251,7 +16285,8 @@ async function main() {
|
|
|
16251
16285
|
const sessions = JSON.parse(await fs6.readFile(path11.join(CODING, "sessions.json"), "utf8"));
|
|
16252
16286
|
const live = sessions.filter((s) => s.klass === "interactive" && !s.duplicateOf);
|
|
16253
16287
|
const cutoff = aiWindowCutoff(live);
|
|
16254
|
-
const
|
|
16288
|
+
const eligible = live.filter((s) => !isTrivial(s) && (!cutoff || (s.start ?? "") >= cutoff));
|
|
16289
|
+
const todo = capGradable(eligible);
|
|
16255
16290
|
await fs6.mkdir(DIR, { recursive: true });
|
|
16256
16291
|
const pending = [];
|
|
16257
16292
|
for (const s of todo) {
|
|
@@ -16259,6 +16294,7 @@ async function main() {
|
|
|
16259
16294
|
pending.push(s);
|
|
16260
16295
|
}
|
|
16261
16296
|
console.log(`[walkthrough] ${todo.length} substantial sessions${cutoff ? ` since ${cutoff.slice(0, 10)} (AI window)` : ""} \xB7 ${pending.length} to build on ${MODEL}, conc ${CONC}`);
|
|
16297
|
+
if (todo.length < eligible.length) console.log(`[walkthrough] cap: the ${todo.length} richest of ${eligible.length} eligible sessions (POLYMATH_MAX_GRADED; 0 = uncapped)`);
|
|
16262
16298
|
const lim = limiter(CONC);
|
|
16263
16299
|
startRun("walkthrough", pending.length);
|
|
16264
16300
|
await Promise.all(pending.map((s) => lim(async () => {
|
package/dist/web/app.js
CHANGED
|
@@ -8331,11 +8331,11 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
|
|
|
8331
8331
|
|
|
8332
8332
|
// ../../lib/calibration/index.ts
|
|
8333
8333
|
var DEFAULT_CALIBRATION = {
|
|
8334
|
-
version: "2026-07-
|
|
8334
|
+
version: "2026-07-15.1",
|
|
8335
8335
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
8336
8336
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
8337
8337
|
// without this being updated (and re-pushed to the server).
|
|
8338
|
-
rubricVersion: "
|
|
8338
|
+
rubricVersion: "7983c01d53",
|
|
8339
8339
|
// Canonical scale = the one the product owner set for the public report
|
|
8340
8340
|
// (11=0.01% … 8=2%), extended downward from the old report ladder. The old
|
|
8341
8341
|
// CodeAnalysisView / npm-viewer maps (7→10%/15%, 6→25%/30%) were drift, not
|
|
@@ -11056,6 +11056,66 @@ function GrowthAxes({ axes, embedded }) {
|
|
|
11056
11056
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: axes.map((ax, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(GrowthAxisRow, { ax }, i)) })
|
|
11057
11057
|
] });
|
|
11058
11058
|
}
|
|
11059
|
+
var wrapName = (name, width = 22) => {
|
|
11060
|
+
const out = [];
|
|
11061
|
+
let line = "";
|
|
11062
|
+
for (const w of name.split(" ")) {
|
|
11063
|
+
if (line && (line + " " + w).length > width) {
|
|
11064
|
+
out.push(line);
|
|
11065
|
+
line = w;
|
|
11066
|
+
} else line = line ? `${line} ${w}` : w;
|
|
11067
|
+
}
|
|
11068
|
+
if (line) out.push(line);
|
|
11069
|
+
return out;
|
|
11070
|
+
};
|
|
11071
|
+
function FacetRadar({ facets, jump, title }) {
|
|
11072
|
+
if (facets.length < 3) return null;
|
|
11073
|
+
const cx = 170, cy = 150, R = 88;
|
|
11074
|
+
const n = facets.length;
|
|
11075
|
+
const pt = (i, r) => {
|
|
11076
|
+
const a = Math.PI * 2 * i / n - Math.PI / 2;
|
|
11077
|
+
return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
|
|
11078
|
+
};
|
|
11079
|
+
const ring = (f) => facets.map((_, i) => pt(i, R * f).join(",")).join(" ");
|
|
11080
|
+
const poly = facets.map((f, i) => pt(i, R * Math.max(0.04, Math.min(1, f.score / f.max))).join(",")).join(" ");
|
|
11081
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "px-5 pt-1", children: [
|
|
11082
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "mb-1 text-center font-serif text-[17px] text-ink", children: title }),
|
|
11083
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "-90 -34 520 368", width: "100%", style: { maxWidth: 480 }, "aria-label": `${title ?? "facet"} radar`, children: [
|
|
11084
|
+
[0.5, 1].map((f) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("polygon", { points: ring(f), fill: "none", stroke: "var(--line, #e7e2d9)" }, f)),
|
|
11085
|
+
facets.map((_, i) => {
|
|
11086
|
+
const [x, y] = pt(i, R);
|
|
11087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: cx, y1: cy, x2: x, y2: y, stroke: "var(--line, #e7e2d9)" }, i);
|
|
11088
|
+
}),
|
|
11089
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("polygon", { points: poly, fill: "rgba(180,95,63,.14)", stroke: "#b45f3f", strokeWidth: 2 }),
|
|
11090
|
+
facets.map((f, i) => {
|
|
11091
|
+
const [x, y] = pt(i, R * Math.max(0.04, Math.min(1, f.score / f.max)));
|
|
11092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: x, cy: y, r: 3, fill: "#b45f3f" }, i);
|
|
11093
|
+
}),
|
|
11094
|
+
facets.map((f, i) => {
|
|
11095
|
+
const [x, y] = pt(i, R + 20);
|
|
11096
|
+
const anchor = Math.abs(x - cx) < 10 ? "middle" : x > cx ? "start" : "end";
|
|
11097
|
+
const above = y < cy;
|
|
11098
|
+
const lines = [...wrapName(f.name), `${f.score}/${f.max}`];
|
|
11099
|
+
const firstY = above ? y - 6 - (lines.length - 1) * 13 : y + 12;
|
|
11100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
11101
|
+
"text",
|
|
11102
|
+
{
|
|
11103
|
+
x,
|
|
11104
|
+
y: firstY,
|
|
11105
|
+
textAnchor: anchor,
|
|
11106
|
+
fontSize: 11,
|
|
11107
|
+
fill: "#6b6257",
|
|
11108
|
+
style: jump ? { cursor: "pointer" } : void 0,
|
|
11109
|
+
onClick: jump ? () => jump(f.key) : void 0,
|
|
11110
|
+
children: lines.map((ln, j) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tspan", { x, dy: j === 0 ? 0 : 13, fontWeight: j === lines.length - 1 ? 700 : 400, fill: j === lines.length - 1 ? "#1a1714" : "#6b6257", children: ln }, j))
|
|
11111
|
+
},
|
|
11112
|
+
i
|
|
11113
|
+
);
|
|
11114
|
+
})
|
|
11115
|
+
] }) })
|
|
11116
|
+
] });
|
|
11117
|
+
}
|
|
11118
|
+
var radarFacets = (dim) => dim.facets.map((f) => ({ key: f.facetKey, name: f.name, score: f.grade?.score ?? f.grade?.bestEstimate ?? null, max: f.scaleMax || 10 })).filter((f) => f.score != null);
|
|
11059
11119
|
function DimensionCard({ dim, onOpen, fb, demos, facetLines, slipLines, summary }) {
|
|
11060
11120
|
const jump = (fk) => document.getElementById(`f-${dim.key}-${fk}`)?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
11061
11121
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Card, { className: "mb-5 !p-0", children: [
|
|
@@ -11072,6 +11132,7 @@ function DimensionCard({ dim, onOpen, fb, demos, facetLines, slipLines, summary
|
|
|
11072
11132
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-semibold text-accent", children: s })
|
|
11073
11133
|
] }, f.facetKey);
|
|
11074
11134
|
}) }),
|
|
11135
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FacetRadar, { facets: radarFacets(dim), jump }),
|
|
11075
11136
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DimensionMore, { summary, overall: dim.overall }),
|
|
11076
11137
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "px-5 pb-2", children: dim.facets.map((f) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FacetSection, { dim, facet: f, onOpen, fb, demos: demos[`${dim.key}:${f.facetKey}`], line: facetLines[`${dim.key}:${f.facetKey}`], slips: slipLines[`${dim.key}:${f.facetKey}`] }, f.facetKey)) }),
|
|
11077
11138
|
dim.growthAxes && dim.growthAxes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(GrowthAxes, { axes: dim.growthAxes }),
|
|
@@ -11268,6 +11329,7 @@ function OceanSection({ entries, demos, facetLines, slipLines, fb, onOpen }) {
|
|
|
11268
11329
|
if (entries.length === 0) return null;
|
|
11269
11330
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "mb-9", children: [
|
|
11270
11331
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NarrativeHeading, { children: "Your OCEAN scores" }),
|
|
11332
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FacetRadar, { facets: entries.map((e) => ({ key: e.key, name: e.facet.name, score: e.raw, max: e.max || 10 })).filter((f) => f.score != null) }),
|
|
11271
11333
|
entries.map((e) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CollapsibleFacet, { entry: e, demos, facetLines, slipLines, fb, onOpen }, e.key))
|
|
11272
11334
|
] });
|
|
11273
11335
|
}
|
|
@@ -11419,6 +11481,7 @@ function DetailedDataView() {
|
|
|
11419
11481
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "h-px flex-1 bg-line" })
|
|
11420
11482
|
] }),
|
|
11421
11483
|
filter === "all" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScoreDistribution, { marks: distributionMarks(dims), compact: true, className: "mb-5" }),
|
|
11484
|
+
filter === "all" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mb-6 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-2", children: dims.filter((d) => radarFacets(d).length >= 3).map((d) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: () => setFilter(d.key), className: "rounded-2xl border border-line bg-paper py-4 text-left transition-colors hover:border-accent", "aria-label": `Open ${d.label}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FacetRadar, { facets: radarFacets(d), title: d.label }) }, d.key)) }),
|
|
11422
11485
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-6 flex flex-wrap items-center gap-2", children: [
|
|
11423
11486
|
["all", ...dims.map((d) => d.key)].map((k) => {
|
|
11424
11487
|
const label = k === "all" ? "Overview" : dims.find((d) => d.key === k)?.label || k;
|