@principles/core 1.262.0 → 1.264.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime-v2/__tests__/architecture-regression.test.js +8 -2
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.js +91 -0
- package/dist/runtime-v2/activation/__tests__/openclaw-promotion-checks.test.js.map +1 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js +83 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js.map +1 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.js +48 -0
- package/dist/runtime-v2/activation/__tests__/promotion-readiness-reader.test.js.map +1 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js +141 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js.map +1 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.js +31 -0
- package/dist/runtime-v2/activation/__tests__/rulecode-safety-circuit-breaker.test.js.map +1 -0
- package/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.d.ts +2 -0
- package/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.d.ts.map +1 -0
- package/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js +311 -0
- package/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js.map +1 -0
- package/dist/runtime-v2/activation/activation-control-types.d.ts +61 -0
- package/dist/runtime-v2/activation/activation-control-types.d.ts.map +1 -0
- package/dist/runtime-v2/activation/activation-control-types.js +2 -0
- package/dist/runtime-v2/activation/activation-control-types.js.map +1 -0
- package/dist/runtime-v2/activation/index.d.ts +14 -0
- package/dist/runtime-v2/activation/index.d.ts.map +1 -1
- package/dist/runtime-v2/activation/index.js +7 -0
- package/dist/runtime-v2/activation/index.js.map +1 -1
- package/dist/runtime-v2/activation/openclaw-promotion-checks.d.ts +30 -0
- package/dist/runtime-v2/activation/openclaw-promotion-checks.d.ts.map +1 -0
- package/dist/runtime-v2/activation/openclaw-promotion-checks.js +124 -0
- package/dist/runtime-v2/activation/openclaw-promotion-checks.js.map +1 -0
- package/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts +17 -0
- package/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts.map +1 -0
- package/dist/runtime-v2/activation/promotion-readiness-evaluator.js +55 -0
- package/dist/runtime-v2/activation/promotion-readiness-evaluator.js.map +1 -0
- package/dist/runtime-v2/activation/promotion-readiness-reader.d.ts +21 -0
- package/dist/runtime-v2/activation/promotion-readiness-reader.d.ts.map +1 -0
- package/dist/runtime-v2/activation/promotion-readiness-reader.js +44 -0
- package/dist/runtime-v2/activation/promotion-readiness-reader.js.map +1 -0
- package/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts +104 -0
- package/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts.map +1 -0
- package/dist/runtime-v2/activation/rulecode-owner-decision-service.js +86 -0
- package/dist/runtime-v2/activation/rulecode-owner-decision-service.js.map +1 -0
- package/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.d.ts +25 -0
- package/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.d.ts.map +1 -0
- package/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.js +23 -0
- package/dist/runtime-v2/activation/rulecode-safety-circuit-breaker.js.map +1 -0
- package/dist/runtime-v2/activation/rulecode-shadow-summary.d.ts +14 -0
- package/dist/runtime-v2/activation/rulecode-shadow-summary.d.ts.map +1 -0
- package/dist/runtime-v2/activation/rulecode-shadow-summary.js +57 -0
- package/dist/runtime-v2/activation/rulecode-shadow-summary.js.map +1 -0
- package/dist/runtime-v2/activation/sqlite-activation-safety-store.d.ts +40 -0
- package/dist/runtime-v2/activation/sqlite-activation-safety-store.d.ts.map +1 -0
- package/dist/runtime-v2/activation/sqlite-activation-safety-store.js +461 -0
- package/dist/runtime-v2/activation/sqlite-activation-safety-store.js.map +1 -0
- package/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
- package/dist/runtime-v2/activation/sqlite-activation-state-store.js +24 -6
- package/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
- package/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +19 -4
- package/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
- package/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
- package/dist/runtime-v2/activation/writers/rule-host-writer.js +10 -0
- package/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
- package/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +13 -0
- package/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
- package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -2
- package/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js +2 -0
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/dist/runtime-v2/index.d.ts +2 -2
- package/dist/runtime-v2/index.d.ts.map +1 -1
- package/dist/runtime-v2/index.js +1 -1
- package/dist/runtime-v2/index.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/legacy-rule-contract-scanner.test.js +20 -1
- package/dist/runtime-v2/internalization/__tests__/legacy-rule-contract-scanner.test.js.map +1 -1
- package/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts +4 -4
- package/dist/runtime-v2/internalization/legacy-rule-contract-scanner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js +92 -5
- package/dist/runtime-v2/internalization/legacy-rule-contract-scanner.js.map +1 -1
- package/dist/runtime-v2/store/sqlite-connection-schema-version.test.js +11 -11
- package/dist/runtime-v2/store/sqlite-connection-schema-version.test.js.map +1 -1
- package/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/dist/runtime-v2/store/sqlite-connection.js +111 -0
- package/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function isRecord(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); }
|
|
2
|
+
export function summarizeRuleCodeShadowEvents(entries, activationId) {
|
|
3
|
+
let observed = 0;
|
|
4
|
+
let matched = 0;
|
|
5
|
+
let wouldBlock = 0;
|
|
6
|
+
let wouldAllow = 0;
|
|
7
|
+
let requireApproval = 0;
|
|
8
|
+
let autoCorrect = 0;
|
|
9
|
+
let errors = 0;
|
|
10
|
+
let neutralControl = 0;
|
|
11
|
+
let firstObservedAt = null;
|
|
12
|
+
let lastObservedAt = null;
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
if (!isRecord(entry) || !isRecord(entry.data) || entry.data.activationId !== activationId)
|
|
15
|
+
continue;
|
|
16
|
+
if (entry.type === 'rulehost_unhealthy') {
|
|
17
|
+
errors += 1;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (entry.type !== 'rulehost_evaluated' || entry.data.activationMode !== 'shadow')
|
|
21
|
+
continue;
|
|
22
|
+
observed += 1;
|
|
23
|
+
if (entry.data.matched === true)
|
|
24
|
+
matched += 1;
|
|
25
|
+
if (entry.data.decision === 'block')
|
|
26
|
+
wouldBlock += 1;
|
|
27
|
+
if (entry.data.decision === 'allow')
|
|
28
|
+
wouldAllow += 1;
|
|
29
|
+
if (entry.data.decision === 'requireApproval')
|
|
30
|
+
requireApproval += 1;
|
|
31
|
+
if (entry.data.decision === 'auto_correct')
|
|
32
|
+
autoCorrect += 1;
|
|
33
|
+
if (entry.data.matched === false && entry.data.decision === 'allow')
|
|
34
|
+
neutralControl += 1;
|
|
35
|
+
if (entry.category === 'failure')
|
|
36
|
+
errors += 1;
|
|
37
|
+
if (typeof entry.ts === 'string' && Number.isFinite(Date.parse(entry.ts))) {
|
|
38
|
+
if (firstObservedAt === null || Date.parse(entry.ts) < Date.parse(firstObservedAt))
|
|
39
|
+
firstObservedAt = entry.ts;
|
|
40
|
+
if (lastObservedAt === null || Date.parse(entry.ts) > Date.parse(lastObservedAt))
|
|
41
|
+
lastObservedAt = entry.ts;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
observed,
|
|
46
|
+
matched,
|
|
47
|
+
wouldBlock,
|
|
48
|
+
wouldAllow,
|
|
49
|
+
requireApproval,
|
|
50
|
+
autoCorrect,
|
|
51
|
+
errors,
|
|
52
|
+
neutralControl,
|
|
53
|
+
firstObservedAt,
|
|
54
|
+
lastObservedAt,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=rulecode-shadow-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rulecode-shadow-summary.js","sourceRoot":"","sources":["../../../src/runtime-v2/activation/rulecode-shadow-summary.ts"],"names":[],"mappings":"AAYA,SAAS,QAAQ,CAAC,KAAc,IAAsC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEpJ,MAAM,UAAU,6BAA6B,CAAC,OAA2B,EAAE,YAAoB;IAC7F,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,YAAY;YAAE,SAAS;QACpG,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,QAAQ;YAAE,SAAS;QAC5F,QAAQ,IAAI,CAAC,CAAC;QACd,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,UAAU,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,UAAU,IAAI,CAAC,CAAC;QACrD,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,iBAAiB;YAAE,eAAe,IAAI,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAc;YAAE,WAAW,IAAI,CAAC,CAAC;QAC7D,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,cAAc,IAAI,CAAC,CAAC;QACzF,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,CAAC,CAAC;QAC9C,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC1E,IAAI,eAAe,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;gBAAE,eAAe,GAAG,KAAK,CAAC,EAAE,CAAC;YAC/G,IAAI,cAAc,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;gBAAE,cAAc,GAAG,KAAK,CAAC,EAAE,CAAC;QAC9G,CAAC;IACH,CAAC;IACD,OAAO;QACL,QAAQ;QACR,OAAO;QACP,UAAU;QACV,UAAU;QACV,eAAe;QACf,WAAW;QACX,MAAM;QACN,cAAc;QACd,eAAe;QACf,cAAc;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SqliteConnection } from '../store/sqlite-connection.js';
|
|
2
|
+
import type { ActivationControlState, ActivationDecisionRecord, GlobalRuleCodePause } from './activation-control-types.js';
|
|
3
|
+
import type { PromotionCommitInput } from './rulecode-owner-decision-service.js';
|
|
4
|
+
export declare class SqliteActivationSafetyStore {
|
|
5
|
+
private readonly connection;
|
|
6
|
+
constructor(connection: SqliteConnection);
|
|
7
|
+
getControlState(activationId: string): Promise<ActivationControlState | null>;
|
|
8
|
+
getActiveGlobalPause(): Promise<GlobalRuleCodePause | null>;
|
|
9
|
+
pauseAllLive(decision: ActivationDecisionRecord, pauseId: string, idempotencyKey: string): Promise<GlobalRuleCodePause>;
|
|
10
|
+
releaseGlobalPause(decision: ActivationDecisionRecord, input: {
|
|
11
|
+
pauseId: string;
|
|
12
|
+
expectedVersion: number;
|
|
13
|
+
idempotencyKey: string;
|
|
14
|
+
}): Promise<GlobalRuleCodePause>;
|
|
15
|
+
deactivateWithDecision(decision: ActivationDecisionRecord, idempotencyKey: string): Promise<{
|
|
16
|
+
activationId: string;
|
|
17
|
+
decisionId: string;
|
|
18
|
+
deactivatedAt: string;
|
|
19
|
+
}>;
|
|
20
|
+
recordOwnerDecision(decision: ActivationDecisionRecord, idempotencyKey: string): Promise<{
|
|
21
|
+
decisionId: string;
|
|
22
|
+
}>;
|
|
23
|
+
recoverToShadow(decision: ActivationDecisionRecord, input: {
|
|
24
|
+
expectedControlVersion: number;
|
|
25
|
+
newActivationId: string;
|
|
26
|
+
idempotencyKey: string;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
sourceActivationId: string;
|
|
29
|
+
shadowActivationId: string;
|
|
30
|
+
decisionId: string;
|
|
31
|
+
}>;
|
|
32
|
+
listDecisions(activationId: string): Promise<ActivationDecisionRecord[]>;
|
|
33
|
+
safetyIsolate(decision: ActivationDecisionRecord, expectedVersion: number): Promise<ActivationControlState>;
|
|
34
|
+
commitPromotion(input: PromotionCommitInput): Promise<{
|
|
35
|
+
activationId: string;
|
|
36
|
+
decisionId: string;
|
|
37
|
+
promotedAt: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=sqlite-activation-safety-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-activation-safety-store.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-activation-safety-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,sBAAsB,EAA0B,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACnJ,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAyGjF,qBAAa,2BAA2B;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAvC,YAA6B,UAAU,EAAE,gBAAgB,EAAI;IAEvD,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAMlF;IAEK,oBAAoB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAMhE;IAEK,YAAY,CAAC,QAAQ,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0B5H;IAEK,kBAAkB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkBtK;IAEK,sBAAsB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAyCrK;IAEK,mBAAmB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAsBrH;IAEK,eAAe,CAAC,QAAQ,EAAE,wBAAwB,EAAE,KAAK,EAAE;QAAE,sBAAsB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAkB7O;IAEK,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAS7E;IAEK,aAAa,CAAC,QAAQ,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA4ChH;IAEK,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAsG5H;CACF"}
|
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function requiredString(row, key) {
|
|
6
|
+
const value = Object.hasOwn(row, key) ? row[key] : undefined;
|
|
7
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
8
|
+
throw new Error(`Malformed activation safety row: ${key}`);
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function optionalString(row, key) {
|
|
12
|
+
const value = Object.hasOwn(row, key) ? row[key] : undefined;
|
|
13
|
+
if (value === null)
|
|
14
|
+
return null;
|
|
15
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
16
|
+
throw new Error(`Malformed activation safety row: ${key}`);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
function mapControl(row) {
|
|
20
|
+
if (row === undefined)
|
|
21
|
+
return null;
|
|
22
|
+
if (!isRecord(row))
|
|
23
|
+
throw new Error('Malformed activation control row');
|
|
24
|
+
const enforcement = requiredString(row, 'enforcement');
|
|
25
|
+
const version = Object.hasOwn(row, 'version') ? row.version : undefined;
|
|
26
|
+
if ((enforcement !== 'eligible' && enforcement !== 'safety_isolated') || typeof version !== 'number' || !Number.isSafeInteger(version) || version < 1) {
|
|
27
|
+
throw new Error('Malformed activation control row: enforcement or version');
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
activationId: requiredString(row, 'activation_id'),
|
|
31
|
+
enforcement,
|
|
32
|
+
isolationDecisionId: optionalString(row, 'isolation_decision_id'),
|
|
33
|
+
version,
|
|
34
|
+
updatedAt: requiredString(row, 'updated_at'),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function mapGlobalPause(row) {
|
|
38
|
+
if (row === undefined)
|
|
39
|
+
return null;
|
|
40
|
+
if (!isRecord(row))
|
|
41
|
+
throw new Error('Malformed global RuleCode pause row');
|
|
42
|
+
const status = requiredString(row, 'status');
|
|
43
|
+
const version = Object.hasOwn(row, 'version') ? row.version : undefined;
|
|
44
|
+
let affected;
|
|
45
|
+
try {
|
|
46
|
+
affected = JSON.parse(requiredString(row, 'affected_activation_ids'));
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new Error('Malformed global RuleCode pause row: affected_activation_ids');
|
|
50
|
+
}
|
|
51
|
+
if ((status !== 'paused' && status !== 'released') || typeof version !== 'number' || !Number.isSafeInteger(version) || version < 1
|
|
52
|
+
|| !Array.isArray(affected) || !affected.every(value => typeof value === 'string' && value.length > 0)) {
|
|
53
|
+
throw new Error('Malformed global RuleCode pause row: status, version, or affected ids');
|
|
54
|
+
}
|
|
55
|
+
return { pauseId: requiredString(row, 'pause_id'), status, incidentDecisionId: requiredString(row, 'incident_decision_id'),
|
|
56
|
+
releaseDecisionId: optionalString(row, 'release_decision_id'), affectedActivationIds: affected,
|
|
57
|
+
pausedAt: requiredString(row, 'paused_at'), releasedAt: optionalString(row, 'released_at'), version };
|
|
58
|
+
}
|
|
59
|
+
const DECISIONS = [
|
|
60
|
+
'continue_observing', 'promote_live', 'reject_after_shadow', 'emergency_deactivate',
|
|
61
|
+
'global_emergency_pause', 'global_emergency_pause_release', 'safety_isolate',
|
|
62
|
+
'recover_to_shadow', 'supersede',
|
|
63
|
+
];
|
|
64
|
+
function isActivationDecisionKind(value) {
|
|
65
|
+
return DECISIONS.some(candidate => candidate === value);
|
|
66
|
+
}
|
|
67
|
+
function mapDecision(row) {
|
|
68
|
+
if (!isRecord(row))
|
|
69
|
+
throw new Error('Malformed activation decision row');
|
|
70
|
+
const decision = requiredString(row, 'decision');
|
|
71
|
+
if (!isActivationDecisionKind(decision))
|
|
72
|
+
throw new Error('Malformed activation decision row: decision');
|
|
73
|
+
const principalKind = requiredString(row, 'principal_kind');
|
|
74
|
+
const authenticationMethod = requiredString(row, 'authentication_method');
|
|
75
|
+
const principal = principalKind === 'configured_owner'
|
|
76
|
+
? { kind: principalKind, ownerId: requiredString(row, 'owner_id') }
|
|
77
|
+
: principalKind === 'system_safety'
|
|
78
|
+
? { kind: principalKind, policyVersion: requiredString(row, 'policy_version') }
|
|
79
|
+
: principalKind === 'break_glass' && requiredString(row, 'break_glass_reason') === 'local_no_auth_emergency'
|
|
80
|
+
? { kind: principalKind, reason: 'local_no_auth_emergency' }
|
|
81
|
+
: null;
|
|
82
|
+
const authentication = authenticationMethod === 'console_token' || authenticationMethod === 'cli_owner_credential'
|
|
83
|
+
? { method: authenticationMethod, credentialId: requiredString(row, 'credential_id') }
|
|
84
|
+
: authenticationMethod === 'system' || authenticationMethod === 'local_break_glass'
|
|
85
|
+
? { method: authenticationMethod }
|
|
86
|
+
: null;
|
|
87
|
+
if (!principal)
|
|
88
|
+
throw new Error('Malformed activation decision row: principal');
|
|
89
|
+
if (!authentication)
|
|
90
|
+
throw new Error('Malformed activation decision row: authentication');
|
|
91
|
+
const operatorKind = optionalString(row, 'operator_kind');
|
|
92
|
+
const operatorId = optionalString(row, 'operator_id');
|
|
93
|
+
if ((operatorKind === null) !== (operatorId === null) || (operatorKind !== null && operatorKind !== 'local_user'))
|
|
94
|
+
throw new Error('Malformed activation decision row: operator');
|
|
95
|
+
return {
|
|
96
|
+
decisionId: requiredString(row, 'decision_id'),
|
|
97
|
+
subject: {
|
|
98
|
+
kind: 'activation',
|
|
99
|
+
activationId: requiredString(row, 'activation_id'),
|
|
100
|
+
artifactId: requiredString(row, 'artifact_id'),
|
|
101
|
+
artifactDigest: requiredString(row, 'artifact_digest'),
|
|
102
|
+
},
|
|
103
|
+
decision,
|
|
104
|
+
principal,
|
|
105
|
+
authentication,
|
|
106
|
+
operator: operatorId === null ? undefined : { kind: 'local_user', operatorId },
|
|
107
|
+
reasonCode: requiredString(row, 'reason_code'),
|
|
108
|
+
note: optionalString(row, 'note'),
|
|
109
|
+
evidenceSnapshotId: optionalString(row, 'evidence_snapshot_id'),
|
|
110
|
+
decidedAt: requiredString(row, 'decided_at'),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export class SqliteActivationSafetyStore {
|
|
114
|
+
connection;
|
|
115
|
+
constructor(connection) {
|
|
116
|
+
this.connection = connection;
|
|
117
|
+
}
|
|
118
|
+
async getControlState(activationId) {
|
|
119
|
+
const row = this.connection.getDb().prepare(`
|
|
120
|
+
SELECT activation_id, enforcement, isolation_decision_id, version, updated_at
|
|
121
|
+
FROM activation_control_states WHERE activation_id = ?
|
|
122
|
+
`).get(activationId);
|
|
123
|
+
return mapControl(row);
|
|
124
|
+
}
|
|
125
|
+
async getActiveGlobalPause() {
|
|
126
|
+
const row = this.connection.getDb().prepare(`
|
|
127
|
+
SELECT pause_id, status, incident_decision_id, release_decision_id, affected_activation_ids, paused_at, released_at, version
|
|
128
|
+
FROM global_rulecode_pauses WHERE status = 'paused'
|
|
129
|
+
`).get();
|
|
130
|
+
return mapGlobalPause(row);
|
|
131
|
+
}
|
|
132
|
+
async pauseAllLive(decision, pauseId, idempotencyKey) {
|
|
133
|
+
const authorized = decision.subject.kind === 'all_live_rulecode' && decision.decision === 'global_emergency_pause'
|
|
134
|
+
&& ((decision.principal.kind === 'break_glass' && decision.authentication.method === 'local_break_glass')
|
|
135
|
+
|| (decision.principal.kind === 'configured_owner' && decision.authentication.method === 'console_token'));
|
|
136
|
+
if (!authorized)
|
|
137
|
+
throw new Error('pauseAllLive requires authorized global_emergency_pause decision');
|
|
138
|
+
const db = this.connection.getDb();
|
|
139
|
+
db.exec('BEGIN IMMEDIATE');
|
|
140
|
+
try {
|
|
141
|
+
const existing = mapGlobalPause(db.prepare(`SELECT pause_id, status, incident_decision_id, release_decision_id, affected_activation_ids, paused_at, released_at, version FROM global_rulecode_pauses WHERE status = 'paused'`).get());
|
|
142
|
+
if (existing) {
|
|
143
|
+
db.exec('COMMIT');
|
|
144
|
+
return existing;
|
|
145
|
+
}
|
|
146
|
+
const rows = db.prepare(`SELECT activation_id FROM activations WHERE channel = 'code_tool_hook' AND action = 'code_tool_hook_live_activate' AND deactivated_at IS NULL ORDER BY activation_id`).all();
|
|
147
|
+
if (!Array.isArray(rows))
|
|
148
|
+
throw new Error('Malformed live activation result');
|
|
149
|
+
const affected = rows.map(row => isRecord(row) ? requiredString(row, 'activation_id') : (() => { throw new Error('Malformed live activation row'); })());
|
|
150
|
+
db.prepare(`INSERT INTO activation_decisions (decision_id, idempotency_key, subject_kind, decision, principal_kind, owner_id, policy_version, break_glass_reason, authentication_method, credential_id, operator_kind, operator_id, reason_code, note, decided_at) VALUES (?, ?, 'all_live_rulecode', 'global_emergency_pause', ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
151
|
+
.run(decision.decisionId, idempotencyKey, decision.principal.kind, decision.principal.kind === 'configured_owner' ? decision.principal.ownerId : null, decision.principal.kind === 'break_glass' ? decision.principal.reason : null, decision.authentication.method, decision.authentication.method === 'console_token' ? decision.authentication.credentialId : null, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.decidedAt);
|
|
152
|
+
db.prepare(`INSERT INTO global_rulecode_pauses (pause_id, status, incident_decision_id, release_decision_id, affected_activation_ids, paused_at, released_at, version) VALUES (?, 'paused', ?, NULL, ?, ?, NULL, 1)`)
|
|
153
|
+
.run(pauseId, decision.decisionId, JSON.stringify(affected), decision.decidedAt);
|
|
154
|
+
const result = mapGlobalPause(db.prepare(`SELECT pause_id, status, incident_decision_id, release_decision_id, affected_activation_ids, paused_at, released_at, version FROM global_rulecode_pauses WHERE pause_id = ?`).get(pauseId));
|
|
155
|
+
if (!result)
|
|
156
|
+
throw new Error('Global pause missing after insert');
|
|
157
|
+
db.exec('COMMIT');
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
try {
|
|
162
|
+
db.exec('ROLLBACK');
|
|
163
|
+
}
|
|
164
|
+
catch { /* best effort */ }
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async releaseGlobalPause(decision, input) {
|
|
169
|
+
const { pauseId, expectedVersion, idempotencyKey } = input;
|
|
170
|
+
if (decision.subject.kind !== 'all_live_rulecode' || decision.decision !== 'global_emergency_pause_release'
|
|
171
|
+
|| decision.principal.kind !== 'configured_owner' || decision.authentication.method !== 'console_token') {
|
|
172
|
+
throw new Error('releaseGlobalPause requires authenticated configured_owner release decision');
|
|
173
|
+
}
|
|
174
|
+
const db = this.connection.getDb();
|
|
175
|
+
db.exec('BEGIN IMMEDIATE');
|
|
176
|
+
try {
|
|
177
|
+
db.prepare(`INSERT INTO activation_decisions (decision_id, idempotency_key, subject_kind, decision, principal_kind, owner_id, authentication_method, credential_id, operator_kind, operator_id, reason_code, note, decided_at) VALUES (?, ?, 'all_live_rulecode', 'global_emergency_pause_release', 'configured_owner', ?, 'console_token', ?, ?, ?, ?, ?, ?)`)
|
|
178
|
+
.run(decision.decisionId, idempotencyKey, decision.principal.ownerId, decision.authentication.credentialId, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.decidedAt);
|
|
179
|
+
const update = db.prepare(`UPDATE global_rulecode_pauses SET status = 'released', release_decision_id = ?, released_at = ?, version = version + 1 WHERE pause_id = ? AND status = 'paused' AND version = ?`)
|
|
180
|
+
.run(decision.decisionId, decision.decidedAt, pauseId, expectedVersion);
|
|
181
|
+
if (update.changes !== 1)
|
|
182
|
+
throw new Error(`Global pause expected version ${expectedVersion}: ${pauseId}`);
|
|
183
|
+
const result = mapGlobalPause(db.prepare(`SELECT pause_id, status, incident_decision_id, release_decision_id, affected_activation_ids, paused_at, released_at, version FROM global_rulecode_pauses WHERE pause_id = ?`).get(pauseId));
|
|
184
|
+
if (!result)
|
|
185
|
+
throw new Error('Global pause missing after release');
|
|
186
|
+
db.exec('COMMIT');
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
try {
|
|
191
|
+
db.exec('ROLLBACK');
|
|
192
|
+
}
|
|
193
|
+
catch { /* best effort */ }
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async deactivateWithDecision(decision, idempotencyKey) {
|
|
198
|
+
if (decision.subject.kind !== 'activation')
|
|
199
|
+
throw new Error('deactivateWithDecision requires activation subject');
|
|
200
|
+
const ownerAuthenticated = decision.principal.kind === 'configured_owner'
|
|
201
|
+
&& (decision.authentication.method === 'console_token' || decision.authentication.method === 'cli_owner_credential');
|
|
202
|
+
const breakGlass = decision.principal.kind === 'break_glass' && decision.authentication.method === 'local_break_glass';
|
|
203
|
+
const authorized = decision.decision === 'reject_after_shadow' ? ownerAuthenticated
|
|
204
|
+
: decision.decision === 'emergency_deactivate' && (ownerAuthenticated || breakGlass);
|
|
205
|
+
if (!authorized)
|
|
206
|
+
throw new Error('deactivateWithDecision requires authorized rejection or emergency decision');
|
|
207
|
+
const db = this.connection.getDb();
|
|
208
|
+
db.exec('BEGIN IMMEDIATE');
|
|
209
|
+
try {
|
|
210
|
+
const rejectAfterShadow = decision.decision === 'reject_after_shadow';
|
|
211
|
+
const subjectStatement = rejectAfterShadow
|
|
212
|
+
? db.prepare(`SELECT COUNT(*) AS count FROM activations WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook' AND action = 'code_tool_hook_shadow_activate' AND deactivated_at IS NULL`)
|
|
213
|
+
: db.prepare(`SELECT COUNT(*) AS count FROM activations WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook' AND deactivated_at IS NULL`);
|
|
214
|
+
const subject = subjectStatement
|
|
215
|
+
.get(decision.subject.activationId, decision.subject.artifactId);
|
|
216
|
+
if (!isRecord(subject) || subject.count !== 1)
|
|
217
|
+
throw new Error(`Deactivation requires exactly one matching active activation: ${decision.subject.activationId}`);
|
|
218
|
+
db.prepare(`INSERT INTO activation_decisions
|
|
219
|
+
(decision_id, idempotency_key, subject_kind, activation_id, artifact_id, artifact_digest, decision,
|
|
220
|
+
principal_kind, owner_id, policy_version, break_glass_reason, authentication_method, credential_id,
|
|
221
|
+
operator_kind, operator_id, reason_code, note, evidence_snapshot_id, decided_at)
|
|
222
|
+
VALUES (?, ?, 'activation', ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
223
|
+
.run(decision.decisionId, idempotencyKey, decision.subject.activationId, decision.subject.artifactId, decision.subject.artifactDigest, decision.decision, decision.principal.kind, decision.principal.kind === 'configured_owner' ? decision.principal.ownerId : null, decision.principal.kind === 'break_glass' ? decision.principal.reason : null, decision.authentication.method, decision.authentication.method === 'console_token' || decision.authentication.method === 'cli_owner_credential'
|
|
224
|
+
? decision.authentication.credentialId : null, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.evidenceSnapshotId, decision.decidedAt);
|
|
225
|
+
const updateStatement = rejectAfterShadow
|
|
226
|
+
? db.prepare(`UPDATE activations SET deactivated_at = ? WHERE activation_id = ? AND artifact_id = ? AND action = 'code_tool_hook_shadow_activate' AND deactivated_at IS NULL`)
|
|
227
|
+
: db.prepare(`UPDATE activations SET deactivated_at = ? WHERE activation_id = ? AND artifact_id = ? AND deactivated_at IS NULL`);
|
|
228
|
+
const update = updateStatement
|
|
229
|
+
.run(decision.decidedAt, decision.subject.activationId, decision.subject.artifactId);
|
|
230
|
+
if (update.changes !== 1)
|
|
231
|
+
throw new Error('Activation state changed during atomic deactivation');
|
|
232
|
+
db.exec('COMMIT');
|
|
233
|
+
return { activationId: decision.subject.activationId, decisionId: decision.decisionId, deactivatedAt: decision.decidedAt };
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
try {
|
|
237
|
+
db.exec('ROLLBACK');
|
|
238
|
+
}
|
|
239
|
+
catch { /* best effort */ }
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async recordOwnerDecision(decision, idempotencyKey) {
|
|
244
|
+
if (decision.subject.kind !== 'activation' || decision.decision !== 'continue_observing'
|
|
245
|
+
|| decision.principal.kind !== 'configured_owner'
|
|
246
|
+
|| (decision.authentication.method !== 'console_token' && decision.authentication.method !== 'cli_owner_credential')) {
|
|
247
|
+
throw new Error('recordOwnerDecision requires authenticated configured_owner continue_observing decision');
|
|
248
|
+
}
|
|
249
|
+
const db = this.connection.getDb();
|
|
250
|
+
db.exec('BEGIN IMMEDIATE');
|
|
251
|
+
try {
|
|
252
|
+
const subject = db.prepare(`SELECT COUNT(*) AS count FROM activations WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook' AND action = 'code_tool_hook_shadow_activate' AND deactivated_at IS NULL`)
|
|
253
|
+
.get(decision.subject.activationId, decision.subject.artifactId);
|
|
254
|
+
if (!isRecord(subject) || subject.count !== 1)
|
|
255
|
+
throw new Error(`Continue observing requires exactly one active shadow activation: ${decision.subject.activationId}`);
|
|
256
|
+
db.prepare(`INSERT INTO activation_decisions
|
|
257
|
+
(decision_id, idempotency_key, subject_kind, activation_id, artifact_id, artifact_digest, decision,
|
|
258
|
+
principal_kind, owner_id, authentication_method, credential_id, operator_kind, operator_id,
|
|
259
|
+
reason_code, note, evidence_snapshot_id, decided_at)
|
|
260
|
+
VALUES (?, ?, 'activation', ?, ?, ?, 'continue_observing', 'configured_owner', ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
|
|
261
|
+
.run(decision.decisionId, idempotencyKey, decision.subject.activationId, decision.subject.artifactId, decision.subject.artifactDigest, decision.principal.ownerId, decision.authentication.method, decision.authentication.credentialId, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.evidenceSnapshotId, decision.decidedAt);
|
|
262
|
+
db.exec('COMMIT');
|
|
263
|
+
return { decisionId: decision.decisionId };
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
try {
|
|
267
|
+
db.exec('ROLLBACK');
|
|
268
|
+
}
|
|
269
|
+
catch { /* best effort */ }
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async recoverToShadow(decision, input) {
|
|
274
|
+
if (decision.subject.kind !== 'activation' || decision.decision !== 'recover_to_shadow'
|
|
275
|
+
|| decision.principal.kind !== 'configured_owner' || decision.authentication.method !== 'console_token') {
|
|
276
|
+
throw new Error('recoverToShadow requires authenticated configured_owner recovery decision');
|
|
277
|
+
}
|
|
278
|
+
const db = this.connection.getDb();
|
|
279
|
+
db.exec('BEGIN IMMEDIATE');
|
|
280
|
+
try {
|
|
281
|
+
const source = db.prepare(`SELECT artifact_id, target_ref FROM activations WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook' AND action = 'code_tool_hook_live_activate' AND deactivated_at IS NULL`).get(decision.subject.activationId, decision.subject.artifactId);
|
|
282
|
+
if (!isRecord(source) || requiredString(source, 'artifact_id') !== decision.subject.artifactId)
|
|
283
|
+
throw new Error(`Recovery requires one isolated live activation: ${decision.subject.activationId}`);
|
|
284
|
+
const control = db.prepare(`SELECT enforcement, version FROM activation_control_states WHERE activation_id = ?`).get(decision.subject.activationId);
|
|
285
|
+
if (!isRecord(control) || control.enforcement !== 'safety_isolated' || control.version !== input.expectedControlVersion)
|
|
286
|
+
throw new Error(`Recovery expected isolated control version ${input.expectedControlVersion}`);
|
|
287
|
+
db.prepare(`INSERT INTO activation_decisions (decision_id, idempotency_key, subject_kind, activation_id, artifact_id, artifact_digest, decision, principal_kind, owner_id, authentication_method, credential_id, reason_code, note, evidence_snapshot_id, decided_at) VALUES (?, ?, 'activation', ?, ?, ?, 'recover_to_shadow', 'configured_owner', ?, 'console_token', ?, ?, ?, ?, ?)`)
|
|
288
|
+
.run(decision.decisionId, input.idempotencyKey, decision.subject.activationId, decision.subject.artifactId, decision.subject.artifactDigest, decision.principal.ownerId, decision.authentication.credentialId, decision.reasonCode, decision.note, decision.evidenceSnapshotId, decision.decidedAt);
|
|
289
|
+
db.prepare(`INSERT INTO activations (activation_id, idempotency_key, artifact_id, channel, action, target_ref, activated_at, promoted_at, deactivated_at) VALUES (?, ?, ?, 'code_tool_hook', 'code_tool_hook_shadow_activate', ?, ?, NULL, NULL)`)
|
|
290
|
+
.run(input.newActivationId, `recovery:${decision.subject.activationId}:${input.idempotencyKey}`, decision.subject.artifactId, requiredString(source, 'target_ref'), decision.decidedAt);
|
|
291
|
+
db.prepare(`INSERT INTO activation_control_states (activation_id, enforcement, isolation_decision_id, version, updated_at) VALUES (?, 'eligible', NULL, 1, ?)`).run(input.newActivationId, decision.decidedAt);
|
|
292
|
+
db.exec('COMMIT');
|
|
293
|
+
return { sourceActivationId: decision.subject.activationId, shadowActivationId: input.newActivationId, decisionId: decision.decisionId };
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
try {
|
|
297
|
+
db.exec('ROLLBACK');
|
|
298
|
+
}
|
|
299
|
+
catch { /* best effort */ }
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async listDecisions(activationId) {
|
|
304
|
+
const rows = this.connection.getDb().prepare(`
|
|
305
|
+
SELECT decision_id, activation_id, artifact_id, artifact_digest, decision, principal_kind,
|
|
306
|
+
owner_id, policy_version, break_glass_reason, authentication_method, credential_id,
|
|
307
|
+
operator_kind, operator_id, reason_code, note, evidence_snapshot_id, decided_at
|
|
308
|
+
FROM activation_decisions WHERE activation_id = ? ORDER BY decided_at, decision_id
|
|
309
|
+
`).all(activationId);
|
|
310
|
+
if (!Array.isArray(rows))
|
|
311
|
+
throw new Error('Malformed activation decision result');
|
|
312
|
+
return rows.map(mapDecision);
|
|
313
|
+
}
|
|
314
|
+
async safetyIsolate(decision, expectedVersion) {
|
|
315
|
+
if (decision.decision !== 'safety_isolate' || decision.principal.kind !== 'system_safety' || decision.authentication.method !== 'system' || decision.subject.kind !== 'activation') {
|
|
316
|
+
throw new Error('safetyIsolate requires a system_safety/system safety_isolate activation decision');
|
|
317
|
+
}
|
|
318
|
+
const db = this.connection.getDb();
|
|
319
|
+
db.exec('BEGIN IMMEDIATE');
|
|
320
|
+
try {
|
|
321
|
+
const subjectRow = db.prepare(`
|
|
322
|
+
SELECT COUNT(*) AS count FROM activations
|
|
323
|
+
WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook' AND deactivated_at IS NULL
|
|
324
|
+
`).get(decision.subject.activationId, decision.subject.artifactId);
|
|
325
|
+
if (!isRecord(subjectRow) || typeof subjectRow.count !== 'number' || subjectRow.count !== 1) {
|
|
326
|
+
throw new Error(`Safety isolation subject mismatch or duplicate activation: ${decision.subject.activationId}`);
|
|
327
|
+
}
|
|
328
|
+
db.prepare(`
|
|
329
|
+
INSERT INTO activation_decisions
|
|
330
|
+
(decision_id, subject_kind, activation_id, artifact_id, artifact_digest, decision, principal_kind,
|
|
331
|
+
owner_id, policy_version, break_glass_reason, authentication_method, credential_id,
|
|
332
|
+
operator_kind, operator_id, reason_code, note, evidence_snapshot_id, decided_at)
|
|
333
|
+
VALUES (?, 'activation', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
334
|
+
`).run(decision.decisionId, decision.subject.activationId, decision.subject.artifactId, decision.subject.artifactDigest, decision.decision, decision.principal.kind, null, decision.principal.policyVersion, null, decision.authentication.method, null, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.evidenceSnapshotId, decision.decidedAt);
|
|
335
|
+
const result = db.prepare(`
|
|
336
|
+
UPDATE activation_control_states
|
|
337
|
+
SET enforcement = 'safety_isolated', isolation_decision_id = ?, version = version + 1, updated_at = ?
|
|
338
|
+
WHERE activation_id = ? AND version = ?
|
|
339
|
+
`).run(decision.decisionId, decision.decidedAt, decision.subject.activationId, expectedVersion);
|
|
340
|
+
if (result.changes !== 1)
|
|
341
|
+
throw new Error(`Safety isolation expected version ${expectedVersion} for activation ${decision.subject.activationId}`);
|
|
342
|
+
const state = mapControl(db.prepare(`
|
|
343
|
+
SELECT activation_id, enforcement, isolation_decision_id, version, updated_at
|
|
344
|
+
FROM activation_control_states WHERE activation_id = ?
|
|
345
|
+
`).get(decision.subject.activationId));
|
|
346
|
+
if (!state)
|
|
347
|
+
throw new Error(`Safety isolation control state missing for activation ${decision.subject.activationId}`);
|
|
348
|
+
db.exec('COMMIT');
|
|
349
|
+
return state;
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
try {
|
|
353
|
+
db.exec('ROLLBACK');
|
|
354
|
+
}
|
|
355
|
+
catch { /* best effort */ }
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
async commitPromotion(input) {
|
|
360
|
+
const { decision, evidenceSnapshot } = input;
|
|
361
|
+
if (decision.decision !== 'promote_live' || decision.subject.kind !== 'activation'
|
|
362
|
+
|| decision.principal.kind !== 'configured_owner'
|
|
363
|
+
|| (decision.authentication.method !== 'console_token' && decision.authentication.method !== 'cli_owner_credential')) {
|
|
364
|
+
throw new Error('commitPromotion requires an authenticated configured_owner promote_live decision');
|
|
365
|
+
}
|
|
366
|
+
if (decision.evidenceSnapshotId !== evidenceSnapshot.snapshotId
|
|
367
|
+
|| input.evidenceSnapshotDigest !== evidenceSnapshot.snapshotDigest
|
|
368
|
+
|| decision.subject.artifactDigest !== evidenceSnapshot.artifactDigest) {
|
|
369
|
+
throw new Error('Promotion evidence binding mismatch');
|
|
370
|
+
}
|
|
371
|
+
if (!Array.isArray(evidenceSnapshot.lineageRefs) || !evidenceSnapshot.lineageRefs.every(value => typeof value === 'string' && value.length > 0)
|
|
372
|
+
|| !Array.isArray(evidenceSnapshot.safetyGateResults)
|
|
373
|
+
|| !evidenceSnapshot.safetyGateResults.every(value => value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
374
|
+
&& typeof value.checkId === 'string' && (value.status === 'passed' || value.status === 'failed'))) {
|
|
375
|
+
throw new Error('Promotion evidence snapshot is malformed');
|
|
376
|
+
}
|
|
377
|
+
const db = this.connection.getDb();
|
|
378
|
+
db.exec('BEGIN IMMEDIATE');
|
|
379
|
+
try {
|
|
380
|
+
const replay = db.prepare(`
|
|
381
|
+
SELECT decision_id, activation_id, decided_at FROM activation_decisions WHERE idempotency_key = ?
|
|
382
|
+
`).get(input.idempotencyKey);
|
|
383
|
+
if (replay !== undefined) {
|
|
384
|
+
if (!isRecord(replay))
|
|
385
|
+
throw new Error('Malformed promotion idempotency row');
|
|
386
|
+
const activationId = requiredString(replay, 'activation_id');
|
|
387
|
+
if (activationId !== decision.subject.activationId)
|
|
388
|
+
throw new Error('Promotion idempotency key subject mismatch');
|
|
389
|
+
db.exec('COMMIT');
|
|
390
|
+
return { activationId, decisionId: requiredString(replay, 'decision_id'), promotedAt: requiredString(replay, 'decided_at') };
|
|
391
|
+
}
|
|
392
|
+
const subject = db.prepare(`
|
|
393
|
+
SELECT COUNT(*) AS count FROM activations
|
|
394
|
+
WHERE activation_id = ? AND artifact_id = ? AND channel = 'code_tool_hook'
|
|
395
|
+
AND action = 'code_tool_hook_shadow_activate' AND deactivated_at IS NULL
|
|
396
|
+
`).get(decision.subject.activationId, decision.subject.artifactId);
|
|
397
|
+
if (!isRecord(subject) || subject.count !== 1)
|
|
398
|
+
throw new Error(`Promotion requires exactly one active shadow activation: ${decision.subject.activationId}`);
|
|
399
|
+
const control = db.prepare(`
|
|
400
|
+
SELECT enforcement, version FROM activation_control_states WHERE activation_id = ?
|
|
401
|
+
`).get(decision.subject.activationId);
|
|
402
|
+
if (!isRecord(control) || control.enforcement !== 'eligible' || control.version !== input.expectedControlVersion) {
|
|
403
|
+
throw new Error(`Promotion expected control version ${input.expectedControlVersion} in eligible state for activation ${decision.subject.activationId}`);
|
|
404
|
+
}
|
|
405
|
+
db.prepare(`
|
|
406
|
+
INSERT INTO activation_evidence_snapshots
|
|
407
|
+
(snapshot_id, snapshot_digest, artifact_digest, lineage_refs, host_runtime_version,
|
|
408
|
+
safety_gate_results, shadow_summary, configuration_version, redaction_metadata, created_at)
|
|
409
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
410
|
+
`).run(evidenceSnapshot.snapshotId, evidenceSnapshot.snapshotDigest, evidenceSnapshot.artifactDigest, JSON.stringify(evidenceSnapshot.lineageRefs), evidenceSnapshot.hostRuntimeVersion, JSON.stringify(evidenceSnapshot.safetyGateResults), JSON.stringify(evidenceSnapshot.shadowSummary), evidenceSnapshot.configurationVersion, JSON.stringify(evidenceSnapshot.redaction), evidenceSnapshot.createdAt);
|
|
411
|
+
db.prepare(`
|
|
412
|
+
INSERT INTO activation_decisions
|
|
413
|
+
(decision_id, idempotency_key, subject_kind, activation_id, artifact_id, artifact_digest, decision,
|
|
414
|
+
principal_kind, owner_id, policy_version, break_glass_reason, authentication_method, credential_id,
|
|
415
|
+
operator_kind, operator_id, reason_code, note, evidence_snapshot_id, readiness_evaluation_id,
|
|
416
|
+
evidence_snapshot_digest, decided_at)
|
|
417
|
+
VALUES (?, ?, 'activation', ?, ?, ?, 'promote_live', 'configured_owner', ?, NULL, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
418
|
+
`).run(decision.decisionId, input.idempotencyKey, decision.subject.activationId, decision.subject.artifactId, decision.subject.artifactDigest, decision.principal.ownerId, decision.authentication.method, decision.authentication.credentialId, decision.operator?.kind ?? null, decision.operator?.operatorId ?? null, decision.reasonCode, decision.note, decision.evidenceSnapshotId, input.readinessEvaluationId, input.evidenceSnapshotDigest, decision.decidedAt);
|
|
419
|
+
const newPrinciple = db.prepare(`SELECT COALESCE(source_principle_id, json_extract(content_json, '$.principleId'), json_extract(content_json, '$.sourcePrincipleId')) AS principle_id FROM pi_artifacts WHERE artifact_id = ?`).get(decision.subject.artifactId);
|
|
420
|
+
const principleId = isRecord(newPrinciple) && (typeof newPrinciple.principle_id === 'string' ? newPrinciple.principle_id : null);
|
|
421
|
+
if (principleId) {
|
|
422
|
+
const oldRows = db.prepare(`SELECT a.activation_id, a.artifact_id, p.artifact_kind, p.source_task_id, p.source_principle_id, p.source_rule_id, p.lineage_artifact_ids, p.validation_status, p.content_json, p.created_at, p.updated_at FROM activations a JOIN pi_artifacts p ON p.artifact_id = a.artifact_id WHERE a.channel = 'code_tool_hook' AND a.action = 'code_tool_hook_live_activate' AND a.deactivated_at IS NULL AND a.activation_id <> ? AND COALESCE(p.source_principle_id, json_extract(p.content_json, '$.principleId'), json_extract(p.content_json, '$.sourcePrincipleId')) = ?`).all(decision.subject.activationId, principleId);
|
|
423
|
+
if (!Array.isArray(oldRows) || oldRows.length > 1)
|
|
424
|
+
throw new Error(`Promotion replacement requires at most one prior live RuleCode for Principle ${principleId}`);
|
|
425
|
+
for (const old of oldRows) {
|
|
426
|
+
if (!isRecord(old))
|
|
427
|
+
throw new Error('Malformed prior live RuleCode row');
|
|
428
|
+
const lineage = JSON.parse(requiredString(old, 'lineage_artifact_ids'));
|
|
429
|
+
if (!Array.isArray(lineage) || !lineage.every(value => typeof value === 'string'))
|
|
430
|
+
throw new Error('Malformed prior artifact lineage');
|
|
431
|
+
const oldArtifact = { artifactId: requiredString(old, 'artifact_id'), artifactKind: requiredString(old, 'artifact_kind'), sourceTaskId: requiredString(old, 'source_task_id'), ...(optionalString(old, 'source_principle_id') ? { sourcePrincipleId: optionalString(old, 'source_principle_id') } : {}), ...(optionalString(old, 'source_rule_id') ? { sourceRuleId: optionalString(old, 'source_rule_id') } : {}), lineageArtifactIds: lineage, validationStatus: requiredString(old, 'validation_status'), contentJson: requiredString(old, 'content_json'), createdAt: requiredString(old, 'created_at'), updatedAt: requiredString(old, 'updated_at') };
|
|
432
|
+
const oldActivationId = requiredString(old, 'activation_id');
|
|
433
|
+
const oldArtifactDigest = `sha256:${createHash('sha256').update(JSON.stringify(oldArtifact), 'utf8').digest('hex')}`;
|
|
434
|
+
db.prepare(`INSERT INTO activation_decisions (decision_id, subject_kind, activation_id, artifact_id, artifact_digest, decision, principal_kind, owner_id, authentication_method, credential_id, reason_code, note, evidence_snapshot_id, decided_at) VALUES (?, 'activation', ?, ?, ?, 'supersede', 'configured_owner', ?, ?, ?, 'new_rulecode_version_promoted', ?, NULL, ?)`)
|
|
435
|
+
.run(`${decision.decisionId}:supersede:${oldActivationId}`, oldActivationId, oldArtifact.artifactId, oldArtifactDigest, decision.principal.ownerId, decision.authentication.method, decision.authentication.credentialId, `Superseded by ${decision.subject.activationId}.`, decision.decidedAt);
|
|
436
|
+
db.prepare(`UPDATE activations SET deactivated_at = ? WHERE activation_id = ? AND deactivated_at IS NULL`).run(decision.decidedAt, oldActivationId);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const activationResult = db.prepare(`
|
|
440
|
+
UPDATE activations SET action = 'code_tool_hook_live_activate', promoted_at = ?
|
|
441
|
+
WHERE activation_id = ? AND artifact_id = ? AND action = 'code_tool_hook_shadow_activate' AND deactivated_at IS NULL
|
|
442
|
+
`).run(decision.decidedAt, decision.subject.activationId, decision.subject.artifactId);
|
|
443
|
+
const controlResult = db.prepare(`
|
|
444
|
+
UPDATE activation_control_states SET version = version + 1, updated_at = ?
|
|
445
|
+
WHERE activation_id = ? AND enforcement = 'eligible' AND version = ?
|
|
446
|
+
`).run(decision.decidedAt, decision.subject.activationId, input.expectedControlVersion);
|
|
447
|
+
if (activationResult.changes !== 1 || controlResult.changes !== 1)
|
|
448
|
+
throw new Error('Promotion state changed during atomic commit');
|
|
449
|
+
db.exec('COMMIT');
|
|
450
|
+
return { activationId: decision.subject.activationId, decisionId: decision.decisionId, promotedAt: decision.decidedAt };
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
try {
|
|
454
|
+
db.exec('ROLLBACK');
|
|
455
|
+
}
|
|
456
|
+
catch { /* best effort */ }
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=sqlite-activation-safety-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-activation-safety-store.js","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-activation-safety-store.ts"],"names":[],"mappings":"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"}
|