create-principles-disciple 1.75.0 → 1.77.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/core/dist/runtime-v2/__tests__/architecture-regression.test.js +3 -2
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js +328 -0
- package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/index.d.ts +0 -2
- package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/index.js +0 -1
- package/core/dist/runtime-v2/activation/index.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +6 -4
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +4 -2
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +3 -24
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +0 -10
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/workspace-guidance-migration.d.ts +12 -0
- package/core/dist/runtime-v2/workspace-guidance-migration.d.ts.map +1 -0
- package/core/dist/runtime-v2/workspace-guidance-migration.js +193 -0
- package/core/dist/runtime-v2/workspace-guidance-migration.js.map +1 -0
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +0 -1
- package/dist/utils/env.js.map +1 -1
- package/package.json +1 -1
- package/plugin/dist/core/event-log.d.ts +1 -3
- package/plugin/dist/core/event-log.js +0 -6
- package/plugin/dist/core/migration.js +0 -1
- package/plugin/dist/core/path-resolver.js +0 -1
- package/plugin/dist/core/paths.d.ts +0 -1
- package/plugin/dist/core/paths.js +0 -1
- package/plugin/dist/core/workspace-guidance-migrator.d.ts +12 -0
- package/plugin/dist/core/workspace-guidance-migrator.js +141 -0
- package/plugin/dist/hooks/gate-block-helper.js +17 -20
- package/plugin/dist/hooks/gate.js +12 -58
- package/plugin/dist/hooks/prompt.d.ts +6 -0
- package/plugin/dist/hooks/prompt.js +1 -56
- package/plugin/dist/index.js +8 -12
- package/plugin/dist/types/event-types.d.ts +1 -1
- package/plugin/dist/utils/io.d.ts +0 -1
- package/plugin/dist/utils/io.js +0 -23
- package/plugin/templates/langs/en/core/AGENTS.md +5 -5
- package/plugin/templates/langs/en/core/BOOTSTRAP.md +1 -1
- package/plugin/templates/langs/en/principles/THINKING_OS.md +4 -3
- package/plugin/templates/langs/en/skills/admin/SKILL.md +2 -2
- package/plugin/templates/langs/en/skills/evolve-task/SKILL.md +2 -2
- package/plugin/templates/langs/en/skills/pd-grooming/SKILL.md +1 -1
- package/plugin/templates/langs/en/skills/pd-mentor/SKILL.md +1 -2
- package/plugin/templates/langs/en/skills/reflection/SKILL.md +2 -2
- package/plugin/templates/langs/en/skills/report/SKILL.md +1 -1
- package/plugin/templates/langs/zh/core/AGENTS.md +5 -5
- package/plugin/templates/langs/zh/core/BOOTSTRAP.md +1 -1
- package/plugin/templates/langs/zh/principles/THINKING_OS.md +4 -3
- package/plugin/templates/langs/zh/skills/admin/SKILL.md +2 -2
- package/plugin/templates/langs/zh/skills/evolve-task/SKILL.md +2 -2
- package/plugin/templates/langs/zh/skills/pd-grooming/SKILL.md +1 -1
- package/plugin/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -2
- package/plugin/templates/langs/zh/skills/reflection/SKILL.md +2 -2
- package/plugin/templates/langs/zh/skills/report/SKILL.md +1 -1
- package/plugin/templates/workspace/.principles/THINKING_OS.md +4 -3
- package/templates/langs/en/core/AGENTS.md +7 -7
- package/templates/langs/en/core/BOOTSTRAP.md +1 -1
- package/templates/langs/en/principles/THINKING_OS.md +4 -3
- package/templates/langs/en/skills/admin/SKILL.md +2 -2
- package/templates/langs/en/skills/evolve-task/SKILL.md +3 -3
- package/templates/langs/en/skills/pd-grooming/SKILL.md +1 -1
- package/templates/langs/en/skills/pd-mentor/SKILL.md +1 -2
- package/templates/langs/en/skills/reflection/SKILL.md +2 -2
- package/templates/langs/en/skills/report/SKILL.md +1 -1
- package/templates/langs/zh/core/AGENTS.md +7 -7
- package/templates/langs/zh/core/BOOTSTRAP.md +1 -1
- package/templates/langs/zh/principles/THINKING_OS.md +4 -3
- package/templates/langs/zh/skills/admin/SKILL.md +2 -2
- package/templates/langs/zh/skills/evolve-task/SKILL.md +4 -4
- package/templates/langs/zh/skills/pd-grooming/SKILL.md +1 -1
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -2
- package/templates/langs/zh/skills/reflection/SKILL.md +2 -2
- package/templates/langs/zh/skills/report/SKILL.md +1 -1
- package/templates/workspace/.principles/THINKING_OS.md +3 -2
- package/core/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.d.ts +0 -2
- package/core/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.d.ts.map +0 -1
- package/core/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.js +0 -148
- package/core/dist/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.js.map +0 -1
- package/core/dist/runtime-v2/activation/sqlite-confirm-first-state-store.d.ts +0 -22
- package/core/dist/runtime-v2/activation/sqlite-confirm-first-state-store.d.ts.map +0 -1
- package/core/dist/runtime-v2/activation/sqlite-confirm-first-state-store.js +0 -136
- package/core/dist/runtime-v2/activation/sqlite-confirm-first-state-store.js.map +0 -1
- package/plugin/dist/core/confirm-first-gate.d.ts +0 -59
- package/plugin/dist/core/confirm-first-gate.js +0 -215
- package/plugin/templates/langs/en/skills/plan-script/SKILL.md +0 -32
- package/plugin/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
- package/plugin/templates/workspace/PLAN.md +0 -2
- package/templates/langs/en/skills/plan-script/SKILL.md +0 -32
- package/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
- package/templates/workspace/PLAN.md +0 -2
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import * as os from 'os';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as fs from 'fs';
|
|
5
|
-
import { SqliteConfirmFirstStateStore } from '../activation/sqlite-confirm-first-state-store.js';
|
|
6
|
-
import { SqliteConnection } from '../store/sqlite-connection.js';
|
|
7
|
-
describe('SqliteConfirmFirstStateStore', () => {
|
|
8
|
-
let tmpDir = '';
|
|
9
|
-
let connection = null;
|
|
10
|
-
let store = null;
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-cf-test-'));
|
|
13
|
-
connection = new SqliteConnection(tmpDir);
|
|
14
|
-
store = new SqliteConfirmFirstStateStore(connection);
|
|
15
|
-
});
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
connection.close();
|
|
18
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
19
|
-
});
|
|
20
|
-
it('upsertDirective insert: inserts a new directive and getState returns correct record', () => {
|
|
21
|
-
store.upsertDirective('sess-1', true, 'principle-abc');
|
|
22
|
-
const record = store.getState('sess-1');
|
|
23
|
-
expect(record).not.toBeNull();
|
|
24
|
-
if (record) {
|
|
25
|
-
expect(record.sessionId).toBe('sess-1');
|
|
26
|
-
expect(record.directiveActive).toBe(true);
|
|
27
|
-
expect(record.directivePrincipleId).toBe('principle-abc');
|
|
28
|
-
expect(record.directiveSetAt).toBeTruthy();
|
|
29
|
-
expect(record.lastSeenAt).toBeTruthy();
|
|
30
|
-
expect(record.approvalActive).toBe(false);
|
|
31
|
-
expect(record.approvalSetAt).toBeNull();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
it('upsertDirective update: updates directive while preserving approval fields', () => {
|
|
35
|
-
store.upsertDirective('sess-2', true, 'p-old');
|
|
36
|
-
store.upsertApproval('sess-2');
|
|
37
|
-
store.upsertDirective('sess-2', false, 'p-new');
|
|
38
|
-
const record = store.getState('sess-2');
|
|
39
|
-
expect(record).not.toBeNull();
|
|
40
|
-
if (record) {
|
|
41
|
-
expect(record.directiveActive).toBe(false);
|
|
42
|
-
expect(record.directivePrincipleId).toBe('p-new');
|
|
43
|
-
expect(record.approvalActive).toBe(true);
|
|
44
|
-
expect(record.approvalSetAt).not.toBeNull();
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
it('upsertApproval on existing row: sets approval fields on a row with prior directive', () => {
|
|
48
|
-
store.upsertDirective('sess-3', true, 'p-1');
|
|
49
|
-
store.upsertApproval('sess-3');
|
|
50
|
-
const record = store.getState('sess-3');
|
|
51
|
-
expect(record).not.toBeNull();
|
|
52
|
-
if (record) {
|
|
53
|
-
expect(record.directiveActive).toBe(true);
|
|
54
|
-
expect(record.directivePrincipleId).toBe('p-1');
|
|
55
|
-
expect(record.approvalActive).toBe(true);
|
|
56
|
-
expect(record.approvalSetAt).not.toBeNull();
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
it('upsertApproval on non-existent row: creates row with directive_active=0', () => {
|
|
60
|
-
store.upsertApproval('sess-4');
|
|
61
|
-
const db = connection.getDb();
|
|
62
|
-
const row = db.prepare('SELECT session_id, directive_active, approval_active FROM confirm_first_state WHERE session_id = ?').get('sess-4');
|
|
63
|
-
expect(row).toBeDefined();
|
|
64
|
-
if (row) {
|
|
65
|
-
expect(row.session_id).toBe('sess-4');
|
|
66
|
-
expect(row.directive_active).toBe(0);
|
|
67
|
-
expect(row.approval_active).toBe(1);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
it('getState returns null for missing session', () => {
|
|
71
|
-
const result = store.getState('nonexistent');
|
|
72
|
-
expect(result).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
it('deleteState: removes a specific session record', () => {
|
|
75
|
-
store.upsertDirective('sess-5', true, 'p-del');
|
|
76
|
-
store.deleteState('sess-5');
|
|
77
|
-
expect(store.getState('sess-5')).toBeNull();
|
|
78
|
-
});
|
|
79
|
-
it('deleteAllState: removes all session records', () => {
|
|
80
|
-
store.upsertDirective('sess-a', true, 'p-a');
|
|
81
|
-
store.upsertDirective('sess-b', true, 'p-b');
|
|
82
|
-
store.upsertDirective('sess-c', true, 'p-c');
|
|
83
|
-
store.deleteAllState();
|
|
84
|
-
expect(store.getAllState()).toEqual([]);
|
|
85
|
-
});
|
|
86
|
-
it('pruneStaleRows with old rows: deletes rows older than 30 days', () => {
|
|
87
|
-
const db = connection.getDb();
|
|
88
|
-
const oldDate = '2020-01-01T00:00:00Z';
|
|
89
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run('old-sess-1', oldDate, oldDate);
|
|
90
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run('old-sess-2', oldDate, oldDate);
|
|
91
|
-
store.upsertDirective('fresh-sess', true, 'p-fresh');
|
|
92
|
-
const pruned = store.pruneStaleRows();
|
|
93
|
-
expect(pruned).toBe(2);
|
|
94
|
-
expect(store.getState('old-sess-1')).toBeNull();
|
|
95
|
-
expect(store.getState('old-sess-2')).toBeNull();
|
|
96
|
-
expect(store.getState('fresh-sess')).not.toBeNull();
|
|
97
|
-
});
|
|
98
|
-
it('pruneStaleRows with > 500 rows: evicts oldest rows keeping only 500', () => {
|
|
99
|
-
const db = connection.getDb();
|
|
100
|
-
for (let i = 0; i < 502; i++) {
|
|
101
|
-
const id = `sess-${String(i).padStart(4, '0')}`;
|
|
102
|
-
db.prepare(`INSERT INTO confirm_first_state (session_id, directive_active, directive_set_at, last_seen_at) VALUES (?, 1, ?, ?)`).run(id, '2026-05-30T00:00:00Z', '2026-05-30T00:00:00Z');
|
|
103
|
-
}
|
|
104
|
-
const pruned = store.pruneStaleRows();
|
|
105
|
-
expect(pruned).toBe(2);
|
|
106
|
-
const all = store.getAllState();
|
|
107
|
-
expect(all).toHaveLength(500);
|
|
108
|
-
expect(store.getState('sess-0000')).toBeNull();
|
|
109
|
-
expect(store.getState('sess-0001')).toBeNull();
|
|
110
|
-
expect(store.getState('sess-0002')).not.toBeNull();
|
|
111
|
-
});
|
|
112
|
-
it('concurrent upsertApproval: calling upsertApproval twice for same session yields single coherent row', () => {
|
|
113
|
-
store.upsertApproval('sess-dup');
|
|
114
|
-
store.upsertApproval('sess-dup');
|
|
115
|
-
const db = connection.getDb();
|
|
116
|
-
const rows = db.prepare('SELECT session_id, approval_active, approval_set_at FROM confirm_first_state WHERE session_id = ?').all('sess-dup');
|
|
117
|
-
expect(rows).toHaveLength(1);
|
|
118
|
-
const [firstRow] = rows;
|
|
119
|
-
if (firstRow) {
|
|
120
|
-
expect(firstRow.session_id).toBe('sess-dup');
|
|
121
|
-
expect(firstRow.approval_active).toBe(1);
|
|
122
|
-
expect(firstRow.approval_set_at).toBeTruthy();
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
it('fresh workspace: getState returns null without error on a new connection', () => {
|
|
126
|
-
const freshTmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-cf-fresh-'));
|
|
127
|
-
try {
|
|
128
|
-
const freshConn = new SqliteConnection(freshTmpDir);
|
|
129
|
-
const freshStore = new SqliteConfirmFirstStateStore(freshConn);
|
|
130
|
-
const result = freshStore.getState('no-such-session');
|
|
131
|
-
expect(result).toBeNull();
|
|
132
|
-
freshConn.close();
|
|
133
|
-
}
|
|
134
|
-
finally {
|
|
135
|
-
fs.rmSync(freshTmpDir, { recursive: true, force: true });
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
it('getAllState: returns all inserted records', () => {
|
|
139
|
-
store.upsertDirective('sess-g1', true, 'p-g1');
|
|
140
|
-
store.upsertDirective('sess-g2', false, 'p-g2');
|
|
141
|
-
store.upsertDirective('sess-g3', true, 'p-g3');
|
|
142
|
-
const all = store.getAllState();
|
|
143
|
-
expect(all).toHaveLength(3);
|
|
144
|
-
const ids = all.map(r => r.sessionId).sort();
|
|
145
|
-
expect(ids).toEqual(['sess-g1', 'sess-g2', 'sess-g3']);
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/sqlite-confirm-first-state-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { SqliteConnection } from '../store/sqlite-connection.js';
|
|
2
|
-
export interface ConfirmFirstStateRecord {
|
|
3
|
-
sessionId: string;
|
|
4
|
-
directiveActive: boolean;
|
|
5
|
-
directivePrincipleId: string | null;
|
|
6
|
-
directiveSetAt: string;
|
|
7
|
-
approvalActive: boolean;
|
|
8
|
-
approvalSetAt: string | null;
|
|
9
|
-
lastSeenAt: string;
|
|
10
|
-
}
|
|
11
|
-
export declare class SqliteConfirmFirstStateStore {
|
|
12
|
-
private readonly connection;
|
|
13
|
-
constructor(connection: SqliteConnection);
|
|
14
|
-
upsertDirective(sessionId: string, active: boolean, principleId?: string | null): void;
|
|
15
|
-
upsertApproval(sessionId: string): void;
|
|
16
|
-
getState(sessionId: string): ConfirmFirstStateRecord | null;
|
|
17
|
-
deleteState(sessionId: string): void;
|
|
18
|
-
deleteAllState(): void;
|
|
19
|
-
pruneStaleRows(): number;
|
|
20
|
-
getAllState(): ConfirmFirstStateRecord[];
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-confirm-first-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAwCD,qBAAa,4BAA4B;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,gBAAgB;IAEzD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IActF,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAavC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,uBAAuB,GAAG,IAAI;IAgB3D,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKpC,cAAc,IAAI,IAAI;IAKtB,cAAc,IAAI,MAAM;IA2BxB,WAAW,IAAI,uBAAuB,EAAE;CAsBzC"}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
const MAX_SESSION_ENTRIES = 500;
|
|
2
|
-
const STALE_ROW_DAYS = 30;
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
5
|
-
}
|
|
6
|
-
function readStringField(row, key) {
|
|
7
|
-
if (!Object.hasOwn(row, key))
|
|
8
|
-
return null;
|
|
9
|
-
const val = row[key];
|
|
10
|
-
return typeof val === 'string' && val.length > 0 ? val : null;
|
|
11
|
-
}
|
|
12
|
-
function mapRowToRecord(row) {
|
|
13
|
-
if (!isRecord(row))
|
|
14
|
-
return null;
|
|
15
|
-
const sessionId = readStringField(row, 'session_id');
|
|
16
|
-
const directiveSetAt = readStringField(row, 'directive_set_at');
|
|
17
|
-
const lastSeenAt = readStringField(row, 'last_seen_at');
|
|
18
|
-
if (!sessionId || !directiveSetAt || !lastSeenAt)
|
|
19
|
-
return null;
|
|
20
|
-
const directiveActive = row.directive_active === 1;
|
|
21
|
-
const directivePrincipleId = readStringField(row, 'directive_principle_id');
|
|
22
|
-
const approvalActive = row.approval_active === 1;
|
|
23
|
-
const approvalSetAt = readStringField(row, 'approval_set_at');
|
|
24
|
-
return {
|
|
25
|
-
sessionId,
|
|
26
|
-
directiveActive,
|
|
27
|
-
directivePrincipleId,
|
|
28
|
-
directiveSetAt,
|
|
29
|
-
approvalActive,
|
|
30
|
-
approvalSetAt,
|
|
31
|
-
lastSeenAt,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export class SqliteConfirmFirstStateStore {
|
|
35
|
-
connection;
|
|
36
|
-
constructor(connection) {
|
|
37
|
-
this.connection = connection;
|
|
38
|
-
}
|
|
39
|
-
upsertDirective(sessionId, active, principleId) {
|
|
40
|
-
const db = this.connection.getDb();
|
|
41
|
-
const now = new Date().toISOString();
|
|
42
|
-
db.prepare(`
|
|
43
|
-
INSERT INTO confirm_first_state (session_id, directive_active, directive_principle_id, directive_set_at, last_seen_at)
|
|
44
|
-
VALUES (?, ?, ?, ?, ?)
|
|
45
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
46
|
-
directive_active=excluded.directive_active,
|
|
47
|
-
directive_principle_id=excluded.directive_principle_id,
|
|
48
|
-
directive_set_at=excluded.directive_set_at,
|
|
49
|
-
last_seen_at=excluded.last_seen_at
|
|
50
|
-
`).run(sessionId, active ? 1 : 0, principleId ?? null, now, now);
|
|
51
|
-
}
|
|
52
|
-
upsertApproval(sessionId) {
|
|
53
|
-
const db = this.connection.getDb();
|
|
54
|
-
const now = new Date().toISOString();
|
|
55
|
-
db.prepare(`
|
|
56
|
-
INSERT INTO confirm_first_state (session_id, approval_active, approval_set_at, last_seen_at, directive_active, directive_set_at)
|
|
57
|
-
VALUES (?, 1, ?, ?, 0, '')
|
|
58
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
59
|
-
approval_active=1,
|
|
60
|
-
approval_set_at=excluded.approval_set_at,
|
|
61
|
-
last_seen_at=excluded.last_seen_at
|
|
62
|
-
`).run(sessionId, now, now);
|
|
63
|
-
}
|
|
64
|
-
getState(sessionId) {
|
|
65
|
-
try {
|
|
66
|
-
const db = this.connection.getDb();
|
|
67
|
-
const row = db.prepare(`
|
|
68
|
-
SELECT session_id, directive_active, directive_principle_id, directive_set_at,
|
|
69
|
-
approval_active, approval_set_at, last_seen_at
|
|
70
|
-
FROM confirm_first_state
|
|
71
|
-
WHERE session_id = ?
|
|
72
|
-
`).get(sessionId);
|
|
73
|
-
return mapRowToRecord(row);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
if (err instanceof Error && err.message.includes('no such table'))
|
|
77
|
-
return null;
|
|
78
|
-
throw err;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
deleteState(sessionId) {
|
|
82
|
-
const db = this.connection.getDb();
|
|
83
|
-
db.prepare('DELETE FROM confirm_first_state WHERE session_id = ?').run(sessionId);
|
|
84
|
-
}
|
|
85
|
-
deleteAllState() {
|
|
86
|
-
const db = this.connection.getDb();
|
|
87
|
-
db.prepare('DELETE FROM confirm_first_state').run();
|
|
88
|
-
}
|
|
89
|
-
pruneStaleRows() {
|
|
90
|
-
const db = this.connection.getDb();
|
|
91
|
-
const staleResult = db.prepare(`DELETE FROM confirm_first_state WHERE datetime(last_seen_at) < datetime('now', '-${STALE_ROW_DAYS} days')`).run();
|
|
92
|
-
let pruned = staleResult.changes;
|
|
93
|
-
const countRow = db.prepare('SELECT COUNT(*) as cnt FROM confirm_first_state').get();
|
|
94
|
-
if (isRecord(countRow) && Object.hasOwn(countRow, 'cnt')) {
|
|
95
|
-
const total = Number(countRow.cnt);
|
|
96
|
-
if (total > MAX_SESSION_ENTRIES) {
|
|
97
|
-
const excess = total - MAX_SESSION_ENTRIES;
|
|
98
|
-
const excessResult = db.prepare(`
|
|
99
|
-
DELETE FROM confirm_first_state
|
|
100
|
-
WHERE session_id IN (
|
|
101
|
-
SELECT session_id FROM confirm_first_state
|
|
102
|
-
ORDER BY last_seen_at ASC
|
|
103
|
-
LIMIT ?
|
|
104
|
-
)
|
|
105
|
-
`).run(excess);
|
|
106
|
-
pruned += excessResult.changes;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return pruned;
|
|
110
|
-
}
|
|
111
|
-
getAllState() {
|
|
112
|
-
try {
|
|
113
|
-
const db = this.connection.getDb();
|
|
114
|
-
const rows = db.prepare(`
|
|
115
|
-
SELECT session_id, directive_active, directive_principle_id, directive_set_at,
|
|
116
|
-
approval_active, approval_set_at, last_seen_at
|
|
117
|
-
FROM confirm_first_state
|
|
118
|
-
`).all();
|
|
119
|
-
if (!Array.isArray(rows))
|
|
120
|
-
return [];
|
|
121
|
-
const result = [];
|
|
122
|
-
for (const row of rows) {
|
|
123
|
-
const record = mapRowToRecord(row);
|
|
124
|
-
if (record)
|
|
125
|
-
result.push(record);
|
|
126
|
-
}
|
|
127
|
-
return result;
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
if (err instanceof Error && err.message.includes('no such table'))
|
|
131
|
-
return [];
|
|
132
|
-
throw err;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=sqlite-confirm-first-state-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-confirm-first-state-store.js","sourceRoot":"","sources":["../../../src/runtime-v2/activation/sqlite-confirm-first-state-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Confirm-First Gate
|
|
3
|
-
*
|
|
4
|
-
* Hard enforcement for confirm-first Runtime V2 prompt activations.
|
|
5
|
-
* When an owner-approved activation requires confirmation before coding,
|
|
6
|
-
* this gate blocks mutating tools until the session has explicit owner approval.
|
|
7
|
-
*
|
|
8
|
-
* This is NOT a replacement for prompt injection — it's a hard fallback
|
|
9
|
-
* for models that don't follow system prompt behavioral directives.
|
|
10
|
-
*
|
|
11
|
-
* Flow:
|
|
12
|
-
* 1. Prompt hook (before_prompt_build) detects confirm-first directive and caches state
|
|
13
|
-
* 2. Prompt hook detects user approval language and marks session approved
|
|
14
|
-
* 3. Gate hook (before_tool_call) checks cached state synchronously
|
|
15
|
-
*/
|
|
16
|
-
import { SqliteConfirmFirstStateStore } from '@principles/core/runtime-v2';
|
|
17
|
-
export declare function setConfirmFirstStore(store: SqliteConfirmFirstStateStore | null): void;
|
|
18
|
-
export interface ConfirmFirstGateResult {
|
|
19
|
-
action: 'allow' | 'block' | 'skip';
|
|
20
|
-
reason?: string;
|
|
21
|
-
nextAction?: string;
|
|
22
|
-
principleId?: string;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Detect if user message contains clear approval language.
|
|
26
|
-
* Rejects negated forms (e.g., "don't proceed", "不同意", "确认一下").
|
|
27
|
-
*/
|
|
28
|
-
export declare function detectApprovalMarker(message: string): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Set confirm-first directive state for a session (called from prompt hook).
|
|
31
|
-
*/
|
|
32
|
-
export declare function setConfirmFirstDirective(sessionId: string, active: boolean, principleId?: string): void;
|
|
33
|
-
/**
|
|
34
|
-
* Mark a session as approved (called from prompt hook when approval detected).
|
|
35
|
-
*/
|
|
36
|
-
export declare function setConfirmFirstApproval(sessionId: string): void;
|
|
37
|
-
/**
|
|
38
|
-
* Synchronous gate evaluation — checks cached state only.
|
|
39
|
-
* Called from before_tool_call hook (must be synchronous).
|
|
40
|
-
*/
|
|
41
|
-
export declare function evaluateConfirmFirstGateSync(sessionId: string | undefined, toolName: string, params: Record<string, unknown> | undefined): ConfirmFirstGateResult;
|
|
42
|
-
/**
|
|
43
|
-
* Reset state for a session (e.g., on /reset).
|
|
44
|
-
*/
|
|
45
|
-
export declare function resetConfirmFirst(sessionId: string): void;
|
|
46
|
-
/**
|
|
47
|
-
* Check if a session has been approved (for testing).
|
|
48
|
-
*/
|
|
49
|
-
export declare function isSessionApproved(sessionId: string): boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Check if a session has an active directive (for testing).
|
|
52
|
-
*/
|
|
53
|
-
export declare function hasActiveDirective(sessionId: string): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Clear all state (for testing).
|
|
56
|
-
*/
|
|
57
|
-
export declare function clearAllConfirmFirstState(): void;
|
|
58
|
-
export declare function hydrateFromStore(sessionId: string): void;
|
|
59
|
-
export declare function pruneStoreStaleRows(): number;
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Confirm-First Gate
|
|
3
|
-
*
|
|
4
|
-
* Hard enforcement for confirm-first Runtime V2 prompt activations.
|
|
5
|
-
* When an owner-approved activation requires confirmation before coding,
|
|
6
|
-
* this gate blocks mutating tools until the session has explicit owner approval.
|
|
7
|
-
*
|
|
8
|
-
* This is NOT a replacement for prompt injection — it's a hard fallback
|
|
9
|
-
* for models that don't follow system prompt behavioral directives.
|
|
10
|
-
*
|
|
11
|
-
* Flow:
|
|
12
|
-
* 1. Prompt hook (before_prompt_build) detects confirm-first directive and caches state
|
|
13
|
-
* 2. Prompt hook detects user approval language and marks session approved
|
|
14
|
-
* 3. Gate hook (before_tool_call) checks cached state synchronously
|
|
15
|
-
*/
|
|
16
|
-
import { BASH_TOOLS_SET, WRITE_TOOLS } from '../constants/tools.js';
|
|
17
|
-
/** Size cap to prevent memory leaks from abandoned sessions */
|
|
18
|
-
const MAX_SESSION_ENTRIES = 500;
|
|
19
|
-
// TODO(PRI-268): stale directive cleanup
|
|
20
|
-
const sessionDirectiveState = new Map();
|
|
21
|
-
// TODO(PRI-267): per-task approval scope
|
|
22
|
-
const sessionApprovalState = new Map();
|
|
23
|
-
let confirmFirstStore = null;
|
|
24
|
-
export function setConfirmFirstStore(store) {
|
|
25
|
-
confirmFirstStore = store;
|
|
26
|
-
}
|
|
27
|
-
function evictOldestIfFull(map) {
|
|
28
|
-
if (map.size >= MAX_SESSION_ENTRIES) {
|
|
29
|
-
const firstKey = map.keys().next().value;
|
|
30
|
-
if (firstKey !== undefined)
|
|
31
|
-
map.delete(firstKey);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if a tool is mutating (write, edit, delete, or mutating exec).
|
|
36
|
-
*/
|
|
37
|
-
function isMutatingTool(toolName, params) {
|
|
38
|
-
// Direct write/edit/delete tools are always mutating
|
|
39
|
-
if (WRITE_TOOLS.has(toolName))
|
|
40
|
-
return true;
|
|
41
|
-
// For exec/bash, only mutating if the command content is mutating
|
|
42
|
-
if (BASH_TOOLS_SET.has(toolName)) {
|
|
43
|
-
const command = String(params?.command || params?.args || '');
|
|
44
|
-
if (!command)
|
|
45
|
-
return false;
|
|
46
|
-
return />\s*|>>\s*|\brm\b|\bmv\b|\bmkdir\b|\btouch\b|\bcp\s|\bsed\s+-i|\bchmod\b|\bchown\b|\bdel\s|\bRemove-Item\b|\bSet-Content\b|\bOut-File\b|\bNew-Item\b/.test(command);
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Detect if user message contains clear approval language.
|
|
52
|
-
* Rejects negated forms (e.g., "don't proceed", "不同意", "确认一下").
|
|
53
|
-
*/
|
|
54
|
-
export function detectApprovalMarker(message) {
|
|
55
|
-
const trimmed = message.trim();
|
|
56
|
-
// Negation prefixes — reject if present before approval keywords
|
|
57
|
-
const zhNegation = /不|别|暂不|先不|无法|不能|没准备好|还没|尚未/;
|
|
58
|
-
const enNegation = /don'?t|not\s+ready|can'?t|won'?t|stop|hold|cannot|isn'?t|aren'?t|haven'?t|shouldn'?t/i;
|
|
59
|
-
// Single-word Chinese markers require exact match (the word alone, not embedded in a sentence)
|
|
60
|
-
const zhExactMarkers = /^(?:确认|批准|同意|执行吧|开始执行)$/;
|
|
61
|
-
// Multi-word Chinese markers
|
|
62
|
-
const zhPhraseMarkers = /按计划执行|可以执行|就这么做|去执行|照.*做|没问题.*执行/;
|
|
63
|
-
// English markers — unambiguous single-word approvals only
|
|
64
|
-
const enMarkers = /\bapproved\b|\bgo\s*ahead\b|\blgtm\b/i;
|
|
65
|
-
// English phrase markers — require explicit approval context
|
|
66
|
-
const enPhraseMarkers = /\byes,?\s*(do\s+it|proceed|execute)\b|\bdo\s+it\b|\bproceed\s+with\s+the\s+plan\b|\bexecute\s+the\s+plan\b|\bplease\s+proceed\s+with\s+the\s+plan\b/i;
|
|
67
|
-
// Check Chinese
|
|
68
|
-
if (zhExactMarkers.test(trimmed) || zhPhraseMarkers.test(trimmed)) {
|
|
69
|
-
// Reject if negation prefix present
|
|
70
|
-
if (zhNegation.test(trimmed))
|
|
71
|
-
return false;
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
// Check English
|
|
75
|
-
if (enMarkers.test(trimmed) || enPhraseMarkers.test(trimmed)) {
|
|
76
|
-
if (enNegation.test(trimmed))
|
|
77
|
-
return false;
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Set confirm-first directive state for a session (called from prompt hook).
|
|
84
|
-
*/
|
|
85
|
-
export function setConfirmFirstDirective(sessionId, active, principleId) {
|
|
86
|
-
evictOldestIfFull(sessionDirectiveState);
|
|
87
|
-
sessionDirectiveState.set(sessionId, { active, principleId });
|
|
88
|
-
if (confirmFirstStore) {
|
|
89
|
-
try {
|
|
90
|
-
confirmFirstStore.upsertDirective(sessionId, active, principleId ?? null);
|
|
91
|
-
}
|
|
92
|
-
catch (storeErr) {
|
|
93
|
-
console.warn(`[PD:ConfirmFirst] Store write failed for directive (session=${sessionId}), degraded to cache-only: ${String(storeErr)}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Mark a session as approved (called from prompt hook when approval detected).
|
|
99
|
-
*/
|
|
100
|
-
export function setConfirmFirstApproval(sessionId) {
|
|
101
|
-
evictOldestIfFull(sessionApprovalState);
|
|
102
|
-
sessionApprovalState.set(sessionId, true);
|
|
103
|
-
if (confirmFirstStore) {
|
|
104
|
-
try {
|
|
105
|
-
confirmFirstStore.upsertApproval(sessionId);
|
|
106
|
-
}
|
|
107
|
-
catch (storeErr) {
|
|
108
|
-
console.warn(`[PD:ConfirmFirst] Store write failed for approval (session=${sessionId}), degraded to cache-only: ${String(storeErr)}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Synchronous gate evaluation — checks cached state only.
|
|
114
|
-
* Called from before_tool_call hook (must be synchronous).
|
|
115
|
-
*/
|
|
116
|
-
export function evaluateConfirmFirstGateSync(sessionId, toolName, params) {
|
|
117
|
-
if (!sessionId)
|
|
118
|
-
return { action: 'skip' };
|
|
119
|
-
// 1. Check if session is already approved
|
|
120
|
-
if (sessionApprovalState.get(sessionId)) {
|
|
121
|
-
return { action: 'allow' };
|
|
122
|
-
}
|
|
123
|
-
// 2. Check if confirm-first directive is active for this session
|
|
124
|
-
const directive = sessionDirectiveState.get(sessionId);
|
|
125
|
-
if (!directive?.active) {
|
|
126
|
-
return { action: 'skip' };
|
|
127
|
-
}
|
|
128
|
-
// 3. Check if tool is mutating
|
|
129
|
-
if (!isMutatingTool(toolName, params)) {
|
|
130
|
-
return { action: 'allow' };
|
|
131
|
-
}
|
|
132
|
-
// 4. Block: mutating tool with active confirm-first and no approval
|
|
133
|
-
return {
|
|
134
|
-
action: 'block',
|
|
135
|
-
reason: 'confirm_first_required',
|
|
136
|
-
nextAction: 'Summarize requirements, list ambiguities, propose a plan, and wait for explicit owner approval before mutating files.',
|
|
137
|
-
principleId: directive.principleId,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Reset state for a session (e.g., on /reset).
|
|
142
|
-
*/
|
|
143
|
-
export function resetConfirmFirst(sessionId) {
|
|
144
|
-
sessionDirectiveState.delete(sessionId);
|
|
145
|
-
sessionApprovalState.delete(sessionId);
|
|
146
|
-
if (confirmFirstStore) {
|
|
147
|
-
try {
|
|
148
|
-
confirmFirstStore.deleteState(sessionId);
|
|
149
|
-
}
|
|
150
|
-
catch (storeErr) {
|
|
151
|
-
console.warn(`[PD:ConfirmFirst] Store delete failed for session=${sessionId}: ${String(storeErr)}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Check if a session has been approved (for testing).
|
|
157
|
-
*/
|
|
158
|
-
export function isSessionApproved(sessionId) {
|
|
159
|
-
return sessionApprovalState.get(sessionId) === true;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Check if a session has an active directive (for testing).
|
|
163
|
-
*/
|
|
164
|
-
export function hasActiveDirective(sessionId) {
|
|
165
|
-
return sessionDirectiveState.get(sessionId)?.active === true;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Clear all state (for testing).
|
|
169
|
-
*/
|
|
170
|
-
export function clearAllConfirmFirstState() {
|
|
171
|
-
sessionDirectiveState.clear();
|
|
172
|
-
sessionApprovalState.clear();
|
|
173
|
-
if (confirmFirstStore) {
|
|
174
|
-
try {
|
|
175
|
-
confirmFirstStore.deleteAllState();
|
|
176
|
-
}
|
|
177
|
-
catch (storeErr) {
|
|
178
|
-
console.warn(`[PD:ConfirmFirst] Store clearAll failed: ${String(storeErr)}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
export function hydrateFromStore(sessionId) {
|
|
183
|
-
if (!confirmFirstStore)
|
|
184
|
-
return;
|
|
185
|
-
if (sessionDirectiveState.has(sessionId))
|
|
186
|
-
return;
|
|
187
|
-
try {
|
|
188
|
-
const record = confirmFirstStore.getState(sessionId);
|
|
189
|
-
if (!record)
|
|
190
|
-
return;
|
|
191
|
-
evictOldestIfFull(sessionDirectiveState);
|
|
192
|
-
sessionDirectiveState.set(sessionId, {
|
|
193
|
-
active: record.directiveActive,
|
|
194
|
-
principleId: record.directivePrincipleId ?? undefined,
|
|
195
|
-
});
|
|
196
|
-
if (record.approvalActive) {
|
|
197
|
-
evictOldestIfFull(sessionApprovalState);
|
|
198
|
-
sessionApprovalState.set(sessionId, true);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
catch (storeErr) {
|
|
202
|
-
console.warn(`[PD:ConfirmFirst] Store hydration failed for session=${sessionId}: ${String(storeErr)}`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
export function pruneStoreStaleRows() {
|
|
206
|
-
if (!confirmFirstStore)
|
|
207
|
-
return 0;
|
|
208
|
-
try {
|
|
209
|
-
return confirmFirstStore.pruneStaleRows();
|
|
210
|
-
}
|
|
211
|
-
catch (storeErr) {
|
|
212
|
-
console.warn(`[PD:ConfirmFirst] Store pruning failed: ${String(storeErr)}`);
|
|
213
|
-
return 0;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: plan-script
|
|
3
|
-
description: Create a step-by-step movie-script style execution plan. Includes target files, verification metrics, and rollback strategy.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Plan Script
|
|
8
|
-
|
|
9
|
-
**Goal**: Produce a "foolproof" executable plan to ensure controlled execution.
|
|
10
|
-
|
|
11
|
-
Please generate plan in the following structure:
|
|
12
|
-
|
|
13
|
-
## 1. Target Files (Authorization List)
|
|
14
|
-
- List file paths **uniquely authorized** for modification in this plan.
|
|
15
|
-
- Format: `- path/to/file`
|
|
16
|
-
|
|
17
|
-
## 2. Steps (Execution Steps)
|
|
18
|
-
1. Operations specific to filenames and tool calls.
|
|
19
|
-
2. Each step includes expected intermediate state.
|
|
20
|
-
|
|
21
|
-
## 3. Metrics (Verification Metrics)
|
|
22
|
-
- How to quantitatively prove this plan succeeded? (e.g., tests pass, command returns 0, specific string appears in logs).
|
|
23
|
-
|
|
24
|
-
## 4. Active Mental Models
|
|
25
|
-
- Select exactly **2** meta-cognitive models from `.principles/THINKING_OS.md` that are most relevant to the current task.
|
|
26
|
-
- Format: `- [T-0X] Model Name: Why is it needed for this specific task?`
|
|
27
|
-
|
|
28
|
-
## 5. Rollback (Rollback Strategy)
|
|
29
|
-
- If step 2 fails, how to one-click restore to safe state?
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
**Action**: Update above content to `PLAN.md` and set `STATUS: READY`.
|