Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/wiki/scripts/wiki-doc.test.mjs

Raw
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";

const skill = readFileSync(new URL("../SKILL.md", import.meta.url), "utf8");
const prompt = readFileSync(new URL("../../../prompts/wiki.md", import.meta.url), "utf8");

function body(markdown) {
  const match = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(markdown);
  assert.ok(match, "YAML frontmatter must be delimited");
  assert.match(match[1], /^description: "[^\n]+"$/m);
  return match[2];
}

function section(heading) {
  const text = body(skill).split(`## ${heading}\n`)[1];
  assert.ok(text, `Missing section: ${heading}`);
  return text.split("\n## ")[0];
}

test("prompt delegates behavior without duplicating the skill", () => {
  const text = body(prompt);
  assert.match(text, /Load and follow the `wiki` skill/);
  assert.match(text, /\$ARGUMENTS/);
  assert.doesNotMatch(text, /raw-sources|SCHEMA\.md|web_fetch|git_clone_safe|\/wiki init|→/);
  assert.ok(text.trim().split("\n").length <= 8, "Keep the dispatcher thin");
});

test("skill owns routing and keeps reads separate from mutations", () => {
  assert.match(skill, /^name: wiki$/m);
  assert.match(section("Dispatch"), /plain text.*recall/i);
  assert.match(section("Dispatch"), /No args.*current focus/i);
  assert.match(section("Dispatch"), /recall.*status.*lint.*digest.*read-only/i);
  assert.match(section("Dispatch"), /Loading.*not.*permission/i);
  assert.match(section("Dispatch"), /Do not auto-ingest/i);
});

test("initialization checks precede schema reads without auto-repair", () => {
  const gate = section("Initialization gate");
  for (const state of ["absent", "partial", "initialized"]) assert.match(gate, new RegExp(state));
  for (const path of ["SCHEMA.md", "index.md", "log.md", "raw-sources/index.md"])
    assert.ok(gate.includes(path));
  assert.match(gate, /Do not use `read` as an existence check/);
  assert.match(gate, /wiki not initialized/);
  assert.match(gate, /explicit repair approval/);
  assert.match(gate, /permission.*errors.*stop/i);
});

test("capture precedes registration and session lessons preserve actual evidence", () => {
  const ingest = section("Ingest");
  assert.ok(ingest.indexOf("**Capture**") < ingest.indexOf("**Register**"));
  assert.match(ingest, /Never register a failed capture/);
  const retro = section("Retro");
  assert.match(retro, /redacted.*excerpt/i);
  assert.match(retro, /session.*entry IDs/i);
  assert.match(retro, /same capture.*register.*compile/i);
});

test("tool guidance cannot reintroduce obsolete or unbounded recipes", () => {
  assert.doesNotMatch(`${skill}\n${prompt}`, /web_fetch|curl -sL|<repo >/);
  assert.match(skill, /web.*action: fetch/);
  assert.match(skill, /current tool schema|current.*help/i);
  assert.match(skill, /redirect.*same.*checks/i);
});

test("url ingest requires approval for private/internal network targets", () => {
  assert.match(skill, /private\/internal URLs.*explicit approval/i);
  assert.match(skill, /localhost|loopback/i);
  assert.match(skill, /169\.254\.169\.254/);
});

test("file and archive ingest guard secrets and unsafe extraction", () => {
  assert.match(skill, /deny known secret paths/i);
  assert.match(skill, /zip-slip|parent paths/i);
  assert.match(skill, /file count.*total size|total size.*file count/i);
});

test("recall searches are literal and bounded", () => {
  assert.match(skill, /rg -i -F --max-filesize/);
  assert.match(skill, /-- "\$query"/);
  assert.match(skill, /--glob '!raw-sources\/\*\*' -- "\$query"/);
  assert.doesNotMatch(skill, /-- "\$query"[^\n]*--glob/);
  assert.doesNotMatch(skill, /2>\/dev\/null/);
  assert.match(section("Recall"), /output.*limit|limit.*output/i);
});

test("lint is read-only unless fix is approved", () => {
  assert.match(skill, /lint is read-only by default/i);
  assert.match(skill, /--fix/i);
});