fix(catalog): deterministic proactive-suggestions.json (no per-run timestamp)

Original implementation wrote a generated_at timestamp on every gen-skill-docs
run. That made CI dry-run freshness checks flap because the file changed on
every regeneration even when the actual content (skill descriptions, routing
prose, voice triggers) was unchanged.

Two fixes:
1. Drop the generated_at field. The file is purely a content registry now.
2. Only write the file when serialized content actually differs from disk.

Reproducible test: bun run gen:skill-docs twice in a row now leaves
scripts/proactive-suggestions.json unchanged on the second run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan 2026-05-25 20:40:28 -07:00
parent fcd49655eb
commit 43e18af4ad
No known key found for this signature in database
GPG Key ID: C1F69E85C74EFE1D
2 changed files with 13 additions and 3 deletions

View File

@ -840,16 +840,27 @@ The orchestrator will persist the plan link to its own memory/knowledge store.
// T4 catalog trim: write aggregated proactive-suggestions.json (Claude only).
// The JSON registry lets agents pull voice triggers / routing prose for any
// skill on demand instead of paying for it always-loaded in the catalog.
//
// No timestamp field — keeps the file content-deterministic across runs so
// CI dry-run freshness checks don't flap on regen. If a per-run timestamp
// is ever needed for debugging, write it to a separate `.gen-stamp` file.
if (currentHost === 'claude' && CATALOG_MODE === 'trim' && Object.keys(proactiveAggregate).length > 0 && !DRY_RUN) {
const proactivePath = path.join(ROOT, 'scripts', 'proactive-suggestions.json');
const payload = {
$schema: 'https://gstack.dev/schemas/proactive-suggestions.json',
generated_at: new Date().toISOString(),
catalog_mode: 'trim',
note: 'Routing / voice-trigger prose extracted from SKILL.md frontmatter descriptions during catalog trim. Loaded on demand when routing guidance is needed.',
skills: proactiveAggregate,
};
fs.writeFileSync(proactivePath, JSON.stringify(payload, null, 2) + '\n');
const serialized = JSON.stringify(payload, null, 2) + '\n';
// Only write if content actually changed — prevents needless touches that
// would flap CI freshness checks. Read existing file, compare, skip write
// when identical.
let existing = '';
try { existing = fs.readFileSync(proactivePath, 'utf-8'); } catch { /* first run */ }
if (existing !== serialized) {
fs.writeFileSync(proactivePath, serialized);
}
}
// Print token budget summary

View File

@ -1,6 +1,5 @@
{
"$schema": "https://gstack.dev/schemas/proactive-suggestions.json",
"generated_at": "2026-05-26T03:40:01.996Z",
"catalog_mode": "trim",
"note": "Routing / voice-trigger prose extracted from SKILL.md frontmatter descriptions during catalog trim. Loaded on demand when routing guidance is needed.",
"skills": {