mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-11 07:29:00 +02:00
fix: housekeeping sweep — telemetry integrity, persistent opt-out, context-bill accuracy, setup hang, dev-server discovery, model resolution (#2136 + v1.63 polish)
Seven small fixes, one theme (claims matching code): - telemetry-sync strips local-only fields with jq del() (structural) instead of quote-fragile sed regexes; unparseable lines are dropped, never forwarded unstripped. Sed survives only as a jq-less fallback. - telemetry-log rejects non-integer durations BEFORE the range caps, whose test(1) comparisons silently no-op on non-numerics — a malformed duration spliced raw text into the JSONL stream. - browse's local telemetry honors the persistent tier (config.yaml telemetry: off), not just the preamble's env hint — direct $B use and embedders now respect the opt-out. - gstack-context-bill --exact sees GSTACK_-promoted keys inside Conductor (conductor-env-shim wired at the CLI entry), and the TOTAL line no longer double-counts every nested skill through the root skill's walk (v1.63 deferred polish; the telemetry-sync HTTP-status outcome deferred alongside it turned out already shipped). - setup's Chromium probe is deadline-bounded (90s, background + poll-kill — macOS has no GNU timeout) and prefers Node for the launch probe everywhere (the bun --eval hang family behind #2136); the install is single-flight behind a lock dir with an actionable stale-lock message. Probe verified live on this Mac. - the review resolver's dev-server check reads CLAUDE.md and the plan file before falling back to an expanded port probe, and says how to make itself smarter next time. - eval/harness model IDs resolve through lib/eval-model.ts (GSTACK_EVAL_MODEL[_KIND] env overrides, per-kind defaults, tested) at the SDK-capture and PTY-warmup sites; the bash-embedded distill snippet mirrors the resolution inline. - memory-ingest's silent-zero shape (staged>0, imported+unchanged==0, errors==0) warns even under --quiet — a run that indexes nothing must never look healthy again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
56d83c684c
commit
b9cd094981
@@ -222,6 +222,20 @@ function totalMd(dir: string, tokensOf: TokensOf): { bytes: number; tokens: numb
|
||||
let bytes = 0;
|
||||
let tokens = 0;
|
||||
for (const p of walkMd(dir)) {
|
||||
// A skill dir that CONTAINS other skill dirs (the gstack root skill wraps
|
||||
// the whole tree) must not swallow its children's files: each nested
|
||||
// skill reports its own totalMd, and the grand total sums per-skill
|
||||
// figures — counting them here again double-counted every nested skill
|
||||
// in the TOTAL line (v1.63 deferred polish, fixed in fork port wave 2).
|
||||
const rel = path.relative(dir, p);
|
||||
const topSeg = rel.split(path.sep)[0];
|
||||
if (
|
||||
topSeg &&
|
||||
topSeg !== rel && // p is inside a subdirectory
|
||||
fs.existsSync(path.join(dir, topSeg, "SKILL.md"))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const b = bytesOf(p) ?? 0;
|
||||
bytes += b;
|
||||
tokens += tokensOf(p, b);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Host-neutral eval/harness model resolution (fork port wave 2, G cluster).
|
||||
*
|
||||
* Model IDs were hardcoded at six call sites across the eval helpers and the
|
||||
* distill bin, so an environment that pins a different model (CI cost
|
||||
* control, a model migration, an air-gapped proxy alias) had to patch source.
|
||||
* One resolution point, env-overridable:
|
||||
*
|
||||
* GSTACK_EVAL_MODEL_<KIND> (e.g. GSTACK_EVAL_MODEL_WARMUP) — per-kind
|
||||
* GSTACK_EVAL_MODEL — global
|
||||
* explicit argument — caller wins
|
||||
* per-kind default — last resort
|
||||
*
|
||||
* Kinds and their defaults:
|
||||
* capture — AskUserQuestion SDK capture runs (quality matters): opus
|
||||
* warmup — PTY warm-up ping (cheapest thing that answers): haiku
|
||||
* distill — free-text distillation (cheap, structured): haiku (pinned)
|
||||
*/
|
||||
|
||||
const DEFAULTS: Record<string, string> = {
|
||||
capture: "claude-opus-4-7",
|
||||
warmup: "claude-haiku-4-5",
|
||||
distill: "claude-haiku-4-5-20251001",
|
||||
};
|
||||
|
||||
export type EvalModelKind = keyof typeof DEFAULTS & string;
|
||||
|
||||
export function resolveEvalModel(
|
||||
kind: EvalModelKind,
|
||||
explicit?: string | null,
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
): string {
|
||||
if (explicit) return explicit;
|
||||
const perKind = env[`GSTACK_EVAL_MODEL_${kind.toUpperCase()}`];
|
||||
if (perKind) return perKind;
|
||||
if (env.GSTACK_EVAL_MODEL) return env.GSTACK_EVAL_MODEL;
|
||||
const fallback = DEFAULTS[kind];
|
||||
if (!fallback) throw new Error(`resolveEvalModel: unknown kind "${kind}"`);
|
||||
return fallback;
|
||||
}
|
||||
Reference in New Issue
Block a user