polymath-society 0.2.26 → 0.2.28

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 CHANGED
@@ -22851,8 +22851,8 @@ function machineBudget(totalMemBytes = os8.totalmem(), cpus = os8.availableParal
22851
22851
  }
22852
22852
  function apportionHeavy(budget) {
22853
22853
  const grade = Math.max(2, Math.floor(budget * 0.45));
22854
- const digest = Math.max(1, Math.floor(budget * 0.17));
22855
- const walkthrough = Math.max(1, Math.floor(budget * 0.17));
22854
+ const digest = Math.max(1, Math.floor(budget * 0.13));
22855
+ const walkthrough = Math.max(1, Math.floor(budget * 0.25));
22856
22856
  const delegation = Math.max(1, budget - grade - digest - walkthrough - 2);
22857
22857
  return { grade, digest, walkthrough, delegation };
22858
22858
  }
@@ -22884,11 +22884,12 @@ function stages(o) {
22884
22884
  // so they run WHILE grading runs (grading is the wall-clock giant; these
22885
22885
  // finish inside its shadow). Budget: grade 8 + digest 3 + walkthrough 3 +
22886
22886
  // two single-call stages ≈ 16 peak subprocesses (measured-safe envelope).
22887
- { script: "coding-grade.mts", label: "AI-grade every substantial session", llm: true, args: gradeArgs, batch: "heavy" },
22888
- { script: "coding-day-digest.mts", label: "Day-by-day digests", llm: true, args: ["--model", narrativeModel, "--conc", String(h.digest)], out: "coding/day-digest.json", batch: "heavy" },
22889
- { script: "coding-walkthrough.mts", label: "Per-session walkthroughs", llm: true, args: ["--model", narrativeModel, "--conc", String(h.walkthrough)], batch: "heavy" },
22890
- { script: "coding-frontier-detail.mts", label: "What you're doing at the frontier", llm: true, args: [], out: "coding/frontier-detail.json", batch: "heavy" },
22891
- { script: "coding-delegation.mts", label: "Delegation patterns", llm: true, args: ["--model", model, "--conc", String(h.delegation)], out: "coding/delegation-rollup.json", batch: "heavy" },
22887
+ { script: "coding-grade.mts", label: "AI-grade every substantial session", llm: true, weight: 30, args: gradeArgs, batch: "heavy" },
22888
+ { script: "coding-day-digest.mts", label: "Day-by-day digests", llm: true, weight: 17, args: ["--model", narrativeModel, "--conc", String(h.digest)], out: "coding/day-digest.json", batch: "heavy" },
22889
+ // walkthrough weight 28 = was 55 at 2 workers, ~28 at the rebalanced 4
22890
+ { script: "coding-walkthrough.mts", label: "Per-session walkthroughs", llm: true, weight: 28, args: ["--model", narrativeModel, "--conc", String(h.walkthrough)], batch: "heavy" },
22891
+ { script: "coding-frontier-detail.mts", label: "What you're doing at the frontier", llm: true, weight: 3, args: [], out: "coding/frontier-detail.json", batch: "heavy" },
22892
+ { script: "coding-delegation.mts", label: "Delegation patterns", llm: true, weight: 2, args: ["--model", model, "--conc", String(h.delegation)], out: "coding/delegation-rollup.json", batch: "heavy" },
22892
22893
  // The FULL focus stage: flow-rule judgment + the paste-into-CLAUDE.md block.
22893
22894
  // The deterministic --skip-llm run above keeps the numbers current every
22894
22895
  // run; this one produces the AI block — it was MISSING from the graded tier
@@ -22896,14 +22897,14 @@ function stages(o) {
22896
22897
  // the companion), so overnight full runs shipped a report with no flow
22897
22898
  // rules and nothing failed loud (found 2026-07-15). Both LLM passes are
22898
22899
  // prompt-hash gated, so an unchanged corpus re-run costs zero calls.
22899
- { script: "coding-focus.mts", label: "Flow rules + focus judgment", llm: true, args: [], out: "coding/focus.json", batch: "heavy" },
22900
+ { script: "coding-focus.mts", label: "Flow rules + focus judgment", llm: true, weight: 6, args: [], out: "coding/focus.json", batch: "heavy" },
22900
22901
  // ---- corpus aggregate (reads grades; deterministic rollup) ----
22901
22902
  { script: "coding-aggregate.mts", label: "Corpus aggregate \u2014 ability ceiling + flow", llm: false, args: [], out: "coding/aggregate.json" },
22902
22903
  // ---- grade readers (grades/* is complete once aggregate ran) ----
22903
22904
  // No default --model here: the agglomerate script defaults itself to Opus
22904
22905
  // (one call per run; the axis verdicts are the most judgment-heavy output).
22905
22906
  // An explicit user model choice still wins.
22906
- { script: "coding-agglomerate.mts", label: "Agglomerated criteria + verdicts + signature moves", llm: true, args: o.model ? ["--model", o.model] : [], out: "coding/agglomerate.json", batch: "grade-readers" },
22907
+ { script: "coding-agglomerate.mts", label: "Agglomerated criteria + verdicts + signature moves", llm: true, weight: 4, args: o.model ? ["--model", o.model] : [], out: "coding/agglomerate.json", batch: "grade-readers" },
22907
22908
  // Domain-expertise map DISABLED (owner call 2026-07-22): the single most
22908
22909
  // expensive stage of the whole run ($13.88 of $49.34 measured — 129 sonnet
22909
22910
  // calls) and for most users the hiring-bar filter correctly returns ZERO
@@ -22912,22 +22913,22 @@ function stages(o) {
22912
22913
  // fold into the grade call); the report renders nothing when the artifact
22913
22914
  // is absent.
22914
22915
  // ---- final synthesis (reads the finished aggregates + batch outputs) ----
22915
- { script: "coding-coaching.mts", label: "Coaching + feel-seen copy", llm: true, args: [], out: "coding/coaching.json", batch: "synthesis" },
22916
- { script: "coding-gap.mts", label: "Gap-to-close vs best practice", llm: true, args: [], out: "coding/gap.json", batch: "synthesis" },
22916
+ { script: "coding-coaching.mts", label: "Coaching + feel-seen copy", llm: true, weight: 2, args: [], out: "coding/coaching.json", batch: "synthesis" },
22917
+ { script: "coding-gap.mts", label: "Gap-to-close vs best practice", llm: true, weight: 5, args: [], out: "coding/gap.json", batch: "synthesis" },
22917
22918
  // Work brief — the hiring-manager narrative + continuous timeline. Consumes
22918
22919
  // day-digest.json (heavy batch, already complete) + concurrency/projects;
22919
22920
  // disjoint output, so it rides the synthesis batch. Defaults itself to Opus
22920
22921
  // (the journey's significance calls are judgment-heavy); an explicit model
22921
22922
  // choice wins. Prompt-hash gated + up-to-date-skip like its siblings.
22922
- { script: "coding-workbrief.mts", label: "Work brief \u2014 narrative timeline", llm: true, args: o.model ? ["--model", o.model] : [], out: "coding/workbrief.json", batch: "synthesis" },
22923
+ { script: "coding-workbrief.mts", label: "Work brief \u2014 narrative timeline", llm: true, weight: 3, args: o.model ? ["--model", o.model] : [], out: "coding/workbrief.json", batch: "synthesis" },
22923
22924
  // Growth reads grades/* + deterministic artifacts only (no per-session AI
22924
22925
  // calls — it deliberately ignores the AI recency window and covers the full
22925
22926
  // history); disjoint output, so it rides the synthesis batch. Like
22926
22927
  // agglomerate it defaults itself to Opus; an explicit model choice wins.
22927
- { script: "coding-growth.mts", label: "Growth arcs + learning rate", llm: true, args: o.model ? ["--model", o.model] : [], out: "coding/growth.json", batch: "synthesis" },
22928
+ { script: "coding-growth.mts", label: "Growth arcs + learning rate", llm: true, weight: 5, args: o.model ? ["--model", o.model] : [], out: "coding/growth.json", batch: "synthesis" },
22928
22929
  // nutshell stays LAST + alone: it merges INTO aggregate.json while the two
22929
22930
  // above read the compiled profile — racing them re-reads mid-write.
22930
- { script: "coding-nutshell.mts", label: "Big-picture nutshell", llm: true, args: [], out: "coding/aggregate.json" }
22931
+ { script: "coding-nutshell.mts", label: "Big-picture nutshell", llm: true, weight: 1, args: [], out: "coding/aggregate.json" }
22931
22932
  // merges bigPicture INTO aggregate.json
22932
22933
  ];
22933
22934
  }
@@ -24874,9 +24875,8 @@ function makeMultiBar(out = process.stderr) {
24874
24875
  const elapsedMin = Math.round((Date.now() - t0) / 6e4);
24875
24876
  const laneRow = ([name17, l]) => {
24876
24877
  const real = [...l.fracs.values()].reduce((a, f) => a + (f.total ? Math.min(1, f.done / f.total) : 0), 0);
24877
- const creep = 0.9 * (1 - Math.exp(-(Date.now() - l.stageAt) / 9e4));
24878
- const withinFrac = Math.min(Math.max(0, l.total - (l.i - 1)), Math.max(real, l.i >= 1 && l.i <= l.total ? creep : 0));
24879
- const frac = l.total ? (l.i - 1 + withinFrac) / l.total : 0;
24878
+ const withinFrac = Math.min(Math.max(0, l.total - (l.i - 1)), real);
24879
+ const frac = l.forced ?? (l.total ? (l.i - 1 + withinFrac) / l.total : 0);
24880
24880
  l.shown = Math.max(l.shown, Math.max(0, Math.min(1, frac)));
24881
24881
  const fill = Math.round(l.shown * width);
24882
24882
  return ` ${name17.padEnd(6)} [${"\u2588".repeat(fill)}${"\u2591".repeat(width - fill)}] ${String(Math.round(l.shown * 100)).padStart(3)}%`;
@@ -24917,7 +24917,7 @@ function makeMultiBar(out = process.stderr) {
24917
24917
  return {
24918
24918
  lane(name17) {
24919
24919
  const getLane = () => {
24920
- const l = lanes.get(name17) ?? { i: 0, total: 0, label: "", fracs: /* @__PURE__ */ new Map(), stageAt: Date.now(), shown: 0 };
24920
+ const l = lanes.get(name17) ?? { i: 0, total: 0, label: "", fracs: /* @__PURE__ */ new Map(), forced: null, stageAt: Date.now(), shown: 0 };
24921
24921
  lanes.set(name17, l);
24922
24922
  return l;
24923
24923
  };
@@ -24942,6 +24942,12 @@ function makeMultiBar(out = process.stderr) {
24942
24942
  }
24943
24943
  repaintAround(tty ? line : `[${name17}] ${line.trimStart()}`);
24944
24944
  },
24945
+ // The cli's duration-weighted fraction — supersedes local math.
24946
+ setFrac(f) {
24947
+ const l = getLane();
24948
+ l.forced = Math.max(0, Math.min(1, f));
24949
+ if (tty) repaintAround();
24950
+ },
24945
24951
  // A stage completed: its share now lives in `i`, so drop its running
24946
24952
  // fraction (fall back to the untagged slot for single stages).
24947
24953
  stageDone(key2) {
@@ -24958,6 +24964,7 @@ function makeMultiBar(out = process.stderr) {
24958
24964
  l.i = l.total + 1;
24959
24965
  l.label = label;
24960
24966
  l.fracs.clear();
24967
+ l.forced = null;
24961
24968
  l.shown = 1;
24962
24969
  repaintAround(`\u25B8 ${name17} \u2713 ${label}`);
24963
24970
  }
@@ -28458,9 +28465,15 @@ Running the full analysis on ${backend.name === "cli" ? "Claude Code" : "Codex"}
28458
28465
  const tag = /^\s*\[([^\]]+)\]/.exec(line)?.[1] ?? "_";
28459
28466
  withinFracs[lane].set(tag, { done: Number(m[1]), total: Number(m[2]) });
28460
28467
  progress[lane].withinFrac = Math.round(sumFracs(lane) * 1e3) / 1e3;
28468
+ if (lane === "coding") {
28469
+ const f = codingFracRef();
28470
+ progress.coding.frac = f;
28471
+ codingLane.setFrac(f);
28472
+ }
28461
28473
  earlyHandle.setProgress(progress);
28462
28474
  }
28463
28475
  };
28476
+ let codingFracRef = () => 0;
28464
28477
  mbar.setLink(earlyHandle.url);
28465
28478
  const codingLane = mbar.lane("coding");
28466
28479
  const aiCount = { coding: 0, chat: 0 };
@@ -28488,6 +28501,16 @@ Running the full analysis on ${backend.name === "cli" ? "Claude Code" : "Codex"}
28488
28501
  const { chatEngineStages: chatEngineStages2 } = await Promise.resolve().then(() => (init_chatPipeline(), chatPipeline_exports));
28489
28502
  aiCount.coding = stages2(pipeOpts).filter((st) => st.llm).length;
28490
28503
  aiCount.chat = chatEngineStages2().filter((st) => st.llm).length;
28504
+ const tagOf = (script) => script.replace(/^coding-|\.mts$/g, "");
28505
+ const codingWeights = new Map(stages2(pipeOpts).filter((st) => st.llm).map((st) => [tagOf(st.script), st.weight ?? 1]));
28506
+ const codingTotalW = [...codingWeights.values()].reduce((a, b) => a + b, 0) || 1;
28507
+ let codingDoneW = 0;
28508
+ const codingFrac = () => {
28509
+ let f = codingDoneW;
28510
+ for (const [tag, x] of withinFracs.coding) f += (codingWeights.get(tag) ?? 0) * (x.total ? Math.min(1, x.done / x.total) : 0);
28511
+ return Math.min(1, f / codingTotalW);
28512
+ };
28513
+ codingFracRef = codingFrac;
28491
28514
  const codingDone = runPipeline({
28492
28515
  ...pipeOpts,
28493
28516
  onUpToDate: () => {
@@ -28512,9 +28535,12 @@ Running the full analysis on ${backend.name === "cli" ? "Claude Code" : "Codex"}
28512
28535
  if (codingPinned || !llm) return;
28513
28536
  aiDone.coding++;
28514
28537
  const key2 = script.replace(/^coding-|\.mts$/g, "");
28538
+ codingDoneW += codingWeights.get(key2) ?? 0;
28515
28539
  if (!withinFracs.coding.delete(key2)) withinFracs.coding.delete("_");
28516
28540
  codingLane.stageDone(key2);
28517
- progress.coding = { ...progress.coding, i: Math.min(aiDone.coding + 1, aiCount.coding), total: aiCount.coding, done: false, withinFrac: Math.round(sumFracs("coding") * 1e3) / 1e3 };
28541
+ const f = codingFrac();
28542
+ codingLane.setFrac(f);
28543
+ progress.coding = { ...progress.coding, i: Math.min(aiDone.coding + 1, aiCount.coding), total: aiCount.coding, done: false, frac: f, withinFrac: Math.round(sumFracs("coding") * 1e3) / 1e3 };
28518
28544
  earlyHandle.setProgress(progress);
28519
28545
  },
28520
28546
  // While pinned, the scrolling stage output stays quiet ("prints hella
@@ -16899,6 +16899,7 @@ function validate(raw, grades, costUsd) {
16899
16899
  const r = raw;
16900
16900
  const overall = typeof r.overall === "string" ? r.overall.trim() : "";
16901
16901
  if (!overall) return null;
16902
+ if (overall.length > 200 && !/[.!?…"'’)\]]$/.test(overall)) return null;
16902
16903
  if (!r.verdicts || typeof r.verdicts !== "object") return null;
16903
16904
  const keys = new Set(GRADED_CRITERIA.map((c) => c.key));
16904
16905
  const criteria = (Array.isArray(r.criteria) ? r.criteria : []).map((c) => {
package/dist/web/app.js CHANGED
@@ -12939,9 +12939,13 @@ function laneFrac(name, l) {
12939
12939
  m.label = l.label;
12940
12940
  m.at = Date.now();
12941
12941
  }
12942
+ if (l.frac != null) {
12943
+ m.shown = Math.max(m.shown, Math.min(1, Math.max(0, l.frac)));
12944
+ laneMemo.set(name, m);
12945
+ return m.shown;
12946
+ }
12942
12947
  const real = l.withinFrac ?? (l.within && l.within.total ? l.within.done / l.within.total : 0);
12943
- const creep = l.i >= 1 ? 0.9 * (1 - Math.exp(-(Date.now() - m.at) / 9e4)) : 0;
12944
- const w = Math.min(Math.max(0, l.total - (l.i - 1)), Math.max(real, creep));
12948
+ const w = Math.min(Math.max(0, l.total - (l.i - 1)), real);
12945
12949
  m.shown = Math.max(m.shown, Math.min(1, Math.max(0, (l.i - 1 + w) / l.total)));
12946
12950
  laneMemo.set(name, m);
12947
12951
  return m.shown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polymath-society",
3
- "version": "0.2.26",
3
+ "version": "0.2.28",
4
4
  "description": "Deterministic metrics from your local Claude Code / Codex agent logs — parallelism, flow, throughput, projects. Zero LLM, zero server, on-device.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",