feat: round-memory ownerSealActionForContent per-stage hash helper SP3-c2a
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ import { buildArtifact } from './artifact-from-spec.mjs';
|
||||
import { parsePlanSteps } from './plan-steps-parse.mjs';
|
||||
import { parsePlanSkills } from './plan-skills.mjs';
|
||||
import { contentHash, sealOnApproval, requiresOwnerSeal } from './judge-seal-channel.mjs';
|
||||
import { freezeArtifact, freezePlan } from './plan-lock.mjs';
|
||||
import { freezeArtifact, freezePlan, planId } from './plan-lock.mjs';
|
||||
|
||||
export function sealableArtifact(md) { return buildArtifact(md); } // {sections, source_sha}
|
||||
export function sealablePlan(md) { return { steps: parsePlanSteps(md), skills: parsePlanSkills(md) }; } // {steps,skills}
|
||||
@@ -90,3 +90,16 @@ export function decideSeal({ verdict, ownerSealOpen = false, ownerSealRequired =
|
||||
if (isRealGo(verdict) && ownerSealRequired) return { seal: false, via: null, ownerRequired: true };
|
||||
return { seal: false, via: null };
|
||||
}
|
||||
|
||||
/** SP3-c: owner-seal-метка для карточки арбитража по содержимому. ТОТ ЖЕ хеш, что считает
|
||||
* sealTurnProd → подпись владельца на этой метке сматчится: план (есть steps) → planId(steps);
|
||||
* иначе спека → judgedHashOf(sealableArtifact). Тотально — null при сбое (карточка тогда без
|
||||
* точной escape-строки, владелец берёт хеш из логов). */
|
||||
export function ownerSealActionForContent(content) {
|
||||
const c = String(content == null ? '' : content);
|
||||
try {
|
||||
const steps = sealablePlan(c).steps;
|
||||
if (Array.isArray(steps) && steps.length) return ownerSealAction(planId(steps));
|
||||
} catch { /* не план — пробуем как спеку */ }
|
||||
try { return ownerSealAction(judgedHashOf(sealableArtifact(c))); } catch { return null; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { sealableArtifact, sealablePlan, judgedHashOf, sealArtifact, sealPlan, ownerSealAction, decideSeal } from './seal-orchestration.mjs';
|
||||
import { sealableArtifact, sealablePlan, judgedHashOf, sealArtifact, sealPlan, ownerSealAction, decideSeal, ownerSealActionForContent } from './seal-orchestration.mjs';
|
||||
import { contentHash } from './judge-seal-channel.mjs';
|
||||
import { planId } from './plan-lock.mjs';
|
||||
|
||||
const specMd = '## Реш {#dec-a}\nтекст';
|
||||
const planMd = '```steps-json\n[{"op":"Edit","object":"app/Foo.php","ref":"dec-a"}]\n```';
|
||||
@@ -102,3 +103,12 @@ describe('owner-seal в seal-функциях (SP3-b3)', () => {
|
||||
expect(r.ownerRequired).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ownerSealActionForContent (SP3-c)', () => {
|
||||
it('план (есть steps-json) → owner-seal:planId(steps) (как в sealTurnProd)', () => {
|
||||
expect(ownerSealActionForContent(planMd)).toBe(ownerSealAction(planId(sealablePlan(planMd).steps)));
|
||||
});
|
||||
it('спека (нет steps) → owner-seal:judgedHashOf(sealableArtifact) (как в sealTurnProd)', () => {
|
||||
expect(ownerSealActionForContent(specMd)).toBe(ownerSealAction(judgedHashOf(sealableArtifact(specMd))));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user