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.
141 lines
6.0 KiB
JavaScript
141 lines
6.0 KiB
JavaScript
/**
|
|
* Antigravity reviewer repo-grounding (#2176).
|
|
*
|
|
* The agy leg once invoked the CLI without granting it the repo under review — no `--add-dir` and
|
|
* no absolute repo-root anchor in the prompt — so the agent anchored on its own
|
|
* `~/.gemini/antigravity-cli/scratch` dir and reviewed the plan text in isolation, which is exactly
|
|
* what the Review Instructions forbid.
|
|
*
|
|
* Phase 5b (#2799) deleted that bash. Both fixes now live in the named `antigravity` handler, which
|
|
* is where they belong: "add this flag only when the binary's --help mentions it" is a conditional,
|
|
* and conditionals escape to a handler rather than accreting inside the descriptor (ADR-2782 D6).
|
|
* These tests moved with them, so this file no longer reads any source text and the source-text
|
|
* exemption it used to carry is gone.
|
|
*/
|
|
|
|
const { test, describe } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const { REVIEWER_LANES } = require('../msd-core/bin/lib/review-lane-descriptor.cjs');
|
|
const { resolveLanePlan } = require('../msd-core/bin/lib/review-lane-invocation.cjs');
|
|
const {
|
|
antigravityArgv,
|
|
antigravityPrompt,
|
|
stampBlindReview,
|
|
} = require('../msd-core/bin/lib/review-lane-runner.cjs');
|
|
|
|
const RUN = '/run';
|
|
const ROOT = '/abs/repo';
|
|
|
|
function planFor(slug) {
|
|
const lane = REVIEWER_LANES.find((l) => l.slug === slug);
|
|
const r = resolveLanePlan({ lane, configGet: () => undefined, runDir: RUN, repoRoot: ROOT });
|
|
assert.equal(r.ok, true);
|
|
return r.plan;
|
|
}
|
|
|
|
/** A spawn stub whose `--help` either advertises `--add-dir` or does not. */
|
|
const helpSaying = (text) => ({ spawn: () => ({ status: 0, stdout: text, stderr: '' }) });
|
|
|
|
describe('#2176 — agy receives the repo under review', () => {
|
|
test('--add-dir is passed with the repo root when the binary supports it', () => {
|
|
const p = planFor('antigravity');
|
|
const argv = antigravityArgv(p.argv, p.promptPath, ROOT, helpSaying('--add-dir --model'));
|
|
const i = argv.indexOf('--add-dir');
|
|
assert.ok(i !== -1, '--add-dir must be passed when supported');
|
|
assert.equal(argv[i + 1], ROOT);
|
|
});
|
|
|
|
test('--add-dir is CAPABILITY-PROBED, not assumed', () => {
|
|
// An older agy rejects an unknown flag outright. A lane that fails to start is worse than one
|
|
// running on the prompt anchor alone, so support is probed rather than presumed.
|
|
const p = planFor('antigravity');
|
|
const argv = antigravityArgv(p.argv, p.promptPath, ROOT, helpSaying('no such flag here'));
|
|
assert.ok(!argv.includes('--add-dir'));
|
|
});
|
|
|
|
test('the probe is bounded', () => {
|
|
const p = planFor('antigravity');
|
|
const calls = [];
|
|
antigravityArgv(p.argv, p.promptPath, ROOT, {
|
|
spawn: (b, a, o) => { calls.push(o); return { status: 0, stdout: '', stderr: '' }; },
|
|
});
|
|
assert.ok(calls.every((c) => c.timeoutMs > 0), 'every process-starting probe must be bounded');
|
|
});
|
|
|
|
test('adding --add-dir keeps the prompt last', () => {
|
|
const p = planFor('antigravity');
|
|
const argv = antigravityArgv(p.argv, p.promptPath, ROOT, helpSaying('--add-dir'));
|
|
assert.equal(argv[argv.length - 2], '-p');
|
|
assert.ok(argv[argv.length - 1].includes(RUN));
|
|
});
|
|
|
|
test('a probe that throws degrades to no flag rather than failing the lane', () => {
|
|
const p = planFor('antigravity');
|
|
const argv = antigravityArgv(p.argv, p.promptPath, ROOT, {
|
|
spawn: () => { throw new Error('spawn failed'); },
|
|
});
|
|
assert.ok(!argv.includes('--add-dir'));
|
|
assert.ok(argv.length > 0);
|
|
});
|
|
});
|
|
|
|
describe('#2176 — the prompt is anchored and demands a self-report', () => {
|
|
test('the prompt carries the ABSOLUTE repo root', () => {
|
|
const prompt = antigravityPrompt(`${RUN}/msd-review-prompt.md`, ROOT);
|
|
assert.ok(prompt.includes(ROOT));
|
|
});
|
|
|
|
test('the prompt mandates REVIEWED-WITHOUT-REPO-ACCESS when the repo is unreadable', () => {
|
|
// Without this clause a blind review is indistinguishable from a grounded one and its verdict
|
|
// is counted at full consensus weight.
|
|
const prompt = antigravityPrompt(`${RUN}/msd-review-prompt.md`, ROOT);
|
|
assert.ok(prompt.includes('REVIEWED-WITHOUT-REPO-ACCESS'));
|
|
});
|
|
|
|
test('the self-report variant actually reaches argv', () => {
|
|
const p = planFor('antigravity');
|
|
const argv = antigravityArgv(p.argv, p.promptPath, ROOT, helpSaying(''));
|
|
assert.ok(argv[argv.length - 1].includes('REVIEWED-WITHOUT-REPO-ACCESS'));
|
|
});
|
|
|
|
test('cursor carries the same absolute-root anchor (#2176 AC5)', () => {
|
|
// Identical gap, identical fix — cursor-agent also takes the prompt in argv and does not
|
|
// reliably inherit the review cwd.
|
|
const p = planFor('cursor');
|
|
assert.ok(p.argv[p.argv.length - 1].includes(ROOT));
|
|
});
|
|
|
|
test('kimi-code carries it too', () => {
|
|
const p = planFor('kimi-code');
|
|
assert.ok(p.argv[p.argv.length - 1].includes(ROOT));
|
|
});
|
|
});
|
|
|
|
describe('#2176 — blind-review marking', () => {
|
|
test('a self-reported blind review is stamped', () => {
|
|
const out = stampBlindReview('REVIEWED-WITHOUT-REPO-ACCESS\nthe review');
|
|
assert.ok(out.includes('[reviewed-without-repo-access]'));
|
|
});
|
|
|
|
test('a scratch-dir workspace DECLARATION is stamped', () => {
|
|
const out = stampBlindReview('my working directory is ~/.gemini/antigravity-cli/scratch, so');
|
|
assert.ok(out.includes('[reviewed-without-repo-access]'));
|
|
});
|
|
|
|
test('a grounded review that merely QUOTES the marker is not stamped', () => {
|
|
// A review OF this very file must not be mis-stamped and down-weighted.
|
|
const quoting = ['a', 'b', 'c', 'd', 'e', 'f', 'the tell is REVIEWED-WITHOUT-REPO-ACCESS'].join('\n');
|
|
assert.ok(!stampBlindReview(quoting).includes('[reviewed-without-repo-access]'));
|
|
});
|
|
|
|
test('an ordinary mention of the scratch path is not a declaration', () => {
|
|
const mention = 'the plan references .gemini/antigravity-cli/scratch as an example path';
|
|
assert.ok(!stampBlindReview(mention).includes('[reviewed-without-repo-access]'));
|
|
});
|
|
|
|
test('an empty review is left alone', () => {
|
|
assert.equal(stampBlindReview(''), '');
|
|
});
|
|
});
|