Merge origin/main (v1.92.20.0) into the seed-ceiling splits (rule 19 grant 2, GSTA-36)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-11-01 08:17:43 +00:00
commit 4de074cdc9
258 files changed
+15205 -1607

No files matched your search

+5 -2
View File
@@ -10,6 +10,8 @@ export type CsoRuntimeBuildStack = typeof CSO_RUNTIME_STACKS[number];
const IMAGE = /^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9][a-z0-9._/-]*@sha256:[a-f0-9]{64}$/;
const TAGGED_IMAGE = /^[a-z0-9.-]+(?::[0-9]+)?\/[a-z0-9][a-z0-9._/-]*:[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
const RELEASE_TAG = /:v?\d+\.\d+\.\d+(?:[._-][A-Za-z0-9._-]*)?$/;
const TWO_PART_RELEASE_TAG = /:v?\d+\.\d+(?:\.\d+)?(?:[._-][A-Za-z0-9._-]*)?$/;
const REVISION = /^[a-z0-9][a-z0-9._-]{0,100}$/;
const REQUIRED_VERSIONS: Record<CsoRuntimeBuildStack, string[]> = {
node: ['node', 'npm', 'cso-preparation'],
@@ -56,8 +58,9 @@ function repositoryOfTag(image: string): string {
return image.slice(0, colon);
}
function assertPinnedFamily(source: unknown, indexImage: unknown, images: unknown, label: string): Record<CsoRuntimeBuildPlatform, string> {
function assertPinnedFamily(source: unknown, indexImage: unknown, images: unknown, label: string, releaseTag = RELEASE_TAG): Record<CsoRuntimeBuildPlatform, string> {
if (typeof source !== 'string' || !TAGGED_IMAGE.test(source)) throw new Error(`INVALID_${label}_SOURCE`);
if (!releaseTag.test(source)) throw new Error(`FLOATING_${label}_SOURCE: ${source} must name an exact release version, not a moving major, minor or alias tag`);
if (typeof indexImage !== 'string' || !IMAGE.test(indexImage)) throw new Error(`UNPINNED_${label}_INDEX`);
if (!record(images)) throw new Error(`MISSING_${label}_IMAGES`);
const repository = repositoryOfTag(source);
@@ -101,7 +104,7 @@ export function imageBuildMatrix(input: unknown): { include: ImageBuildRow[] } {
if (typeof stack !== 'string' || !CSO_RUNTIME_STACKS.includes(stack as CsoRuntimeBuildStack) || seenStacks.has(stack)) throw new Error('INVALID_STACK');
seenStacks.add(stack);
const typedStack = stack as CsoRuntimeBuildStack;
const bases = assertPinnedFamily(source, indexImage, baseImages, 'BASE');
const bases = assertPinnedFamily(source, indexImage, baseImages, 'BASE', typedStack === 'postgresql' ? TWO_PART_RELEASE_TAG : RELEASE_TAG);
if (!record(versions)) throw new Error('MISSING_TOOL_VERSIONS');
const exactVersion = (value: unknown) => typeof value === 'string' &&
(typedStack === 'postgresql'
+10 -3
View File
@@ -322,9 +322,16 @@ function flag(args: string[], name: string): string | undefined {
return index >= 0 ? args[index + 1] : undefined;
}
async function main(args: string[]): Promise<void> {
/** The W2 per-judge table plus the arm benchmark's paired judge (run by --config only; the manifest prices the W2 table). */
export async function loadCalibrationConfigs(): Promise<{ w2: CalibrationConfig[]; all: CalibrationConfig[] }> {
// The per-judge table (builders, schemas, verdict rules) is committed separately from this harness.
const { CALIBRATION_CONFIGS } = await import(path.join(import.meta.dir, 'judge-calibration-configs.ts')) as { CALIBRATION_CONFIGS: CalibrationConfig[] };
const { ARM_PAIR_CALIBRATION } = await import(path.join(import.meta.dir, '..', 'test', 'helpers', 'arm-pair-judge.ts')) as { ARM_PAIR_CALIBRATION: CalibrationConfig };
return { w2: CALIBRATION_CONFIGS, all: [...CALIBRATION_CONFIGS, ARM_PAIR_CALIBRATION] };
}
async function main(args: string[]): Promise<void> {
const { w2: CALIBRATION_CONFIGS, all: configs } = await loadCalibrationConfigs();
const command = args[0];
if (command === 'manifest') {
const client = new Anthropic();
@@ -338,8 +345,8 @@ async function main(args: string[]): Promise<void> {
console.table(manifest.entries);
return;
}
const config = CALIBRATION_CONFIGS.find(candidate => candidate.id === flag(args, 'config'));
if (!config) throw new Error(`unknown --config; expected one of ${CALIBRATION_CONFIGS.map(candidate => candidate.id).join(', ')}`);
const config = configs.find(candidate => candidate.id === flag(args, 'config'));
if (!config) throw new Error(`unknown --config; expected one of ${configs.map(candidate => candidate.id).join(', ')}`);
const items = loadCorpus(config.id);
const runsDir = path.join(CORPUS_ROOT, config.id, 'runs');
const samplesPath = path.join(runsDir, 'comparison-1.samples.jsonl');
+8
View File
@@ -364,6 +364,10 @@ export const KNOWN_WINDOWS_INCOMPATIBLE: Array<{ file: string; reason: string }>
file: 'test/ship-queue-train-ops.test.ts',
reason: 'drives bin/gstack-ship-queue (screen verdicts, scratch-merge screens, prune --stale, watch, forget, verify --post-merge, ready --dispatch-ci, --stack-tests) against the same #!/bin/sh gh shim in test/helpers/ship-queue-train-fixture.ts',
},
{
file: 'test/ship-queue-train-generic.test.ts',
reason: 'drives bin/gstack-ship-queue train build, verdict, land, watch, init and doctor against the same #!/bin/sh gh shim plus an extensionless node gh wrapper on a colon-joined PATH; on windows-latest spawnSync(\'gh\') resolves the runner\'s gh.exe instead (windows-free-shard 1, run 41218228855)',
},
{
file: 'test/ship-policy-compat.test.ts',
reason: 'spawns bin/gstack-ship-policy, bin/gstack-restamp and bin/gstack-tree-receipt (shebangs) through test/helpers/restamp-fixture.ts',
@@ -380,6 +384,10 @@ export const KNOWN_WINDOWS_INCOMPATIBLE: Array<{ file: string; reason: string }>
file: 'test/ship-release.test.ts',
reason: 'spawns bin/gstack-ship-release (shebang) directly and writes #!/bin/sh gh stubs through test/helpers/ship-bin-fixture.ts; windows-latest exits before the bin runs (windows-free-shard 3, run 41073592483)',
},
{
file: 'test/ship-rereview-triggers.test.ts',
reason: 'drives bin/gstack-ship-release, gstack-docs-candidate and gstack-wtree (shebangs) through test/helpers/ship-bin-fixture.ts like test/ship-release.test.ts; windows-latest fails every bin case at the first spawn (windows-free-shard 6, run 41193336209)',
},
];
// Force-include overrides: files a WINDOWS_FRAGILE_PATTERNS regex excludes for
+5 -1
View File
@@ -216,7 +216,11 @@
"test/skill-e2e-triage.test.ts": 1000,
"test/skill-e2e-workflow.test.ts": 121594,
"test/skill-llm-eval.test.ts": 339704,
"test/skill-routing-e2e.test.ts": 81360
"test/skill-routing-e2e.test.ts": 81360,
"test/skill-e2e-planning-wave.test.ts#planning-wave-planted-facts": 74000,
"test/skill-e2e-planning-wave.test.ts#planning-wave-schema": 52000,
"test/skill-e2e-planning-wave.test.ts#planning-wave-tasks-rerun": 37000,
"test/skill-e2e-planning-wave.test.ts#planning-wave-closing-signals": 27000
}
}
}
+1 -1
View File
@@ -89,7 +89,7 @@ export const SELECTION_DATA_MODULES: readonly string[] = [
// The build entry list: every compiled binary, which skills reach through their `--outfile` path instead.
'scripts/build.sh',
// The reason-code table: its `fix:` prose names the command a person reruns, not a file the module consumes.
'lib/result-codes.ts', 'lib/result-codes-release.ts', 'lib/result-codes-capy.ts', 'lib/result-codes-budget.ts', 'lib/result-codes-eval.ts',
'lib/result-codes.ts', 'lib/result-codes-release.ts', 'lib/result-codes-capy.ts', 'lib/result-codes-budget.ts', 'lib/result-codes-eval.ts', 'lib/result-codes-plan.ts',
// The exercised-path map: observed commands per case, read only by exercisedConsumers() (shadow data; a change selects no paid case).
'test/helpers/exercised-commands.json',
];
+3 -4
View File
@@ -593,11 +593,10 @@ Show the screenshot to the user. Ask: "Does this feel right? Want to iterate on
If they want changes, regenerate the HTML with their feedback and re-render.
If they approve or say "good enough," proceed.
**Step 5: Include in design doc**
**Step 5: Save the sketch**
Reference the wireframe screenshot in the design doc's "Recommended Approach" section.
The screenshot file at \`<sketch-dir>/sketch.png\` (name the full path in the doc) can be referenced by downstream skills
(\`/plan-design-review\`, \`/design-review\`) to see what was originally envisioned.
Copy the temporary \`sketch.png\` and \`sketch.html\` to \`<PROJECT_DIR>/{user}-{branch}-sketch-{datetime}.*\`.
In "Recommended Approach" add \`Wireframe: projects/<slug>/<png name>\` (state-root relative), or \`Wireframe: none (<reason>)\`.
**Step 6: Outside design voices** (optional)
+6 -40
View File
@@ -32,6 +32,10 @@ empty JSONL files array. Each task needs a concrete verification step.` : `Befor
build-actionable tasks. Each task derives from a specific finding — no padding.`}
${conditionalWrites ? `Always emit the markdown section. Write its JSONL artifact for \`/autoplan\` only when the ${storagePolicy} permits it; otherwise label the complete task output not persisted and do not claim an aggregation artifact exists.` : 'Emit the markdown section AND write a JSONL artifact that `/autoplan` can\naggregate across phases.'}
### Earlier lists on this branch
Before listing tasks, run \`~/.claude/skills/gstack/bin/gstack-tasks prior --phase ${phase}\` and reconcile what it prints, so a rerun never leaves two lists.
### Markdown section (always emit)
\`\`\`markdown
@@ -54,49 +58,11 @@ Rules:
### JSONL artifact (${conditionalWrites ? 'write when permitted, including zero tasks' : 'always write, even if zero tasks'})
\`/autoplan\` reads this file to aggregate across phases. Build each line with
\`jq -nc\` so titles and source findings containing quotes, newlines, or
backslashes serialize cleanly — never use hand-rolled \`echo\` / \`printf\`.
\`/autoplan\` aggregates this list. With your file-write tool, write one JSON object per line to \`.gstack/tmp/tasks-${phase}-rows.jsonl\` at the repo root (no free text in a command; no rows, no file): a task is \`{"id":"T1","priority":"P1","component":"","title":"","source_finding":"","effort_human":"~2h","effort_cc":"~15min","files":[]}\`, plus \`"carried_from":"<run_id>/<id>"\` when carried; a closed earlier task is \`{"prior":"<run_id>/<id>","disposition":"done|dropped","reason":""}\`. Then write the list (empty means "ran, no findings", distinct from "didn't run"):
\`\`\`bash
GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ROOT); : "\${GSTACK_STATE_ROOT:?gstack-paths failed; reinstall with ./setup or /gstack-upgrade}"
SLUG=$(~/.claude/skills/gstack/bin/gstack-slug --get SLUG 2>/dev/null)
TASKS_DIR="$GSTACK_STATE_ROOT/projects/\${SLUG:-unknown}"
mkdir -p "$TASKS_DIR"
TASKS_FILE="$TASKS_DIR/tasks-${phase}-$(date +%Y%m%d-%H%M%S).jsonl"
COMMIT=$(git rev-parse HEAD 2>/dev/null || echo unknown)
# The task record keeps the raw git branch; artifact filenames keep gstack-slug's sanitized BRANCH.
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo unknown)
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-$$"
# Repeat ONE jq invocation per task identified during this review.
# Substitute the placeholders inline with shell variables you set per task:
# TASK_ID (T1, T2, ...), PRIORITY (P1/P2/P3), COMPONENT, TITLE,
# SOURCE_FINDING, EFFORT_HUMAN, EFFORT_CC, FILES_JSON (a JSON array literal
# like '["browse/src/sanitize.ts","browse/src/server.ts"]').
jq -nc \\
--arg phase '${phase}' \\
--arg run_id "$RUN_ID" \\
--arg branch "$GIT_BRANCH" \\
--arg commit "$COMMIT" \\
--arg id "$TASK_ID" \\
--arg priority "$PRIORITY" \\
--arg component "$COMPONENT" \\
--arg effort_human "$EFFORT_HUMAN" \\
--arg effort_cc "$EFFORT_CC" \\
--arg title "$TITLE" \\
--arg source_finding "$SOURCE_FINDING" \\
--argjson files "$FILES_JSON" \\
'{phase:$phase, run_id:$run_id, branch:$branch, commit:$commit, id:$id, priority:$priority, component:$component, files:$files, effort_human:$effort_human, effort_cc:$effort_cc, title:$title, source_finding:$source_finding}' \\
>> "$TASKS_FILE"
~/.claude/skills/gstack/bin/gstack-tasks add --phase ${phase}
\`\`\`
If \`jq\` is not installed, fall back to skipping the JSONL write and warn
the user to install jq for autoplan aggregation. Never hand-roll JSONL.
${conditionalWrites ? 'When writes are permitted and zero tasks were identified, touch the JSONL file' : 'If zero tasks were identified in this review, still touch the JSONL file'}
(\`: > "$TASKS_FILE"\`) so the aggregator sees that the phase produced output
this run (an empty file means "ran, no findings" — distinct from "didn't run").
`;
};