mister-wolf 2.16.3 → 2.17.1
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/README.md +24 -11
- package/README.ru.md +25 -14
- package/dist/adapters/cli/cli-entry.d.ts.map +1 -1
- package/dist/adapters/cli/cli-entry.js +25 -0
- package/dist/adapters/cli/cli-entry.js.map +1 -1
- package/dist/adapters/cli/commands/claim.d.ts +6 -0
- package/dist/adapters/cli/commands/claim.d.ts.map +1 -0
- package/dist/adapters/cli/commands/claim.js +65 -0
- package/dist/adapters/cli/commands/claim.js.map +1 -0
- package/dist/adapters/cli/commands/face.d.ts +3 -0
- package/dist/adapters/cli/commands/face.d.ts.map +1 -0
- package/dist/adapters/cli/commands/face.js +227 -0
- package/dist/adapters/cli/commands/face.js.map +1 -0
- package/dist/adapters/cli/commands/memory-add.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-add.js +1 -1
- package/dist/adapters/cli/commands/memory-add.js.map +1 -1
- package/dist/adapters/cli/commands/memory-doctor.d.ts +20 -0
- package/dist/adapters/cli/commands/memory-doctor.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-doctor.js +123 -7
- package/dist/adapters/cli/commands/memory-doctor.js.map +1 -1
- package/dist/adapters/cli/commands/memory-edit.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-edit.js +6 -52
- package/dist/adapters/cli/commands/memory-edit.js.map +1 -1
- package/dist/adapters/cli/commands/memory-init.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-init.js +37 -54
- package/dist/adapters/cli/commands/memory-init.js.map +1 -1
- package/dist/adapters/cli/commands/memory-list.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-list.js +1 -1
- package/dist/adapters/cli/commands/memory-list.js.map +1 -1
- package/dist/adapters/cli/commands/memory-scaffold.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-scaffold.js +2 -1
- package/dist/adapters/cli/commands/memory-scaffold.js.map +1 -1
- package/dist/adapters/cli/commands/memory-search.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-search.js +1 -1
- package/dist/adapters/cli/commands/memory-search.js.map +1 -1
- package/dist/adapters/cli/commands/memory-sync.js +1 -1
- package/dist/adapters/cli/commands/memory-sync.js.map +1 -1
- package/dist/adapters/cli/commands/propose.d.ts +3 -0
- package/dist/adapters/cli/commands/propose.d.ts.map +1 -0
- package/dist/adapters/cli/commands/propose.js +94 -0
- package/dist/adapters/cli/commands/propose.js.map +1 -0
- package/dist/adapters/cli/type-command-generator.d.ts.map +1 -1
- package/dist/adapters/cli/type-command-generator.js +2 -0
- package/dist/adapters/cli/type-command-generator.js.map +1 -1
- package/dist/adapters/fs/claim-registry.d.ts +85 -0
- package/dist/adapters/fs/claim-registry.d.ts.map +1 -0
- package/dist/adapters/fs/claim-registry.js +276 -0
- package/dist/adapters/fs/claim-registry.js.map +1 -0
- package/dist/adapters/fs/memory-root.d.ts +26 -1
- package/dist/adapters/fs/memory-root.d.ts.map +1 -1
- package/dist/adapters/fs/memory-root.js +88 -2
- package/dist/adapters/fs/memory-root.js.map +1 -1
- package/dist/app/use-cases/add-memory-object.d.ts +5 -0
- package/dist/app/use-cases/add-memory-object.d.ts.map +1 -1
- package/dist/app/use-cases/add-memory-object.js +24 -5
- package/dist/app/use-cases/add-memory-object.js.map +1 -1
- package/dist/app/use-cases/claim-artifact.d.ts +31 -0
- package/dist/app/use-cases/claim-artifact.d.ts.map +1 -0
- package/dist/app/use-cases/claim-artifact.js +38 -0
- package/dist/app/use-cases/claim-artifact.js.map +1 -0
- package/dist/app/use-cases/create-face-version.d.ts +101 -0
- package/dist/app/use-cases/create-face-version.d.ts.map +1 -0
- package/dist/app/use-cases/create-face-version.js +100 -0
- package/dist/app/use-cases/create-face-version.js.map +1 -0
- package/dist/app/use-cases/create-mutation-record.d.ts +55 -0
- package/dist/app/use-cases/create-mutation-record.d.ts.map +1 -0
- package/dist/app/use-cases/create-mutation-record.js +78 -0
- package/dist/app/use-cases/create-mutation-record.js.map +1 -0
- package/dist/app/use-cases/deliver-proposal.d.ts +26 -0
- package/dist/app/use-cases/deliver-proposal.d.ts.map +1 -0
- package/dist/app/use-cases/deliver-proposal.js +35 -0
- package/dist/app/use-cases/deliver-proposal.js.map +1 -0
- package/dist/app/use-cases/edit-memory-object.d.ts +26 -0
- package/dist/app/use-cases/edit-memory-object.d.ts.map +1 -0
- package/dist/app/use-cases/edit-memory-object.js +57 -0
- package/dist/app/use-cases/edit-memory-object.js.map +1 -0
- package/dist/app/use-cases/face-operation.d.ts +81 -0
- package/dist/app/use-cases/face-operation.d.ts.map +1 -0
- package/dist/app/use-cases/face-operation.js +503 -0
- package/dist/app/use-cases/face-operation.js.map +1 -0
- package/dist/app/use-cases/get-call-injections.d.ts +12 -1
- package/dist/app/use-cases/get-call-injections.d.ts.map +1 -1
- package/dist/app/use-cases/get-call-injections.js +73 -12
- package/dist/app/use-cases/get-call-injections.js.map +1 -1
- package/dist/app/use-cases/migrate-faces.d.ts +81 -0
- package/dist/app/use-cases/migrate-faces.d.ts.map +1 -0
- package/dist/app/use-cases/migrate-faces.js +267 -0
- package/dist/app/use-cases/migrate-faces.js.map +1 -0
- package/dist/app/use-cases/promote-memory.d.ts +14 -1
- package/dist/app/use-cases/promote-memory.d.ts.map +1 -1
- package/dist/app/use-cases/promote-memory.js +36 -5
- package/dist/app/use-cases/promote-memory.js.map +1 -1
- package/dist/app/use-cases/record-relation.d.ts.map +1 -1
- package/dist/app/use-cases/record-relation.js +6 -0
- package/dist/app/use-cases/record-relation.js.map +1 -1
- package/dist/app/use-cases/save-proposal.d.ts +49 -0
- package/dist/app/use-cases/save-proposal.d.ts.map +1 -0
- package/dist/app/use-cases/save-proposal.js +32 -0
- package/dist/app/use-cases/save-proposal.js.map +1 -0
- package/dist/app/use-cases/scaffold-agent.d.ts.map +1 -1
- package/dist/app/use-cases/scaffold-agent.js +20 -52
- package/dist/app/use-cases/scaffold-agent.js.map +1 -1
- package/dist/app/use-cases/scaffold-artifact.d.ts +5 -0
- package/dist/app/use-cases/scaffold-artifact.d.ts.map +1 -1
- package/dist/app/use-cases/scaffold-artifact.js +2 -0
- package/dist/app/use-cases/scaffold-artifact.js.map +1 -1
- package/dist/app/use-cases/seed-base-playbooks.d.ts +17 -96
- package/dist/app/use-cases/seed-base-playbooks.d.ts.map +1 -1
- package/dist/app/use-cases/seed-base-playbooks.js +77 -32
- package/dist/app/use-cases/seed-base-playbooks.js.map +1 -1
- package/dist/app/use-cases/supersede-memory-object.d.ts +3 -1
- package/dist/app/use-cases/supersede-memory-object.d.ts.map +1 -1
- package/dist/app/use-cases/supersede-memory-object.js +8 -1
- package/dist/app/use-cases/supersede-memory-object.js.map +1 -1
- package/dist/app/use-cases/transition-memory-object.d.ts.map +1 -1
- package/dist/app/use-cases/transition-memory-object.js +6 -0
- package/dist/app/use-cases/transition-memory-object.js.map +1 -1
- package/dist/domain/facet-colors.d.ts.map +1 -1
- package/dist/domain/facet-colors.js +1 -0
- package/dist/domain/facet-colors.js.map +1 -1
- package/dist/domain/memory-types.d.ts +36 -1
- package/dist/domain/memory-types.d.ts.map +1 -1
- package/dist/domain/memory-types.js +36 -2
- package/dist/domain/memory-types.js.map +1 -1
- package/dist/domain/schemas/memory-event-schema.d.ts +8 -0
- package/dist/domain/schemas/memory-event-schema.d.ts.map +1 -1
- package/dist/domain/schemas/memory-event-schema.js +42 -1
- package/dist/domain/schemas/memory-event-schema.js.map +1 -1
- package/dist/domain/schemas/relation-schema.d.ts +6 -2
- package/dist/domain/schemas/relation-schema.d.ts.map +1 -1
- package/dist/domain/schemas/relation-schema.js +8 -0
- package/dist/domain/schemas/relation-schema.js.map +1 -1
- package/dist/domain/schemas/session-checkpoint-schema.d.ts +1 -1
- package/dist/domain/type-schema-builder.d.ts +4 -2
- package/dist/domain/type-schema-builder.d.ts.map +1 -1
- package/dist/domain/type-schema-builder.js +32 -1
- package/dist/domain/type-schema-builder.js.map +1 -1
- package/package.json +1 -1
- package/templates/.wolf/router.log +1 -1
- package/templates/base/agents/steward.md +9 -6
- package/templates/base/playbooks/complaint-protocol.md +1 -1
- package/templates/base/playbooks/steward-nastavnik.md +36 -17
- package/templates/opencode/plugins/wolf-router.ts +60 -10
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { closeSync, existsSync, linkSync, mkdirSync, openSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync, } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { UserFacingError } from '../../domain/errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* 2.17.1 REQ-05 (R06), design §3.5 / ADR-5: файловый claim-реестр владения
|
|
6
|
+
* общими артефактами (TASK-бриф, план, отчёт, worktree). JSON-файлы в общем
|
|
7
|
+
* `.wolf/shared/claims/` (cross-copy видимость — root из resolveMemoryRoot);
|
|
8
|
+
* атомарный захват — `openSync(…, 'wx')` (механика FsMemoryLock tryAcquire);
|
|
9
|
+
* stale: PID мёртв (ESRCH) ИЛИ возраст > CLAIM_TTL; перехват stale сохраняет
|
|
10
|
+
* прежний файл жёсткой ссылкой в след `<slug>.<epochMs>.json` (excl, NFR-02).
|
|
11
|
+
*/
|
|
12
|
+
/** TTL claim'а: локальный-first, heartbeat не вводим (design §3.5). */
|
|
13
|
+
export const CLAIM_TTL_MS = 24 * 60 * 60 * 1000;
|
|
14
|
+
export class ClaimHeldError extends Error {
|
|
15
|
+
claimPath;
|
|
16
|
+
owner;
|
|
17
|
+
reason;
|
|
18
|
+
constructor(claimPath, owner, reason) {
|
|
19
|
+
super(`Claim held by ${owner}: ${claimPath} (${reason})`);
|
|
20
|
+
this.claimPath = claimPath;
|
|
21
|
+
this.owner = owner;
|
|
22
|
+
this.reason = reason;
|
|
23
|
+
this.name = 'ClaimHeldError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function claimsDir(root) {
|
|
27
|
+
return join(root, '.wolf', 'shared', 'claims');
|
|
28
|
+
}
|
|
29
|
+
/** Имя файла claim'а: слэг артефакта, безопасный для ФС.
|
|
30
|
+
* shortcut: различные артефакты могут слэгнуться одинаково (отказ fail-closed, не порча). */
|
|
31
|
+
export function claimSlug(artifact) {
|
|
32
|
+
return artifact.replace(/[^A-Za-z0-9._-]+/g, '_');
|
|
33
|
+
}
|
|
34
|
+
export function claimFilePath(root, artifact) {
|
|
35
|
+
return join(claimsDir(root), `${claimSlug(artifact)}.json`);
|
|
36
|
+
}
|
|
37
|
+
/** След перехвата: `<slug>.<epochMs>.json` (исходные байты сохраняются, NFR-02). */
|
|
38
|
+
export function claimTrailPath(root, artifact, epochMs) {
|
|
39
|
+
return join(claimsDir(root), `${claimSlug(artifact)}.${epochMs}.json`);
|
|
40
|
+
}
|
|
41
|
+
/** Прод-liveness: signal 0; ESRCH — мёртв, EPERM — жив (чужой user). pid<=0 —
|
|
42
|
+
* неизвестен (переданный claim) — считаем живым, пока не истечёт TTL. */
|
|
43
|
+
export function pidAlive(pid) {
|
|
44
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
45
|
+
return true;
|
|
46
|
+
try {
|
|
47
|
+
process.kill(pid, 0);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return e.code === 'EPERM';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Синхронное ожидание in-flight окна (MINOR-2): Atomics.wait — без busy-loop. */
|
|
55
|
+
function sleepMs(ms) {
|
|
56
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
57
|
+
}
|
|
58
|
+
function parseClaim(raw) {
|
|
59
|
+
try {
|
|
60
|
+
const d = JSON.parse(raw);
|
|
61
|
+
if (typeof d.artifact !== 'string' || typeof d.owner !== 'string')
|
|
62
|
+
return null;
|
|
63
|
+
return {
|
|
64
|
+
artifact: d.artifact,
|
|
65
|
+
owner: d.owner,
|
|
66
|
+
session_id: typeof d.session_id === 'string' ? d.session_id : null,
|
|
67
|
+
pid: typeof d.pid === 'number' ? d.pid : 0,
|
|
68
|
+
cwd: typeof d.cwd === 'string' ? d.cwd : '',
|
|
69
|
+
acquired_at: typeof d.acquired_at === 'string' ? d.acquired_at : '',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Stale (design §3.5): мёртвый PID ИЛИ возраст > TTL; порченый файл = stale. */
|
|
77
|
+
function isStale(rec, deps) {
|
|
78
|
+
if (rec === null)
|
|
79
|
+
return true;
|
|
80
|
+
const alive = deps.isAlive ?? pidAlive;
|
|
81
|
+
if (!alive(rec.pid))
|
|
82
|
+
return true;
|
|
83
|
+
const acquired = Date.parse(rec.acquired_at);
|
|
84
|
+
if (Number.isNaN(acquired))
|
|
85
|
+
return true;
|
|
86
|
+
const now = (deps.now ?? (() => new Date()))().getTime();
|
|
87
|
+
return now - acquired > CLAIM_TTL_MS;
|
|
88
|
+
}
|
|
89
|
+
function readClaimFile(path) {
|
|
90
|
+
try {
|
|
91
|
+
const raw = readFileSync(path, 'utf-8');
|
|
92
|
+
return { raw, rec: parseClaim(raw) };
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return { raw: null, rec: null };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function describeHolder(rec) {
|
|
99
|
+
return `session ${rec.session_id ?? '-'}, pid ${rec.pid}, acquired ${rec.acquired_at}`;
|
|
100
|
+
}
|
|
101
|
+
/** Атомарный захват (REQ-05 AC-1): wx-create; занято и fresh — ClaimHeldError
|
|
102
|
+
* с идентификатором владельца; stale/порченый — перехват со следом. */
|
|
103
|
+
export function acquireClaim(deps, input) {
|
|
104
|
+
const dir = claimsDir(deps.root);
|
|
105
|
+
mkdirSync(dir, { recursive: true });
|
|
106
|
+
const path = claimFilePath(deps.root, input.artifact);
|
|
107
|
+
const now = deps.now ?? (() => new Date());
|
|
108
|
+
const record = {
|
|
109
|
+
artifact: input.artifact,
|
|
110
|
+
owner: input.identity.owner,
|
|
111
|
+
session_id: input.identity.sessionId,
|
|
112
|
+
pid: input.identity.pid,
|
|
113
|
+
cwd: input.cwd,
|
|
114
|
+
acquired_at: now().toISOString(),
|
|
115
|
+
};
|
|
116
|
+
for (let attempt = 0;; attempt++) {
|
|
117
|
+
try {
|
|
118
|
+
const fd = openSync(path, 'wx');
|
|
119
|
+
writeFileSync(fd, JSON.stringify(record), 'utf-8');
|
|
120
|
+
closeSync(fd);
|
|
121
|
+
return record;
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
const code = e.code;
|
|
125
|
+
if (code !== 'EEXIST')
|
|
126
|
+
throw e;
|
|
127
|
+
}
|
|
128
|
+
const { raw, rec } = readClaimFile(path);
|
|
129
|
+
// MINOR-2 (ревью T5): пустой файл — in-flight окно создателя (между wx и
|
|
130
|
+
// write), не порча: takeover запрещён, короткое ожидание и повтор
|
|
131
|
+
if (raw !== null && raw.trim() === '') {
|
|
132
|
+
if (attempt >= 60) {
|
|
133
|
+
throw new ClaimHeldError(path, 'unknown', 'claim file exists but stays empty (in-flight write?) — if it persists, remove it manually');
|
|
134
|
+
}
|
|
135
|
+
(deps.wait ?? sleepMs)(10);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (rec !== null && !isStale(rec, deps)) {
|
|
139
|
+
throw new ClaimHeldError(path, rec.owner, describeHolder(rec));
|
|
140
|
+
}
|
|
141
|
+
// stale/порченый (rec === null, сырые байты могли быть) → перехват со следом;
|
|
142
|
+
// проигранная гонка перехвата (ENOENT на link/unlink) — повтор захвата
|
|
143
|
+
try {
|
|
144
|
+
const epoch = now().getTime();
|
|
145
|
+
// FIX-4 (MINOR-4, ревью T5): след — через linkSync (excl-семантика):
|
|
146
|
+
// exists+rename TOCTOU позволял двум перехватчикам одной мс перезаписать
|
|
147
|
+
// чужой след (потеря байтов, NFR-02); при EEXIST — bump эпохи до свободного
|
|
148
|
+
let preserved = null;
|
|
149
|
+
for (let bump = 0; bump < 50 && preserved === null; bump++) {
|
|
150
|
+
const trail = claimTrailPath(deps.root, input.artifact, epoch + bump);
|
|
151
|
+
try {
|
|
152
|
+
linkSync(path, trail);
|
|
153
|
+
preserved = trail;
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
if (e.code !== 'EEXIST')
|
|
157
|
+
throw e;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (preserved !== null) {
|
|
161
|
+
// решение принималось по raw, а слинковаться мог уже переписанный файл
|
|
162
|
+
// (чужой takeover между чтением и link): чужую свежую запись в след не
|
|
163
|
+
// берём и claim-имя под ней не освобождаем — перечитаем и откажемся
|
|
164
|
+
if (raw !== null && readFileSync(preserved, 'utf-8') !== raw) {
|
|
165
|
+
unlinkSync(preserved);
|
|
166
|
+
}
|
|
167
|
+
else if (statSync(path).ino === statSync(preserved).ino) {
|
|
168
|
+
// unlink только сохранённый inode: конкурент мог уже пересоздать claim
|
|
169
|
+
unlinkSync(path);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
/* конкурент уже сохранил/убрал файл — идём на повторный wx */
|
|
175
|
+
}
|
|
176
|
+
if (attempt > 20) {
|
|
177
|
+
throw new ClaimHeldError(path, rec?.owner ?? 'unknown', 'too many contention attempts');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function ownerSessionMatch(rec, identity) {
|
|
182
|
+
return rec.owner === identity.owner && rec.session_id === identity.sessionId;
|
|
183
|
+
}
|
|
184
|
+
/** Освобождение (design §3.5): владелец — совпадение owner+session+pid.
|
|
185
|
+
* Освобождение чужим (иной owner/session, или pid записи жив и не совпал) —
|
|
186
|
+
* отказ с именем владельца. Мёртвый/stale держатель: тот же owner+session
|
|
187
|
+
* может убрать запись (равносильно перехвату acquire — новой власти не даёт). */
|
|
188
|
+
export function releaseClaim(deps, input) {
|
|
189
|
+
const path = claimFilePath(deps.root, input.artifact);
|
|
190
|
+
const { rec } = readClaimFile(path);
|
|
191
|
+
if (!existsSync(path)) {
|
|
192
|
+
throw new UserFacingError(`No claim held for "${input.artifact}" (claim file: ${path})`);
|
|
193
|
+
}
|
|
194
|
+
if (rec === null) {
|
|
195
|
+
// FIX-5 (MINOR-5, ревью T5): файл есть, но не читается как claim — «No claim
|
|
196
|
+
// held» лгало об отсутствии; честный отказ без расширения поведения.
|
|
197
|
+
throw new UserFacingError(`Claim file for "${input.artifact}" is corrupt — ownership cannot be verified; take over via "wolf claim acquire" (preserves bytes) or remove it manually (claim file: ${path})`);
|
|
198
|
+
}
|
|
199
|
+
const fullMatch = ownerSessionMatch(rec, input.identity) && rec.pid === input.identity.pid;
|
|
200
|
+
const pidReleasable = rec.pid <= 0 || isStale(rec, deps);
|
|
201
|
+
// MINOR-1b (интегральное ревью 2.17.1): зеркально requireClaim — адресат
|
|
202
|
+
// transfer (session null + owner) освобождает своей сессией, иначе передача
|
|
203
|
+
// паркует release до TTL
|
|
204
|
+
const transferredToWho = rec.session_id === null && rec.owner === input.identity.owner;
|
|
205
|
+
if (!fullMatch && !transferredToWho && !(ownerSessionMatch(rec, input.identity) && pidReleasable)) {
|
|
206
|
+
throw new UserFacingError(`Claim for "${input.artifact}" is owned by ${rec.owner} (${describeHolder(rec)}) — release is owner-only (claim file: ${path})`);
|
|
207
|
+
}
|
|
208
|
+
if (input.transferTo !== undefined) {
|
|
209
|
+
const now = (deps.now ?? (() => new Date()))();
|
|
210
|
+
const transferred = {
|
|
211
|
+
artifact: rec.artifact,
|
|
212
|
+
owner: input.transferTo,
|
|
213
|
+
// новый владелец ещё не предъявил процесс — liveness неизвестна (TTL решает)
|
|
214
|
+
session_id: null,
|
|
215
|
+
pid: 0,
|
|
216
|
+
cwd: rec.cwd,
|
|
217
|
+
acquired_at: now.toISOString(),
|
|
218
|
+
};
|
|
219
|
+
writeFileSync(path, JSON.stringify(transferred), 'utf-8');
|
|
220
|
+
return { action: 'transferred', owner: input.transferTo };
|
|
221
|
+
}
|
|
222
|
+
unlinkSync(path);
|
|
223
|
+
return { action: 'released', owner: rec.owner };
|
|
224
|
+
}
|
|
225
|
+
/** Реестр для наблюдаемости (REQ-05 AC-2): кто/когда/что из файлов; следы
|
|
226
|
+
* `<slug>.<epochMs>.json` исключаются — по содержимому: след хранит запись
|
|
227
|
+
* базового артефакта, его slug ≠ имя файла следа (MINOR-4). */
|
|
228
|
+
export function listClaims(deps) {
|
|
229
|
+
const dir = claimsDir(deps.root);
|
|
230
|
+
let names;
|
|
231
|
+
try {
|
|
232
|
+
names = readdirSync(dir);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
const out = [];
|
|
238
|
+
for (const name of names) {
|
|
239
|
+
if (!name.endsWith('.json'))
|
|
240
|
+
continue;
|
|
241
|
+
const { rec } = readClaimFile(join(dir, name));
|
|
242
|
+
if (rec === null)
|
|
243
|
+
continue;
|
|
244
|
+
// MINOR-4: имя с 13 цифрами на конце может быть легитимным claim'ом —
|
|
245
|
+
// след распознаём по несоответствию имени и slug(rec.artifact), не по маске
|
|
246
|
+
if (claimFilePath(deps.root, rec.artifact) !== join(dir, name))
|
|
247
|
+
continue;
|
|
248
|
+
out.push(rec);
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
/** Guard записи (REQ-05 AC-3): активный claim артефакта должен существовать и
|
|
253
|
+
* принадлежать пишущему (owner+session; pid писателя ≠ pid захватчика —
|
|
254
|
+
* захват и запись обычно разные процессы). Отказ — UserFacingError с именем
|
|
255
|
+
* владельца и путём claim-файла. */
|
|
256
|
+
export function requireClaim(deps, artifact, who) {
|
|
257
|
+
const path = claimFilePath(deps.root, artifact);
|
|
258
|
+
const { rec } = readClaimFile(path);
|
|
259
|
+
if (!existsSync(path)) {
|
|
260
|
+
throw new UserFacingError(`No claim held for "${artifact}" — acquire it first: wolf claim acquire "${artifact}" (claim file: ${path})`);
|
|
261
|
+
}
|
|
262
|
+
if (rec === null) {
|
|
263
|
+
throw new UserFacingError(`Claim file for "${artifact}" is corrupt — treated as stale; re-acquire: wolf claim acquire "${artifact}" (claim file: ${path})`);
|
|
264
|
+
}
|
|
265
|
+
if (isStale(rec, deps)) {
|
|
266
|
+
throw new UserFacingError(`Claim for "${artifact}" is stale (holder ${rec.owner}) — re-acquire: wolf claim acquire "${artifact}" (claim file: ${path})`);
|
|
267
|
+
}
|
|
268
|
+
// MINOR-1 (ревью T5): переданный claim (transfer: session null, pid 0)
|
|
269
|
+
// доступен адресату с любой его сессией — иначе передача парковала бы
|
|
270
|
+
// запись до TTL. pid-проверка для pid:0 не применяется (pidAlive).
|
|
271
|
+
const transferredToWho = rec.session_id === null && rec.owner === who.owner;
|
|
272
|
+
if (!transferredToWho && (rec.owner !== who.owner || rec.session_id !== who.sessionId)) {
|
|
273
|
+
throw new UserFacingError(`Artifact "${artifact}" is claimed by ${rec.owner} (${describeHolder(rec)}) — claim file: ${path}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=claim-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-registry.js","sourceRoot":"","sources":["../../../src/adapters/fs/claim-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
export interface MemoryRootInfo {
|
|
2
2
|
/** Корень чекаута, владеющего общим .wolf/ (main-чекоут; вне worktree — сам baseDir). */
|
|
3
3
|
root: string;
|
|
4
|
-
/**
|
|
4
|
+
/** Токен WT-ID linked worktree (`w-<12 hex>`) или null (main-чекоут / вне git / аномалия).
|
|
5
|
+
* 2.17.1 REQ-02 (R02): токен вместо basename — одинаковые basename двух копий дают
|
|
6
|
+
* разные идентификаторы; consumer подставляет его в scope как `worktree:${worktree}`. */
|
|
5
7
|
worktree: string | null;
|
|
6
8
|
}
|
|
9
|
+
/** 2.17.1 REQ-02 (R02), design §3.1 (ADR-1): устойчивая идентичность linked worktree. */
|
|
10
|
+
export interface WorktreeIdentity {
|
|
11
|
+
/** Полный scope-токен копии: `worktree:w-<12 hex sha1(realpath(baseDir))>`. */
|
|
12
|
+
id: string;
|
|
13
|
+
/** basename(baseDir) — маппинг legacy-токенов `worktree:<name>` (записанных до 2.17.1). */
|
|
14
|
+
legacyName: string;
|
|
15
|
+
/** true — ровно одна живая копия с этим basename: legacy-имя однозначно маппится на неё. */
|
|
16
|
+
legacyUnique: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** Токен WT-ID без префикса scope: `w-` + первые 12 hex sha1(realpath(dir)).
|
|
19
|
+
* Идентичность по realpath: одинаковые basename двух копий дают разные токены;
|
|
20
|
+
* переименование каталога = новая копия с новым WT-ID (ограничение ADR-1). */
|
|
21
|
+
export declare function worktreeScopeToken(dir: string): string;
|
|
7
22
|
/** WP3 §6.1 (спека 2.16): linked worktree резолвит общий .wolf/ в main-чекоуте.
|
|
8
23
|
* Механика спеки — git common-dir (`git rev-parse --git-common-dir`); здесь тот же
|
|
9
24
|
* информационный fs-парс без подпроцессов (прецедент чтения .git/HEAD:
|
|
10
25
|
* heuristic-project-scanner.ts:221-239) — юнит-тестируемо без git, нет подпроцесса
|
|
11
26
|
* в hot-path. Любой сбой — безопасный fallback на локальный .wolf/ (риск Р5 спеки). */
|
|
12
27
|
export declare function resolveMemoryRoot(baseDir: string): MemoryRootInfo;
|
|
28
|
+
/** 2.17.1 REQ-02 (R02), design §3.1 (ADR-1): идентичность linked worktree.
|
|
29
|
+
* null — main-чекоут, вне git, bare-аномалия, сбой git-метаданных (fail-closed:
|
|
30
|
+
* legacy-токены не маппятся, чужой scope недоступен — §5).
|
|
31
|
+
* Вызывать лениво — по встрече legacy-токена (бюджет NFR-01: ≤1 git-подпроцесса
|
|
32
|
+
* на процесс, только linked worktree; main-чекоут git не запускает). */
|
|
33
|
+
export declare function resolveWorktreeIdentity(baseDir: string): WorktreeIdentity | null;
|
|
34
|
+
/** Каталог выглядит linked worktree (.git — файл-указатель), но метаданные не
|
|
35
|
+
* резолвятся в общий root: fail-closed предупреждение доставки (REQ-02 AC-5,
|
|
36
|
+
* design §5 — предупреждение в wolf call). null — не broken (main/outside git). */
|
|
37
|
+
export declare function brokenWorktreeHint(baseDir: string): string | null;
|
|
13
38
|
//# sourceMappingURL=memory-root.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-root.d.ts","sourceRoot":"","sources":["../../../src/adapters/fs/memory-root.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-root.d.ts","sourceRoot":"","sources":["../../../src/adapters/fs/memory-root.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb;;6FAEyF;IACzF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;8EAE8E;AAC9E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;uFAIuF;AACvF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAmBjE;AAsCD;;;;wEAIwE;AACxE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAWhF;AAED;;mFAEmF;AACnF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWjE"}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { existsSync, readFileSync, realpathSync, statSync } from 'fs';
|
|
2
4
|
import { basename, dirname, isAbsolute, join, resolve } from 'path';
|
|
5
|
+
/** Токен WT-ID без префикса scope: `w-` + первые 12 hex sha1(realpath(dir)).
|
|
6
|
+
* Идентичность по realpath: одинаковые basename двух копий дают разные токены;
|
|
7
|
+
* переименование каталога = новая копия с новым WT-ID (ограничение ADR-1). */
|
|
8
|
+
export function worktreeScopeToken(dir) {
|
|
9
|
+
return 'w-' + createHash('sha1').update(realpathSync(dir)).digest('hex').slice(0, 12);
|
|
10
|
+
}
|
|
3
11
|
/** WP3 §6.1 (спека 2.16): linked worktree резолвит общий .wolf/ в main-чекоуте.
|
|
4
12
|
* Механика спеки — git common-dir (`git rev-parse --git-common-dir`); здесь тот же
|
|
5
13
|
* информационный fs-парс без подпроцессов (прецедент чтения .git/HEAD:
|
|
@@ -25,10 +33,88 @@ export function resolveMemoryRoot(baseDir) {
|
|
|
25
33
|
// bare-репо + linked worktree: commondir указывает мимо чекаута — fallback локальный (Р5)
|
|
26
34
|
if (!existsSync(join(root, '.git')))
|
|
27
35
|
return { root: baseDir, worktree: null };
|
|
28
|
-
return { root, worktree:
|
|
36
|
+
return { root, worktree: worktreeScopeToken(baseDir) };
|
|
29
37
|
}
|
|
30
38
|
catch {
|
|
31
39
|
return { root: baseDir, worktree: null };
|
|
32
40
|
}
|
|
33
41
|
}
|
|
42
|
+
/** basename каждой живой записи `git worktree list --porcelain` (включая main-чекоут).
|
|
43
|
+
* Дубликаты сохраняются: однозначность legacy-имени — счёт, не множество. Кэш на
|
|
44
|
+
* процесс (NFR-01 (R02): ≤1 git-подпроцесса); null — сбой git-метаданных. */
|
|
45
|
+
const liveBasenamesCache = new Map();
|
|
46
|
+
function liveWorktreeBasenames(baseDir) {
|
|
47
|
+
let key;
|
|
48
|
+
try {
|
|
49
|
+
key = realpathSync(baseDir);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (liveBasenamesCache.has(key))
|
|
55
|
+
return liveBasenamesCache.get(key);
|
|
56
|
+
let result = null;
|
|
57
|
+
try {
|
|
58
|
+
const out = execFileSync('git', ['worktree', 'list', '--porcelain'], {
|
|
59
|
+
cwd: baseDir,
|
|
60
|
+
encoding: 'utf-8',
|
|
61
|
+
timeout: 10_000,
|
|
62
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
63
|
+
});
|
|
64
|
+
result = [];
|
|
65
|
+
for (const line of out.split('\n')) {
|
|
66
|
+
if (!line.startsWith('worktree '))
|
|
67
|
+
continue;
|
|
68
|
+
try {
|
|
69
|
+
result.push(basename(realpathSync(line.slice('worktree '.length).trim())));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// каталог записи исчез — git пометит prunable; в счёт живых он не входит
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
result = null; // битые git-метаданные — fail-closed (design §5)
|
|
78
|
+
}
|
|
79
|
+
liveBasenamesCache.set(key, result);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/** 2.17.1 REQ-02 (R02), design §3.1 (ADR-1): идентичность linked worktree.
|
|
83
|
+
* null — main-чекоут, вне git, bare-аномалия, сбой git-метаданных (fail-closed:
|
|
84
|
+
* legacy-токены не маппятся, чужой scope недоступен — §5).
|
|
85
|
+
* Вызывать лениво — по встрече legacy-токена (бюджет NFR-01: ≤1 git-подпроцесса
|
|
86
|
+
* на процесс, только linked worktree; main-чекоут git не запускает). */
|
|
87
|
+
export function resolveWorktreeIdentity(baseDir) {
|
|
88
|
+
const info = resolveMemoryRoot(baseDir);
|
|
89
|
+
if (info.worktree === null)
|
|
90
|
+
return null;
|
|
91
|
+
const live = liveWorktreeBasenames(baseDir);
|
|
92
|
+
if (live === null)
|
|
93
|
+
return null;
|
|
94
|
+
const legacyName = basename(baseDir);
|
|
95
|
+
return {
|
|
96
|
+
id: `worktree:${info.worktree}`,
|
|
97
|
+
legacyName,
|
|
98
|
+
legacyUnique: live.filter((n) => n === legacyName).length === 1,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** Каталог выглядит linked worktree (.git — файл-указатель), но метаданные не
|
|
102
|
+
* резолвятся в общий root: fail-closed предупреждение доставки (REQ-02 AC-5,
|
|
103
|
+
* design §5 — предупреждение в wolf call). null — не broken (main/outside git). */
|
|
104
|
+
export function brokenWorktreeHint(baseDir) {
|
|
105
|
+
try {
|
|
106
|
+
const dotGit = join(baseDir, '.git');
|
|
107
|
+
if (!existsSync(dotGit) || statSync(dotGit).isDirectory())
|
|
108
|
+
return null;
|
|
109
|
+
const raw = readFileSync(dotGit, 'utf-8');
|
|
110
|
+
if (!raw.startsWith('gitdir:'))
|
|
111
|
+
return null;
|
|
112
|
+
if (resolveMemoryRoot(baseDir).worktree !== null)
|
|
113
|
+
return null;
|
|
114
|
+
return `worktree git metadata is broken in ${baseDir} — delivery is fail-closed, worktree-scoped memory stays hidden`;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
34
120
|
//# sourceMappingURL=memory-root.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-root.js","sourceRoot":"","sources":["../../../src/adapters/fs/memory-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-root.js","sourceRoot":"","sources":["../../../src/adapters/fs/memory-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAqBpE;;8EAE8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxF,CAAC;AAED;;;;uFAIuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAClE,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,iBAAiB;QACjG,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,qBAAqB;QAC/F,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/D,0FAA0F;QAC1F,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC9E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;6EAE6E;AAC7E,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAC9D,SAAS,qBAAqB,CAAC,OAAe;IAC5C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IACrE,IAAI,MAAM,GAAoB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE;YACnE,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;gBAAE,SAAS;YAC5C,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,CAAC;YAAC,MAAM,CAAC;gBACP,yEAAyE;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,IAAI,CAAC,CAAC,iDAAiD;IAClE,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;wEAIwE;AACxE,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO;QACL,EAAE,EAAE,YAAY,IAAI,CAAC,QAAQ,EAAE;QAC/B,UAAU;QACV,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC;KAChE,CAAC;AACJ,CAAC;AAED;;mFAEmF;AACnF,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE;YAAE,OAAO,IAAI,CAAC;QACvE,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9D,OAAO,sCAAsC,OAAO,iEAAiE,CAAC;IACxH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -28,6 +28,11 @@ export interface AddMemoryObjectInput {
|
|
|
28
28
|
status?: MemoryObject['status'];
|
|
29
29
|
/** 2.13 §5.3: фасет «характер записи» — обязателен для note, запрещён прочим типам. */
|
|
30
30
|
facet?: string;
|
|
31
|
+
/** 2.17 (заявка T-09): маркер версионирующего пути — единственный легальный
|
|
32
|
+
* создатель face (createFaceVersion и его служебные входы migrate/seed).
|
|
33
|
+
* Не экспортируется в CLI/MCP: прямой add face refuses ниже (REQ-01 AC3,
|
|
34
|
+
* прецедент — T-07 тест «даже с initiator в extra»). */
|
|
35
|
+
internalFacePath?: boolean;
|
|
31
36
|
}
|
|
32
37
|
export interface AddMemoryObjectResult {
|
|
33
38
|
object: MemoryObject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-memory-object.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/add-memory-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAsB,MAAM,8CAA8C,CAAC;AAGhG,OAAO,
|
|
1
|
+
{"version":3,"file":"add-memory-object.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/add-memory-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAsB,MAAM,8CAA8C,CAAC;AAGhG,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAUtC;;6CAE6C;AAC7C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,SAAS,EAC5C,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,YAAY,CAAC,SAAS,CAAC,CAWzB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;4DAGwD;IACxD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE;IACJ,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAChD,oEAAoE;IACpE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAoIhC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { MemoryObjectSchema } from '../../domain/schemas/memory-object-schema.js';
|
|
2
2
|
import { validateMemoryObject } from '../../domain/policies/write-protocol.js';
|
|
3
3
|
import { governanceDefaults } from '../../domain/governance.js';
|
|
4
|
-
import { getDeclaration, DEFAULT_CHARACTER_FACETS } from '../../domain/memory-types.js';
|
|
5
|
-
import { buildTypeSchema, applyFacetEnum } from '../../domain/type-schema-builder.js';
|
|
4
|
+
import { getDeclaration, DEFAULT_CHARACTER_FACETS, MEMORY_TYPES, SIGNAL_FACETS, } from '../../domain/memory-types.js';
|
|
5
|
+
import { buildTypeSchema, applyFacetEnum, PROPOSAL_FACET, PROPOSAL_CONTRACT_FIELDS, } from '../../domain/type-schema-builder.js';
|
|
6
6
|
import { UserFacingError } from '../../domain/errors.js';
|
|
7
7
|
import { isAbsolute, normalize, relative, sep } from 'path';
|
|
8
8
|
/** WP3 §6.3: related.files/docs — project-relative posix-пути; абсолют вне root — отказ.
|
|
@@ -28,9 +28,23 @@ export async function addMemoryObject(deps, input) {
|
|
|
28
28
|
if (input.type === 'rule' && input.createdBy.startsWith('agent:')) {
|
|
29
29
|
throw new UserFacingError('Rules can only be created by explicit user request (use a user actor: --created-by user:<name> or env WOLF_ACTOR)');
|
|
30
30
|
}
|
|
31
|
+
// Волна 2.17 REQ-01 AC3 (design §Схемные изменения п.5): face создаётся только
|
|
32
|
+
// версионирующим путём (wolf face new/restore/breakglass) — прямой add закрыт
|
|
33
|
+
// для всех акторов, включая пользователя (прецедент: rule-guard выше).
|
|
34
|
+
// internalFacePath — маркер этого пути (createFaceVersion; заявка T-09:
|
|
35
|
+
// без него guard T-07 блокировал и версионирующий путь — 24 теста T-02/T-03/T-04/T-05 красные на HEAD)
|
|
36
|
+
if (input.type === 'face' && input.internalFacePath !== true) {
|
|
37
|
+
throw new UserFacingError('type "face" cannot be created with add: faces are versioned, use "wolf face" commands (new | restore | breakglass)');
|
|
38
|
+
}
|
|
31
39
|
// 2.13 §5.3: фасетная валидация в домене (формат подсказки — прецедент getDeclaration)
|
|
32
40
|
const facetDict = deps.facetCharacter ?? DEFAULT_CHARACTER_FACETS;
|
|
33
41
|
const facet = input.facet ?? input.extra?.facet;
|
|
42
|
+
// Волна 2.17 REQ-08/ADR-3: сигнал-фасет разрешён на не-note core-типах
|
|
43
|
+
// (SIGNAL_FACETS); character-фасеты — по-прежнему только note
|
|
44
|
+
const isSignalFacet = input.type !== 'note' &&
|
|
45
|
+
facet !== undefined &&
|
|
46
|
+
MEMORY_TYPES.includes(input.type) &&
|
|
47
|
+
SIGNAL_FACETS.includes(facet);
|
|
34
48
|
if (input.type === 'note') {
|
|
35
49
|
if (facet === undefined) {
|
|
36
50
|
throw new UserFacingError(`facet is required for type "note" (valid values: ${facetDict.join(', ')})`);
|
|
@@ -39,7 +53,7 @@ export async function addMemoryObject(deps, input) {
|
|
|
39
53
|
throw new UserFacingError(`Invalid facet "${facet}" for type "note" (valid values: ${facetDict.join(', ')})`);
|
|
40
54
|
}
|
|
41
55
|
}
|
|
42
|
-
else if (facet !== undefined) {
|
|
56
|
+
else if (facet !== undefined && !isSignalFacet) {
|
|
43
57
|
throw new UserFacingError(`facet is only valid for type "note" (got type "${input.type}")`);
|
|
44
58
|
}
|
|
45
59
|
const run = async () => {
|
|
@@ -72,14 +86,19 @@ export async function addMemoryObject(deps, input) {
|
|
|
72
86
|
// WP3 §6.2: явный scope (--scope main / --set scope=...) сильнее дефолта ворктрии
|
|
73
87
|
if (deps.defaultScope !== undefined && object.scope === undefined)
|
|
74
88
|
object.scope = deps.defaultScope;
|
|
75
|
-
|
|
89
|
+
// 2.17: фасет пишется и для сигнал-фасетов не-note core-типов (REQ-08);
|
|
90
|
+
// guard выше уже отсек недопустимые комбинации тип×фасет
|
|
91
|
+
if (facet !== undefined)
|
|
76
92
|
object.facet = facet;
|
|
77
93
|
const baseDecl = getDeclaration(object.type, deps.declarations);
|
|
78
94
|
// note: enum фасета = эффективный словарь (кастомный из конфига или дефолт)
|
|
79
95
|
const decl = object.type === 'note' ? applyFacetEnum(baseDecl, facetDict) : baseDecl;
|
|
80
96
|
const baseKeys = new Set(Object.keys(MemoryObjectSchema.shape));
|
|
81
97
|
for (const key of Object.keys(input.extra ?? {})) {
|
|
82
|
-
|
|
98
|
+
// 2.17 REQ-08: поля контракта предложения допустимы только при facet='proposal'
|
|
99
|
+
// (сами поля не входят в декларации типов — валидирует schema-builder superRefine)
|
|
100
|
+
const proposalField = facet === PROPOSAL_FACET && PROPOSAL_CONTRACT_FIELDS.includes(key);
|
|
101
|
+
if (!baseKeys.has(key) && !proposalField && !(key in (decl.fields ?? {}))) {
|
|
83
102
|
// T011: список валидных полей типа в сообщении; classifyError → invalid_input
|
|
84
103
|
throw new UserFacingError(`Unknown field "${key}" for type "${object.type}" (valid fields: ${Object.keys(decl.fields ?? {}).join(', ') || 'none'})`);
|
|
85
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-memory-object.js","sourceRoot":"","sources":["../../../src/app/use-cases/add-memory-object.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"add-memory-object.js","sourceRoot":"","sources":["../../../src/app/use-cases/add-memory-object.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ClaimRecord } from '../../adapters/fs/claim-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* 2.17.1 REQ-05 (R06), design §3.5: use-case-слой claim. Идентичность — env
|
|
4
|
+
* (WOLF_ACTOR/WOLF_SESSION, тот же механизм атрибуции, что у мутаций);
|
|
5
|
+
* реестр — в общем root (resolveMemoryRoot): claims видны из всех копий.
|
|
6
|
+
* makeClaimGuard — точка инъекции для use-cases записи общих артефактов
|
|
7
|
+
* (requireClaim до записи, REQ-05 AC-3).
|
|
8
|
+
*/
|
|
9
|
+
export interface ClaimArtifactDeps {
|
|
10
|
+
baseDir: string;
|
|
11
|
+
/** Тестовые seam'ы; прод-дефолты — process.env / process.pid / process.cwd(). */
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
pid?: number;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
now?: () => Date;
|
|
16
|
+
isAlive?: (pid: number) => boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function acquireArtifactClaim(deps: ClaimArtifactDeps, artifact: string): ClaimRecord;
|
|
19
|
+
export declare function releaseArtifactClaim(deps: ClaimArtifactDeps, artifact: string, transferTo?: string): {
|
|
20
|
+
action: 'released' | 'transferred';
|
|
21
|
+
owner: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function listArtifactClaims(deps: ClaimArtifactDeps): ClaimRecord[];
|
|
24
|
+
/** Guard для use-cases записи общих артефактов: claim артефакта должен
|
|
25
|
+
* принадлежать текущей идентичности (owner+session); pid писателя не важен
|
|
26
|
+
* (захват и запись — разные процессы). */
|
|
27
|
+
export interface ClaimGuard {
|
|
28
|
+
requireClaim(artifact: string): void;
|
|
29
|
+
}
|
|
30
|
+
export declare function makeClaimGuard(deps: ClaimArtifactDeps): ClaimGuard;
|
|
31
|
+
//# sourceMappingURL=claim-artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-artifact.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/claim-artifact.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,qCAAqC,CAAC;AAE7C;;;;;;GAMG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC;AAkBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAM3F;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,MAAM,EAAE,UAAU,GAAG,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEvD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAEzE;AAED;;0CAE0C;AAC1C,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAOlE"}
|