chore: address Copilot review round 1
- skill-manifest: the closing `---` fence must occupy a whole line. `---oops` was accepted as a terminator, silently truncating the frontmatter and passing validation — the exact failure the guard exists to catch. Regression cases added (prefix, trailing whitespace, EOF, CRLF). - skill-eval: reject a nonzero `claude -p` exit instead of resolving it as an empty observation. An auth error or rate limit was scoring as "no skill invoked", which passes every negative case and reads as a trigger miss on every positive one. - skill-eval: extract `collectSkillInvocations` / `sampleHit` behind a `main()` guard and cover them in `skill-eval.test.mjs` — the stream parsing and the process-outcome handling are unreachable from an eval run's happy path. - docs/test-servers: annotate the era on every catalogue row. Six legacy rows carried no annotation under a "unless noted, Modern" default, so the doc sent readers to the wrong era for the feature they were trying to see. - docs/quality-gate: `validate` runs four guards, not three; add the `verify:skills` row and the two new `test:scripts` suites; fix the `#publishing` fragment left dangling by the split. - issue-create / pr-flow: delegate the card steps to `/board-ops` rather than restating its option IDs, which are explicitly unstable. - issue-triage: the audit counted presence, not cardinality — an issue carrying both `v1` and `v2` passed a check that claims "exactly one". Same for the five type labels. Also scope the two milestone checks to board #28. - AGENTS.md: codify the v1 milestone exception. Every milestone is a v2 release bucket, so a v1 issue has none to take and the Incoming-milestone invariant cannot apply to board #11. - clients/launcher/README: its pointer promised an explanation of why the cli/tui manifests ship, which the extracted guide does not make. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
73447c72d1
commit
a51e62dfa1
2 changed files with 248 additions and 83 deletions
|
|
@ -49,12 +49,15 @@ export function splitFrontmatter(text) {
|
|||
};
|
||||
}
|
||||
const rest = text.slice(FRONTMATTER_FENCE.length + 1);
|
||||
const end = rest.indexOf("\n" + FRONTMATTER_FENCE);
|
||||
if (end === -1)
|
||||
// The closing fence must occupy the WHOLE line. Matching a mere prefix would
|
||||
// accept `---oops` as a terminator, silently truncating the frontmatter to
|
||||
// whatever preceded it — the very failure this function exists to catch.
|
||||
const close = /\n---[ \t]*(\r?\n|$)/.exec(rest);
|
||||
if (close === null)
|
||||
return { error: "frontmatter is never closed by a `---` line" };
|
||||
return {
|
||||
frontmatter: rest.slice(0, end),
|
||||
body: rest.slice(end + FRONTMATTER_FENCE.length + 2),
|
||||
frontmatter: rest.slice(0, close.index),
|
||||
body: rest.slice(close.index + close[0].length),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,25 @@ test("splitFrontmatter requires the fence on the very first line", () => {
|
|||
assert.equal(splitFrontmatter(fm("name: x")).error, undefined);
|
||||
});
|
||||
|
||||
test("splitFrontmatter requires the closing fence to be a whole line", () => {
|
||||
// `---oops` is not a terminator. Accepting it would silently truncate the
|
||||
// frontmatter to whatever preceded it and report the file as valid.
|
||||
assert.match(
|
||||
splitFrontmatter("---\nname: x\n---oops\nbody\n").error ?? "",
|
||||
/never closed/,
|
||||
);
|
||||
// Trailing whitespace on the fence is still a fence, and so is EOF.
|
||||
assert.equal(
|
||||
splitFrontmatter("---\nname: x\n--- \nbody\n").frontmatter,
|
||||
"name: x",
|
||||
);
|
||||
assert.equal(splitFrontmatter("---\nname: x\n---").frontmatter, "name: x");
|
||||
assert.equal(
|
||||
splitFrontmatter("---\nname: x\n---\r\nbody").frontmatter,
|
||||
"name: x",
|
||||
);
|
||||
});
|
||||
|
||||
test("splitFrontmatter reports an unterminated block", () => {
|
||||
assert.match(splitFrontmatter("---\nname: x\n").error ?? "", /never closed/);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue