feat(ms-ai-architect): Sesjon 19 — B3 merge-apply (cross-skill + taksonomi-persist) [skip-docs]
Merge-apply = den tyngste destruktive op-en: eksekver en operatør-godkjent merge_skills-entry → faktisk cross-skill skills/-mutasjon. Tre mekanismer som sanitize/retire ikke trengte: kuratert relokasjon (ikke arkiv), taksonomi-persistering, retire-av-absorbert. - taxonomy.mjs (ny persist): saveTaxonomy (atomisk .tmp+rename, speiler saveDecisions) + ren applyCategoryReassignments (repointer KUN der eier === from; absent/allerede-flyttet = no-op). Lag-0 er normalt read-only; ENESTE writer = gated merge-apply. - applyApprovedAction merge-gren (skill-ops.mjs): re-plan fersk → revalidér (kollisjon → guardrail.ok=false → abort) → flytt absorbed-refs → absorber (moveFile; flyttingen ER bevaringen set-equality beviser) → persister taksonomi-repoint fra FERSK plan (drift-sikker) → arkivér absorbed-SKILL.md FØR rmdir → flipp ledger approved→applied. Description-forsoning forblir MANUELL (planner-kontrakt: apply rører aldri absorber-SKILL.md). archiveMove→moveFile (generisk: arkiv + kuratert flytt). - CLI apply-skill-op.mjs merge <absorber> <absorbed> — lookup via actionKey (merge_skills:<sortert par>); default PREVIEW, --apply = dobbel-gate. TDD, tmpdir-fixtures: 0 ekte skills/-mutasjon. Ny test-skill-ops-merge-apply (7) + 2 taksonomi-tester; fjernet foreldet merge-throws fra S18-fila. Tester: kb-eval 78→84, kb-update 137→139; validate 239 · kb-integrity 192/192 uendret. eval --json deterministisk uendret (K10 eng+infra FAIL, øvrige PASS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ac18a76c8
commit
de3a9a483b
6 changed files with 434 additions and 55 deletions
|
|
@ -1,9 +1,9 @@
|
|||
// tests/kb-eval/test-skill-ops-apply.test.mjs
|
||||
// Spor B / B3 (Sesjon 18): the APPLY-PATH — the destructive frontier. An
|
||||
// operator-approved (status:approved) ledger entry is executed into a real
|
||||
// skills/ mutation. Single-skill ops only this session (sanitize + retire);
|
||||
// merge-apply is staged to S19 (it needs taxonomy persistence + cross-skill
|
||||
// moves). create_skill comes last.
|
||||
// skills/ mutation. This file covers the SINGLE-SKILL ops (sanitize + retire);
|
||||
// merge-apply (cross-skill, Sesjon 19) lives in test-skill-ops-merge-apply.test.mjs;
|
||||
// create_skill comes last.
|
||||
//
|
||||
// Binding contract proven here:
|
||||
// 1. revalidateApply (pure) re-checks an approved entry against a FRESH plan:
|
||||
|
|
@ -30,7 +30,6 @@ import {
|
|||
planSanitizeSkill,
|
||||
SANITIZE_OPERATION,
|
||||
RETIRE_OPERATION,
|
||||
MERGE_OPERATION,
|
||||
} from '../../scripts/kb-eval/lib/skill-ops.mjs';
|
||||
import {
|
||||
loadDecisions,
|
||||
|
|
@ -269,18 +268,3 @@ test('applyApprovedAction — a guardrail-failing approved entry never applies',
|
|||
assert.ok(existsSync(join(skillsDir, 'skill-a/references/cat1/live.md')), 'curated ref still safe');
|
||||
});
|
||||
});
|
||||
|
||||
test('applyApprovedAction — merge_skills is unsupported this session (staged to S19) and throws', () => {
|
||||
withFixture(({ root, skillsDir, agentsDir, dataDir }) => {
|
||||
const approved = {
|
||||
operation_type: MERGE_OPERATION,
|
||||
status: 'approved',
|
||||
targets: { absorber: 'skill-a', absorbed: 'skill-b' },
|
||||
guardrail: { ok: true },
|
||||
};
|
||||
assert.throws(
|
||||
() => applyApprovedAction(approved, { pluginRoot: root, skillsDir, agentsDir, dataDir, apply: true }),
|
||||
/merge|unsupported|S19/i,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue