feat(#1433): capability trust gate + upgrade/compat (ADR-1244 Phase 4) (#1449)

ADR-1244 Phase 4 (D5 trust + D6 upgrade/compat). capability-trust.cjs (disclosure/consent, strict_known_registries, engines+compatVersions, reserved namespace) + capability-lifecycle.cjs (install/upgrade/remove/reconcile; ledger-as-commit-point _pending intent; atomic stage-then-swap; surgical marker-isolated shared-edit strip; owner-token lock) + capability-source promote/skipEnginesGate seams + loader pending-skip + config keys. No sandbox re-derived (consent+integrity+reversibility). 6 Codex adversarial rounds + /security-review (no HIGH) + /code-review; gsd-test green both platforms; CI green. Phase 5 (#1434) wires the CLI dispatch.

Closes #1433.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-06-18 21:40:37 -04:00
committed by GitHub
parent 1abb0d3427
commit 9219af3360
22 changed files with 2843 additions and 14 deletions

View File

@@ -194,6 +194,33 @@ describe('local adapter — happy path', () => {
assert.strictEqual(result.stagedDir, expectedDir);
assert.ok(fs.existsSync(expectedDir));
});
test('skipEnginesGate:true stages an engines-incompatible capability without throwing', async () => {
const cap = featureCap('test-cap-local');
cap.engines = { gsd: '>=99.0.0' };
const incompatDir = makeLocalCap(cap);
// Default: the engines gate throws.
await assert.rejects(
() => resolveCapabilitySource(incompatDir, { gsdHome, hostVersion: '1.6.0' }),
/engines\.gsd/,
);
// skipEnginesGate: the resolver stages it (copy-only) and leaves the gate to the caller.
const r = await resolveCapabilitySource(incompatDir, { gsdHome, hostVersion: '1.6.0', skipEnginesGate: true, promote: false });
assert.strictEqual(r.id, 'test-cap-local');
assert.ok(fs.existsSync(path.join(r.stagedDir, 'capability.json')));
cleanup(incompatDir);
cleanup(r.stagedDir);
});
test('promote:false validates but does NOT promote — returns the staging dir, final dir absent', async () => {
const result = await resolveCapabilitySource(capDir, { gsdHome, hostVersion: '1.5.0', promote: false });
const finalDir = path.join(gsdHome, '.gsd', 'capabilities', 'test-cap-local');
const stagingRoot = path.join(gsdHome, '.gsd', 'capabilities', '.staging');
assert.notStrictEqual(result.stagedDir, finalDir, 'must not be the final dir');
assert.ok(result.stagedDir.startsWith(stagingRoot), 'staged dir is under .staging');
assert.ok(fs.existsSync(path.join(result.stagedDir, 'capability.json')), 'staged manifest present');
assert.ok(!fs.existsSync(finalDir), 'final dir must NOT be created when promote:false');
});
});
describe('local adapter — invalid manifest', () => {