test(docsync): accept the cap gate's ~/.claude/skills/gstack form the section prints (pass 9 Red Team note)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-27 00:46:55 +00:00
1 parent 8aa3578753
commit 2549a32bad
2 files changed
+6 -4

No files matched your search

+3 -3
View File
@@ -515,13 +515,13 @@ test('Step 14.5 housekeeping commands and the docs record are declared exactly a
const skills = fixture.skills.split(path.sep).join('/');
const caps = docsCapsCommand(skills);
const interfaceText = docsNativeInterface(fixture);
for (const command of [DOCS_TMP_EXCLUDE, DOCS_AUDIT_RESET, caps]) {
expect(interfaceText).toContain(command);
for (const command of [DOCS_TMP_EXCLUDE, DOCS_AUDIT_RESET, caps, docsCapsCommand('~/.claude/skills/gstack')]) {
if (command === caps) expect(interfaceText).toContain(command);
expect(docsCommandAllowed(command, fixture)).toBe(true);
expect(docsToolFailures(nativeResult(command, 'DOCS_CAP: none declared'), fixture, [], true)).toEqual([]);
}
for (const command of [DOCS_TMP_EXCLUDE.replace("'/.gstack/tmp/'", "'/.gstack/'"), `${DOCS_TMP_EXCLUDE}; git add -A`, 'rm -f .gstack/tmp', 'rm -rf .gstack/tmp/docs-audit.json',
`${skills}/bin/gstack-ship-receipt docs-caps --base feature/docs`, `${skills}/bin/gstack-ship-receipt write --docs @${DOCS_AUDIT_RECORD}`, `${skills}/bin/gstack-ship-receipt docs-caps --base main --json`]) {
`${skills}/bin/gstack-ship-receipt docs-caps --base feature/docs`, '~/.claude/skills/other/bin/gstack-ship-receipt docs-caps --base main', `${skills}/bin/gstack-ship-receipt write --docs @${DOCS_AUDIT_RECORD}`, `${skills}/bin/gstack-ship-receipt docs-caps --base main --json`]) {
expect(docsCommandAllowed(command, fixture)).toBe(false);
}
const write = (file: string): SkillTestResult => {
+3 -1
View File
@@ -230,7 +230,9 @@ function unwrapHarmlessRead(text: string, fixture: ReturnType<typeof fixtureDocs
export function docsCommandAllowed(command: string, fixture: ReturnType<typeof fixtureDocs>, scripts: string[] = []): boolean {
const text = command.trim();
if (docsPreambleCommands(fixture).some(block => block.trim() === text)) return true;
if (text === DOCS_TMP_EXCLUDE || text === DOCS_AUDIT_RESET || text === docsCapsCommand(fixture.skills.split(path.sep).join('/'))) return true;
// The section prints the cap gate with the ~/.claude/skills/gstack prefix; in the fixture HOME is fixture.home, so that form names the same installed binary.
if (text === DOCS_TMP_EXCLUDE || text === DOCS_AUDIT_RESET || text === docsCapsCommand(fixture.skills.split(path.sep).join('/')) ||
(text === docsCapsCommand('~/.claude/skills/gstack') && fixture.skills === path.join(fixture.home, '.claude/skills/gstack'))) return true;
if (readOnlyCommandAllowed(text, docsReadOnlyScope(fixture)) || docsComposedReadAllowed(text, fixture)) return true;
const insert = /^cat (['"]?)([^\s'"]+)\1 >> (['"]?)([^\s'"]+)\3$/.exec(text);
if (insert) return [insert[2], insert[4]].every(file => path.isAbsolute(file) && /\.md$/i.test(file) &&