feat: round-memory owner-seal decideSeal carve-out via-labels SP3-b1
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -54,11 +54,20 @@ export function ownerSealAction(hash) {
|
||||
return `owner-seal:${String(hash == null ? '' : hash)}`;
|
||||
}
|
||||
|
||||
/** Решение печати с учётом owner-seal. Реальный GO (wired && GO) → печать обычным путём.
|
||||
* Иначе ownerSealOpen (владелец подписал owner-seal на этот hash) → печать несмотря на
|
||||
* NO-GO/degraded. Ни того, ни другого → нет печати. */
|
||||
export function decideSeal({ verdict, ownerSealOpen = false } = {}) {
|
||||
if (isRealGo(verdict)) return { seal: true, via: 'wired-go' };
|
||||
if (ownerSealOpen) return { seal: true, via: 'owner-seal' };
|
||||
/** Решение печати с учётом owner-seal и carve-out §6 (деньги/тупик).
|
||||
* - Чистый GO без чувствительной темы → печать обычным путём (wired-go).
|
||||
* - Владелец подписал owner-seal:<хеш тела> → печать. Повод различаем для аудита:
|
||||
* carveout — судья дал GO, но тема денежная/тупик (§6), владелец подтвердил;
|
||||
* override — судья NO-GO/не дозвонился, владелец перевесил.
|
||||
* - GO + чувствительная тема, но владелец ещё не подписал → штатно зовём владельца
|
||||
* (ownerRequired, carve-out §6) — это ожидаемый путь, не спор.
|
||||
* - Ни GO, ни owner-seal → нет печати.
|
||||
* ownerSealRequired = requiresOwnerSeal({artifact,verdict}) — единственный детектор «тема
|
||||
* чувствительная» (не дублируется здесь). Интеграция owner-seal ↔ requiresOwnerSeal: один
|
||||
* механизм подписи owner-seal закрывает И carve-out, И override. */
|
||||
export function decideSeal({ verdict, ownerSealOpen = false, ownerSealRequired = false } = {}) {
|
||||
if (isRealGo(verdict) && !ownerSealRequired) return { seal: true, via: 'wired-go' };
|
||||
if (ownerSealOpen) return { seal: true, via: isRealGo(verdict) ? 'owner-seal-carveout' : 'owner-seal-override' };
|
||||
if (isRealGo(verdict) && ownerSealRequired) return { seal: false, via: null, ownerRequired: true };
|
||||
return { seal: false, via: null };
|
||||
}
|
||||
|
||||
@@ -52,13 +52,21 @@ describe('owner-seal (SP3)', () => {
|
||||
it('decideSeal: реальный GO → печать via wired-go', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'GO' } })).toEqual({ seal: true, via: 'wired-go' });
|
||||
});
|
||||
it('decideSeal: NO-GO + ownerSealOpen → печать via owner-seal (перевешивает)', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'NO-GO' }, ownerSealOpen: true })).toEqual({ seal: true, via: 'owner-seal' });
|
||||
it('decideSeal: NO-GO + ownerSealOpen → печать via owner-seal-override (перевешивает)', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'NO-GO' }, ownerSealOpen: true })).toEqual({ seal: true, via: 'owner-seal-override' });
|
||||
});
|
||||
it('decideSeal: NO-GO без owner-seal → нет печати', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'NO-GO' }, ownerSealOpen: false })).toEqual({ seal: false, via: null });
|
||||
});
|
||||
it('decideSeal: degraded (wired:false) + ownerSealOpen → печать via owner-seal', () => {
|
||||
expect(decideSeal({ verdict: { wired: false, decision: 'GO' }, ownerSealOpen: true })).toEqual({ seal: true, via: 'owner-seal' });
|
||||
it('decideSeal: degraded (wired:false) + ownerSealOpen → печать via owner-seal-override', () => {
|
||||
expect(decideSeal({ verdict: { wired: false, decision: 'GO' }, ownerSealOpen: true })).toEqual({ seal: true, via: 'owner-seal-override' });
|
||||
});
|
||||
it('decideSeal: GO + ownerSealRequired (деньги/тупик) без owner-seal → ownerRequired, нет печати (carve-out §6)', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'GO' }, ownerSealRequired: true }))
|
||||
.toEqual({ seal: false, via: null, ownerRequired: true });
|
||||
});
|
||||
it('decideSeal: GO + ownerSealRequired + ownerSealOpen → печать via owner-seal-carveout', () => {
|
||||
expect(decideSeal({ verdict: { wired: true, decision: 'GO' }, ownerSealRequired: true, ownerSealOpen: true }))
|
||||
.toEqual({ seal: true, via: 'owner-seal-carveout' });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user