Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
205 lines
9.3 KiB
JavaScript
205 lines
9.3 KiB
JavaScript
// allow-test-rule: source-text-is-the-product (see #2641)
|
|
// The mempalace-capture skill gates on config.mempalace.capture_artifacts.
|
|
// The capability registry declares this key with default: true, so an absent
|
|
// key must be treated as enabled. The skill previously used `!== true` which
|
|
// treated absent (undefined) as disabled — inverted from the schema default.
|
|
// The fix changes it to `=== false` (disabled only on explicit false).
|
|
|
|
'use strict';
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const SKILL = path.join(__dirname, '..', 'skills', 'msd-mempalace-capture', 'SKILL.md');
|
|
const COMMAND = path.join(__dirname, '..', 'commands', 'msd', 'mempalace-capture.md');
|
|
|
|
describe('#2641 — mempalace-capture gate treats absent capture_artifacts as enabled', () => {
|
|
test('SKILL.md uses === false (disabled only on explicit false), not !== true', () => {
|
|
const text = fs.readFileSync(SKILL, 'utf8');
|
|
assert.ok(
|
|
text.includes('capture_artifacts === false'),
|
|
'SKILL.md must use capture_artifacts === false (defaults to enabled when absent, matching the schema) — not !== true (#2641)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('capture_artifacts !== true'),
|
|
'SKILL.md must NOT use the inverted capture_artifacts !== true check (#2641)',
|
|
);
|
|
});
|
|
|
|
test('commands/msd/mempalace-capture.md uses === false, not !== true', () => {
|
|
const text = fs.readFileSync(COMMAND, 'utf8');
|
|
assert.ok(
|
|
text.includes('capture_artifacts === false'),
|
|
'commands/msd/mempalace-capture.md must use capture_artifacts === false (#2641)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('capture_artifacts !== true'),
|
|
'commands/msd/mempalace-capture.md must NOT use the inverted check (#2641)',
|
|
);
|
|
});
|
|
});
|
|
|
|
// #3479 — the #2982/#2641 fix was applied to the capture_artifacts gate but not
|
|
// to the sibling gates on other mempalace sub-toggles whose registry-declared
|
|
// default is `true`. A positive-presence gate ("when `X` is true") treats an
|
|
// absent key as disabled — inverted from the registry default. Every gate on a
|
|
// default-true key must treat absent as enabled (disabled only on an explicit
|
|
// false); every gate on a default-false key must keep requiring positive
|
|
// presence. The hand-maintained commands/msd/*.md mirrors must stay in lockstep
|
|
// with their skills/*/SKILL.md originals.
|
|
|
|
const RECALL_SKILL = path.join(__dirname, '..', 'skills', 'msd-mempalace-recall', 'SKILL.md');
|
|
const RECALL_COMMAND = path.join(__dirname, '..', 'commands', 'msd', 'mempalace-recall.md');
|
|
const CURATOR = path.join(__dirname, '..', 'agents', 'msd-mempalace-curator.md');
|
|
const REGISTRY_PATH = path.join(__dirname, '..', 'msd-core', 'bin', 'lib', 'capability-registry.cjs');
|
|
|
|
/** Deep-search the mempalace capability for the flat settings schema keyed `mempalace.<key>`. */
|
|
function mempalaceSettings() {
|
|
const { capabilities } = require(REGISTRY_PATH);
|
|
const stack = [capabilities.mempalace];
|
|
while (stack.length > 0) {
|
|
const node = stack.pop();
|
|
if (!node || typeof node !== 'object') continue;
|
|
if (Object.prototype.hasOwnProperty.call(node, 'mempalace.mirror_kg')) return node;
|
|
for (const value of Object.values(node)) {
|
|
if (value && typeof value === 'object') stack.push(value);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** Boolean mempalace.<key> settings partitioned by their registry-declared default. */
|
|
function mempalaceBooleansByDefault() {
|
|
const settings = mempalaceSettings();
|
|
assert.ok(settings, 'capability registry must expose a mempalace settings schema');
|
|
const defaultTrue = [];
|
|
const defaultFalse = [];
|
|
for (const [key, spec] of Object.entries(settings)) {
|
|
if (!key.startsWith('mempalace.') || spec.type !== 'boolean') continue;
|
|
(spec.default === true ? defaultTrue : defaultFalse).push(key);
|
|
}
|
|
return { defaultTrue, defaultFalse };
|
|
}
|
|
|
|
describe('#3479 — gates on default-true mempalace keys treat an absent key as enabled', () => {
|
|
test('capture SKILL.md mirror_kg gate is disabled-only-on-explicit-false', () => {
|
|
const text = fs.readFileSync(SKILL, 'utf8');
|
|
assert.ok(
|
|
text.includes('config.mempalace.mirror_kg === false'),
|
|
'skills/msd-mempalace-capture/SKILL.md step 3 must mirror KG facts unless config.mempalace.mirror_kg === false (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('config.mempalace.mirror_kg` is true'),
|
|
'skills/msd-mempalace-capture/SKILL.md must NOT gate mirror_kg on positive presence — absent means enabled per the registry default (#3479)',
|
|
);
|
|
});
|
|
|
|
test('commands/msd/mempalace-capture.md mirror_kg gate matches the skill', () => {
|
|
const text = fs.readFileSync(COMMAND, 'utf8');
|
|
assert.ok(
|
|
text.includes('config.mempalace.mirror_kg === false'),
|
|
'commands/msd/mempalace-capture.md is a hand-maintained mirror of the skill — its mirror_kg gate needs the same fix (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('config.mempalace.mirror_kg` is true'),
|
|
'commands/msd/mempalace-capture.md must NOT gate mirror_kg on positive presence (#3479)',
|
|
);
|
|
});
|
|
|
|
test('recall SKILL.md mirror_kg gate is disabled-only-on-explicit-false', () => {
|
|
const text = fs.readFileSync(RECALL_SKILL, 'utf8');
|
|
assert.ok(
|
|
text.includes('config.mempalace.mirror_kg !== false'),
|
|
'skills/msd-mempalace-recall/SKILL.md KG-facts step must include mirror_kg unless !== false, matching its recall_on_plan gate style (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('config.mempalace.mirror_kg` is true'),
|
|
'skills/msd-mempalace-recall/SKILL.md must NOT gate mirror_kg on positive presence (#3479)',
|
|
);
|
|
});
|
|
|
|
test('commands/msd/mempalace-recall.md mirror_kg gate matches the skill', () => {
|
|
const text = fs.readFileSync(RECALL_COMMAND, 'utf8');
|
|
assert.ok(
|
|
text.includes('config.mempalace.mirror_kg !== false'),
|
|
'commands/msd/mempalace-recall.md is a hand-maintained mirror of the skill — its mirror_kg gate needs the same fix (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('config.mempalace.mirror_kg` is true'),
|
|
'commands/msd/mempalace-recall.md must NOT gate mirror_kg on positive presence (#3479)',
|
|
);
|
|
});
|
|
|
|
test('curator agent diary_journal and mirror_kg gates are disabled-only-on-explicit-false', () => {
|
|
const text = fs.readFileSync(CURATOR, 'utf8');
|
|
assert.ok(
|
|
text.includes('mempalace.diary_journal !== false'),
|
|
'agents/msd-mempalace-curator.md diary gate must run unless mempalace.diary_journal !== false (#3479)',
|
|
);
|
|
assert.ok(
|
|
text.includes('mempalace.mirror_kg !== false'),
|
|
'agents/msd-mempalace-curator.md KG-mirror gate must run unless mempalace.mirror_kg !== false (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('mempalace.diary_journal` is true'),
|
|
'agents/msd-mempalace-curator.md must NOT gate diary_journal on positive presence (#3479)',
|
|
);
|
|
assert.ok(
|
|
!text.includes('mempalace.mirror_kg` is true'),
|
|
'agents/msd-mempalace-curator.md must NOT gate mirror_kg on positive presence (#3479)',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('#3479 — registry parity guard: no default-true mempalace key is positively gated', () => {
|
|
test('every default-true mempalace boolean defaults to enabled in the registry', () => {
|
|
// Lock the declared defaults the corrected gates depend on: if one of these
|
|
// flips in the registry, the absence semantics of its prose gates must be
|
|
// re-audited — fail here so that happens consciously.
|
|
const { defaultTrue } = mempalaceBooleansByDefault();
|
|
for (const key of ['mempalace.capture_artifacts', 'mempalace.mirror_kg', 'mempalace.diary_journal']) {
|
|
assert.ok(defaultTrue.includes(key), `${key} must declare default: true in the capability registry`);
|
|
}
|
|
});
|
|
|
|
test('no gate file uses positive presence for a default-true key', () => {
|
|
const { defaultTrue } = mempalaceBooleansByDefault();
|
|
const files = [SKILL, COMMAND, RECALL_SKILL, RECALL_COMMAND, CURATOR];
|
|
for (const file of files) {
|
|
const text = fs.readFileSync(file, 'utf8');
|
|
for (const key of defaultTrue) {
|
|
for (const refix of ['config.' + key, key]) {
|
|
assert.ok(
|
|
!text.includes('`' + refix + '` is true'),
|
|
`${path.relative(process.cwd(), file)} gates \`${key}\` on positive presence, but the registry declares default: true — absent must mean enabled (#3479)`,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
test('default-false keys keep requiring positive presence (no over-correction)', () => {
|
|
const { defaultFalse } = mempalaceBooleansByDefault();
|
|
assert.ok(
|
|
defaultFalse.includes('mempalace.enabled'),
|
|
'mempalace.enabled must stay default: false — the master switch is opt-in',
|
|
);
|
|
const capture = fs.readFileSync(SKILL, 'utf8');
|
|
const curator = fs.readFileSync(CURATOR, 'utf8');
|
|
assert.ok(
|
|
capture.includes('config.mempalace.enabled !== true'),
|
|
'capture master gate must keep treating an absent mempalace.enabled as disabled (#3479)',
|
|
);
|
|
assert.ok(
|
|
curator.includes('mempalace.enabled !== true'),
|
|
'curator master gate must keep treating an absent mempalace.enabled as disabled (#3479)',
|
|
);
|
|
assert.ok(
|
|
curator.includes('mempalace.cross_project_tunnels` is true'),
|
|
'cross_project_tunnels (default: false) must keep its positive-presence gate — do not over-correct (#3479)',
|
|
);
|
|
});
|
|
});
|