mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-09 14:38:59 +02:00
fix(gen-skill-docs): throw when a template contains {{PREAMBLE}} twice
Hardens the #2508/#2362 class: a second {{PREAMBLE}} occurrence — even a
prose mention, which is exactly how spec/SKILL.md.tmpl re-expanded the full
~12K-token preamble mid-document — now fails generation with the template
path instead of silently shipping a doubled preamble. Pure exported guard
(assertSinglePreamble) called from resolvePlaceholders, unit-tested with the
original prose-mention shape.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
ba979dbd6f
commit
480ebe4f26
@@ -668,12 +668,32 @@ function applyHostRewrites(content: string, hostConfig: HostConfig): string {
|
||||
* unresolved. Extracted so SKILL.md and section templates resolve through the
|
||||
* exact same path — a security/sanitization fix to one can't miss the other.
|
||||
*/
|
||||
/**
|
||||
* A second {{PREAMBLE}} in one template re-expands the entire ~12K-token
|
||||
* preamble mid-document (#2508/#2362 — a PROSE mention of the macro in
|
||||
* spec/SKILL.md.tmpl expanded it a second time, +43KB per /spec load).
|
||||
* Resolution is context-blind, so any second occurrence — code fence, prose,
|
||||
* anywhere — is a generation error, never intentional. Throw at render time
|
||||
* so the mistake cannot reach a generated SKILL.md again.
|
||||
*/
|
||||
export function assertSinglePreamble(tmplContent: string, relTmplPath: string): void {
|
||||
const count = (tmplContent.match(/\{\{PREAMBLE\}\}/g) || []).length;
|
||||
if (count > 1) {
|
||||
throw new Error(
|
||||
`${relTmplPath} contains {{PREAMBLE}} ${count} times — a template may reference it `
|
||||
+ `at most once (each occurrence expands the full preamble; see #2508/#2362). `
|
||||
+ `Refer to "the preamble" in prose instead of the macro.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function resolvePlaceholders(
|
||||
tmplContent: string,
|
||||
ctx: TemplateContext,
|
||||
hostConfig: HostConfig,
|
||||
relTmplPath: string,
|
||||
): string {
|
||||
assertSinglePreamble(tmplContent, relTmplPath);
|
||||
// effectiveSuppressedResolvers() honors --respect-detection: when gbrain is
|
||||
// detected locally, GBRAIN_* resolvers un-suppress. Shared by SKILL.md and
|
||||
// section generation so both paths get the same gbrain-aware behavior.
|
||||
|
||||
Reference in New Issue
Block a user