@fenglimg/fabric-shared 2.0.1 → 2.2.0-rc.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/dist/{chunk-7CX32MYL.js → chunk-7TZ2PMVH.js} +80 -4
- package/dist/{chunk-WVPDH4BF.js → chunk-JEXTOQVV.js} +31 -2
- package/dist/{chunk-LTDB2UDN.js → chunk-TX2XZ7AW.js} +2 -0
- package/dist/i18n/index.js +1 -1
- package/dist/{index-UBqD9F0b.d.ts → index-J3Xn5h2J.d.ts} +48 -1
- package/dist/index.d.ts +3083 -227
- package/dist/index.js +1896 -562
- package/dist/node/atomic-write.d.ts +26 -1
- package/dist/node/atomic-write.js +45 -2
- package/dist/node/mcp-payload-guard.d.ts +32 -1
- package/dist/node/mcp-payload-guard.js +15 -1
- package/dist/schemas/api-contracts.d.ts +81 -34
- package/dist/schemas/api-contracts.js +1 -1
- package/dist/templates/bootstrap-canonical.d.ts +1 -1
- package/dist/templates/bootstrap-canonical.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,31 @@ interface AtomicWriteJsonOptions extends AtomicWriteOptions {
|
|
|
6
6
|
}
|
|
7
7
|
declare function atomicWriteText(path: string, content: string, opts?: AtomicWriteOptions): Promise<void>;
|
|
8
8
|
declare function atomicWriteJson(path: string, value: unknown, opts?: AtomicWriteJsonOptions): Promise<void>;
|
|
9
|
+
interface FileLockOptions {
|
|
10
|
+
/** A held lock older than this (ms, by lock-file mtime) is presumed stale —
|
|
11
|
+
* left by a crashed holder — and reclaimed. Default 10s. */
|
|
12
|
+
staleMs?: number;
|
|
13
|
+
/** Poll interval (ms) between acquire attempts while contended. Default 20ms. */
|
|
14
|
+
retryDelayMs?: number;
|
|
15
|
+
/** Give up acquiring after this long (ms) and throw. Default 10s. */
|
|
16
|
+
maxWaitMs?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Run `fn` while holding a cross-process advisory lock at `lockPath`.
|
|
20
|
+
*
|
|
21
|
+
* Unlike the hook-side `appendLockedLine` (which DROPS on contention, fine for
|
|
22
|
+
* best-effort telemetry), this WAITS for the lock — the critical section it
|
|
23
|
+
* guards (e.g. a read-modify-write of a shared counter file) must not be
|
|
24
|
+
* skipped. The lock is a `wx` (O_CREAT|O_EXCL) lock file, so acquisition is
|
|
25
|
+
* atomic across processes; a crashed holder leaves the file behind, so any
|
|
26
|
+
* holder older than `staleMs` is reclaimed. The lock is always released in a
|
|
27
|
+
* `finally`, even if `fn` throws.
|
|
28
|
+
*
|
|
29
|
+
* Scope: cross-process AND in-process. Two concurrent callers on the same
|
|
30
|
+
* `lockPath` (same process or not) serialize, because both race the same
|
|
31
|
+
* O_EXCL create.
|
|
32
|
+
*/
|
|
33
|
+
declare function withFileLock<T>(lockPath: string, fn: () => Promise<T>, opts?: FileLockOptions): Promise<T>;
|
|
9
34
|
interface LedgerWriteQueue {
|
|
10
35
|
append(path: string, line: string): Promise<void>;
|
|
11
36
|
/**
|
|
@@ -27,4 +52,4 @@ interface LedgerWriteQueue {
|
|
|
27
52
|
}
|
|
28
53
|
declare function createLedgerWriteQueue(): LedgerWriteQueue;
|
|
29
54
|
|
|
30
|
-
export { type AtomicWriteJsonOptions, type AtomicWriteOptions, type LedgerWriteQueue, atomicWriteJson, atomicWriteText, createLedgerWriteQueue };
|
|
55
|
+
export { type AtomicWriteJsonOptions, type AtomicWriteOptions, type FileLockOptions, type LedgerWriteQueue, atomicWriteJson, atomicWriteText, createLedgerWriteQueue, withFileLock };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/node/atomic-write.ts
|
|
2
|
-
import { appendFile, open, rename, unlink, writeFile } from "fs/promises";
|
|
2
|
+
import { appendFile, mkdir, open, rename, stat, unlink, writeFile } from "fs/promises";
|
|
3
|
+
import { dirname } from "path";
|
|
3
4
|
function makeTmpSuffix() {
|
|
4
5
|
const rand = Math.floor(Math.random() * 65535).toString(16).padStart(4, "0");
|
|
5
6
|
return `.${process.pid}.${Date.now()}.${rand}.tmp`;
|
|
@@ -32,6 +33,47 @@ async function atomicWriteJson(path, value, opts) {
|
|
|
32
33
|
const content = JSON.stringify(value, null, indent) + "\n";
|
|
33
34
|
await atomicWriteText(path, content, { fsync: opts?.fsync });
|
|
34
35
|
}
|
|
36
|
+
function isErrnoException(err) {
|
|
37
|
+
return err instanceof Error && typeof err.code === "string";
|
|
38
|
+
}
|
|
39
|
+
function sleep(ms) {
|
|
40
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
41
|
+
}
|
|
42
|
+
async function withFileLock(lockPath, fn, opts = {}) {
|
|
43
|
+
const staleMs = opts.staleMs ?? 1e4;
|
|
44
|
+
const retryDelayMs = opts.retryDelayMs ?? 20;
|
|
45
|
+
const maxWaitMs = opts.maxWaitMs ?? 1e4;
|
|
46
|
+
await mkdir(dirname(lockPath), { recursive: true });
|
|
47
|
+
const start = Date.now();
|
|
48
|
+
for (; ; ) {
|
|
49
|
+
let handle;
|
|
50
|
+
try {
|
|
51
|
+
handle = await open(lockPath, "wx");
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (!isErrnoException(err) || err.code !== "EEXIST") throw err;
|
|
54
|
+
try {
|
|
55
|
+
const st = await stat(lockPath);
|
|
56
|
+
if (Date.now() - st.mtimeMs > staleMs) {
|
|
57
|
+
await unlink(lockPath).catch(() => void 0);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (Date.now() - start > maxWaitMs) {
|
|
64
|
+
throw new Error(`withFileLock: timed out acquiring ${lockPath} after ${maxWaitMs}ms`);
|
|
65
|
+
}
|
|
66
|
+
await sleep(retryDelayMs);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
await handle.close();
|
|
71
|
+
return await fn();
|
|
72
|
+
} finally {
|
|
73
|
+
await unlink(lockPath).catch(() => void 0);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
35
77
|
function createLedgerWriteQueue() {
|
|
36
78
|
const chains = /* @__PURE__ */ new Map();
|
|
37
79
|
async function doAppend(path, line) {
|
|
@@ -65,5 +107,6 @@ function createLedgerWriteQueue() {
|
|
|
65
107
|
export {
|
|
66
108
|
atomicWriteJson,
|
|
67
109
|
atomicWriteText,
|
|
68
|
-
createLedgerWriteQueue
|
|
110
|
+
createLedgerWriteQueue,
|
|
111
|
+
withFileLock
|
|
69
112
|
};
|
|
@@ -14,5 +14,36 @@ interface PayloadGuardResult {
|
|
|
14
14
|
declare const PAYLOAD_LIMIT_DEFAULT_WARN_BYTES = 16384;
|
|
15
15
|
declare const PAYLOAD_LIMIT_DEFAULT_HARD_BYTES = 65536;
|
|
16
16
|
declare function enforcePayloadLimit(serializedPayload: string, opts?: PayloadGuardOptions): PayloadGuardResult;
|
|
17
|
+
interface PayloadBudgetTrimResult<T> {
|
|
18
|
+
/** The retained head of `items` (the ranked tail was dropped to fit). */
|
|
19
|
+
items: T[];
|
|
20
|
+
/** How many trailing items were dropped to fit the hard budget. */
|
|
21
|
+
dropped: number;
|
|
22
|
+
/** Serialized byte size of the envelope built from the retained items. */
|
|
23
|
+
bytes: number;
|
|
24
|
+
/**
|
|
25
|
+
* True when even `minKeep` items still overflow the hard budget — the caller
|
|
26
|
+
* must surface this (a single oversized entry) rather than assume it fit.
|
|
27
|
+
*/
|
|
28
|
+
overBudget: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* v2.2 MC4-payload-budget (W1-T4): the byte-budget tail of the unified
|
|
32
|
+
* truncation chain (CJK → BM25 → top_k → payload). Rather than hard-throwing
|
|
33
|
+
* when a response overflows the hard limit, callers trim the LEAST-relevant
|
|
34
|
+
* items off the tail of an already-ranked list until the serialized envelope
|
|
35
|
+
* fits — turning a 413 crash into graceful degradation.
|
|
36
|
+
*
|
|
37
|
+
* `serialize` builds the FULL response envelope from a candidate slice (so the
|
|
38
|
+
* byte count includes warnings / metadata, not just the list). Trimming drops
|
|
39
|
+
* from the END, which is correct ONLY when the list is pre-ranked best-first
|
|
40
|
+
* (plan_context sorts by BM25 before calling this). `minKeep` (default 1)
|
|
41
|
+
* guarantees a non-empty result even under a pathological oversized head; in
|
|
42
|
+
* that case `overBudget` is returned true so the caller can warn instead of
|
|
43
|
+
* silently shipping an over-limit payload.
|
|
44
|
+
*/
|
|
45
|
+
declare function trimToPayloadBudget<T>(items: T[], serialize: (items: T[]) => string, opts?: PayloadGuardOptions & {
|
|
46
|
+
minKeep?: number;
|
|
47
|
+
}): PayloadBudgetTrimResult<T>;
|
|
17
48
|
|
|
18
|
-
export { PAYLOAD_LIMIT_DEFAULT_HARD_BYTES, PAYLOAD_LIMIT_DEFAULT_WARN_BYTES, type PayloadGuardOptions, type PayloadGuardResult, enforcePayloadLimit };
|
|
49
|
+
export { PAYLOAD_LIMIT_DEFAULT_HARD_BYTES, PAYLOAD_LIMIT_DEFAULT_WARN_BYTES, type PayloadBudgetTrimResult, type PayloadGuardOptions, type PayloadGuardResult, enforcePayloadLimit, trimToPayloadBudget };
|
|
@@ -37,8 +37,22 @@ function enforcePayloadLimit(serializedPayload, opts) {
|
|
|
37
37
|
}
|
|
38
38
|
return { bytes };
|
|
39
39
|
}
|
|
40
|
+
function trimToPayloadBudget(items, serialize, opts) {
|
|
41
|
+
const hardAt = opts?.hardBytes ?? DEFAULT_HARD;
|
|
42
|
+
const minKeep = Math.max(0, opts?.minKeep ?? 1);
|
|
43
|
+
let kept = items;
|
|
44
|
+
let bytes = Buffer.byteLength(serialize(kept), "utf8");
|
|
45
|
+
let dropped = 0;
|
|
46
|
+
while (bytes > hardAt && kept.length > minKeep) {
|
|
47
|
+
kept = kept.slice(0, -1);
|
|
48
|
+
dropped += 1;
|
|
49
|
+
bytes = Buffer.byteLength(serialize(kept), "utf8");
|
|
50
|
+
}
|
|
51
|
+
return { items: kept, dropped, bytes, overBudget: bytes > hardAt };
|
|
52
|
+
}
|
|
40
53
|
export {
|
|
41
54
|
PAYLOAD_LIMIT_DEFAULT_HARD_BYTES,
|
|
42
55
|
PAYLOAD_LIMIT_DEFAULT_WARN_BYTES,
|
|
43
|
-
enforcePayloadLimit
|
|
56
|
+
enforcePayloadLimit,
|
|
57
|
+
trimToPayloadBudget
|
|
44
58
|
};
|
|
@@ -104,38 +104,41 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
104
104
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
105
105
|
relevance_scope: z.ZodOptional<z.ZodEnum<["narrow", "broad"]>>;
|
|
106
106
|
relevance_paths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
107
|
+
related: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
107
108
|
}, "strip", z.ZodTypeAny, {
|
|
108
109
|
summary: string;
|
|
109
110
|
intent_clues: string[];
|
|
110
111
|
tech_stack: string[];
|
|
111
112
|
impact: string[];
|
|
112
113
|
must_read_if: string;
|
|
114
|
+
created_at?: string | undefined;
|
|
115
|
+
id?: string | undefined;
|
|
113
116
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
114
117
|
relevance_paths?: string[] | undefined;
|
|
115
118
|
entities?: string[] | undefined;
|
|
116
|
-
id?: string | undefined;
|
|
117
119
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
118
120
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
119
121
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
120
122
|
layer_reason?: string | undefined;
|
|
121
|
-
created_at?: string | undefined;
|
|
122
123
|
tags?: string[] | undefined;
|
|
124
|
+
related?: string[] | undefined;
|
|
123
125
|
}, {
|
|
124
126
|
summary: string;
|
|
125
127
|
intent_clues: string[];
|
|
126
128
|
tech_stack: string[];
|
|
127
129
|
impact: string[];
|
|
128
130
|
must_read_if: string;
|
|
131
|
+
created_at?: string | undefined;
|
|
132
|
+
id?: string | undefined;
|
|
129
133
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
130
134
|
relevance_paths?: string[] | undefined;
|
|
131
135
|
entities?: string[] | undefined;
|
|
132
|
-
id?: string | undefined;
|
|
133
136
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
134
137
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
135
138
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
136
139
|
layer_reason?: string | undefined;
|
|
137
|
-
created_at?: string | undefined;
|
|
138
140
|
tags?: string[] | undefined;
|
|
141
|
+
related?: string[] | undefined;
|
|
139
142
|
}>;
|
|
140
143
|
}, "strip", z.ZodTypeAny, {
|
|
141
144
|
description: {
|
|
@@ -144,16 +147,17 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
144
147
|
tech_stack: string[];
|
|
145
148
|
impact: string[];
|
|
146
149
|
must_read_if: string;
|
|
150
|
+
created_at?: string | undefined;
|
|
151
|
+
id?: string | undefined;
|
|
147
152
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
148
153
|
relevance_paths?: string[] | undefined;
|
|
149
154
|
entities?: string[] | undefined;
|
|
150
|
-
id?: string | undefined;
|
|
151
155
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
152
156
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
153
157
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
154
158
|
layer_reason?: string | undefined;
|
|
155
|
-
created_at?: string | undefined;
|
|
156
159
|
tags?: string[] | undefined;
|
|
160
|
+
related?: string[] | undefined;
|
|
157
161
|
};
|
|
158
162
|
stable_id: string;
|
|
159
163
|
}, {
|
|
@@ -163,19 +167,21 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
163
167
|
tech_stack: string[];
|
|
164
168
|
impact: string[];
|
|
165
169
|
must_read_if: string;
|
|
170
|
+
created_at?: string | undefined;
|
|
171
|
+
id?: string | undefined;
|
|
166
172
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
167
173
|
relevance_paths?: string[] | undefined;
|
|
168
174
|
entities?: string[] | undefined;
|
|
169
|
-
id?: string | undefined;
|
|
170
175
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
171
176
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
172
177
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
173
178
|
layer_reason?: string | undefined;
|
|
174
|
-
created_at?: string | undefined;
|
|
175
179
|
tags?: string[] | undefined;
|
|
180
|
+
related?: string[] | undefined;
|
|
176
181
|
};
|
|
177
182
|
stable_id: string;
|
|
178
183
|
}>, "many">;
|
|
184
|
+
omitted_candidate_count: z.ZodOptional<z.ZodNumber>;
|
|
179
185
|
preflight_diagnostics: z.ZodArray<z.ZodObject<{
|
|
180
186
|
code: z.ZodEnum<["missing_description", "empty_shell_suppressed"]>;
|
|
181
187
|
severity: z.ZodLiteral<"warn">;
|
|
@@ -234,16 +240,17 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
234
240
|
tech_stack: string[];
|
|
235
241
|
impact: string[];
|
|
236
242
|
must_read_if: string;
|
|
243
|
+
created_at?: string | undefined;
|
|
244
|
+
id?: string | undefined;
|
|
237
245
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
238
246
|
relevance_paths?: string[] | undefined;
|
|
239
247
|
entities?: string[] | undefined;
|
|
240
|
-
id?: string | undefined;
|
|
241
248
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
242
249
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
243
250
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
244
251
|
layer_reason?: string | undefined;
|
|
245
|
-
created_at?: string | undefined;
|
|
246
252
|
tags?: string[] | undefined;
|
|
253
|
+
related?: string[] | undefined;
|
|
247
254
|
};
|
|
248
255
|
stable_id: string;
|
|
249
256
|
}[];
|
|
@@ -254,6 +261,7 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
254
261
|
path?: string | undefined;
|
|
255
262
|
stable_ids?: string[] | undefined;
|
|
256
263
|
}[];
|
|
264
|
+
omitted_candidate_count?: number | undefined;
|
|
257
265
|
warnings?: {
|
|
258
266
|
code: string;
|
|
259
267
|
file: string;
|
|
@@ -283,16 +291,17 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
283
291
|
tech_stack: string[];
|
|
284
292
|
impact: string[];
|
|
285
293
|
must_read_if: string;
|
|
294
|
+
created_at?: string | undefined;
|
|
295
|
+
id?: string | undefined;
|
|
286
296
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
287
297
|
relevance_paths?: string[] | undefined;
|
|
288
298
|
entities?: string[] | undefined;
|
|
289
|
-
id?: string | undefined;
|
|
290
299
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
291
300
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
292
301
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
293
302
|
layer_reason?: string | undefined;
|
|
294
|
-
created_at?: string | undefined;
|
|
295
303
|
tags?: string[] | undefined;
|
|
304
|
+
related?: string[] | undefined;
|
|
296
305
|
};
|
|
297
306
|
stable_id: string;
|
|
298
307
|
}[];
|
|
@@ -303,6 +312,7 @@ declare const planContextOutputSchema: z.ZodObject<{
|
|
|
303
312
|
path?: string | undefined;
|
|
304
313
|
stable_ids?: string[] | undefined;
|
|
305
314
|
}[];
|
|
315
|
+
omitted_candidate_count?: number | undefined;
|
|
306
316
|
warnings?: {
|
|
307
317
|
code: string;
|
|
308
318
|
file: string;
|
|
@@ -327,13 +337,13 @@ declare const planContextHintNarrowEntrySchema: z.ZodObject<{
|
|
|
327
337
|
summary: z.ZodString;
|
|
328
338
|
}, "strip", z.ZodTypeAny, {
|
|
329
339
|
type: string;
|
|
330
|
-
summary: string;
|
|
331
340
|
id: string;
|
|
341
|
+
summary: string;
|
|
332
342
|
maturity: string;
|
|
333
343
|
}, {
|
|
334
344
|
type: string;
|
|
335
|
-
summary: string;
|
|
336
345
|
id: string;
|
|
346
|
+
summary: string;
|
|
337
347
|
maturity: string;
|
|
338
348
|
}>;
|
|
339
349
|
declare const planContextHintOutputSchema: z.ZodObject<{
|
|
@@ -347,21 +357,21 @@ declare const planContextHintOutputSchema: z.ZodObject<{
|
|
|
347
357
|
summary: z.ZodString;
|
|
348
358
|
}, "strip", z.ZodTypeAny, {
|
|
349
359
|
type: string;
|
|
350
|
-
summary: string;
|
|
351
360
|
id: string;
|
|
361
|
+
summary: string;
|
|
352
362
|
maturity: string;
|
|
353
363
|
}, {
|
|
354
364
|
type: string;
|
|
355
|
-
summary: string;
|
|
356
365
|
id: string;
|
|
366
|
+
summary: string;
|
|
357
367
|
maturity: string;
|
|
358
368
|
}>, "many">;
|
|
359
369
|
broad_count: z.ZodNumber;
|
|
360
370
|
}, "strip", z.ZodTypeAny, {
|
|
361
371
|
narrow: {
|
|
362
372
|
type: string;
|
|
363
|
-
summary: string;
|
|
364
373
|
id: string;
|
|
374
|
+
summary: string;
|
|
365
375
|
maturity: string;
|
|
366
376
|
}[];
|
|
367
377
|
target_paths: string[];
|
|
@@ -371,8 +381,8 @@ declare const planContextHintOutputSchema: z.ZodObject<{
|
|
|
371
381
|
}, {
|
|
372
382
|
narrow: {
|
|
373
383
|
type: string;
|
|
374
|
-
summary: string;
|
|
375
384
|
id: string;
|
|
385
|
+
summary: string;
|
|
376
386
|
maturity: string;
|
|
377
387
|
}[];
|
|
378
388
|
target_paths: string[];
|
|
@@ -527,6 +537,7 @@ declare const recallInputSchema: z.ZodObject<{
|
|
|
527
537
|
layer_filter: z.ZodOptional<z.ZodEnum<["team", "personal", "both"]>>;
|
|
528
538
|
target_paths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
529
539
|
ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
540
|
+
include_related: z.ZodOptional<z.ZodBoolean>;
|
|
530
541
|
}, "strip", z.ZodTypeAny, {
|
|
531
542
|
paths: string[];
|
|
532
543
|
known_tech?: string[] | undefined;
|
|
@@ -538,6 +549,7 @@ declare const recallInputSchema: z.ZodObject<{
|
|
|
538
549
|
layer_filter?: "personal" | "team" | "both" | undefined;
|
|
539
550
|
target_paths?: string[] | undefined;
|
|
540
551
|
ids?: string[] | undefined;
|
|
552
|
+
include_related?: boolean | undefined;
|
|
541
553
|
}, {
|
|
542
554
|
paths: string[];
|
|
543
555
|
known_tech?: string[] | undefined;
|
|
@@ -549,6 +561,7 @@ declare const recallInputSchema: z.ZodObject<{
|
|
|
549
561
|
layer_filter?: "personal" | "team" | "both" | undefined;
|
|
550
562
|
target_paths?: string[] | undefined;
|
|
551
563
|
ids?: string[] | undefined;
|
|
564
|
+
include_related?: boolean | undefined;
|
|
552
565
|
}>;
|
|
553
566
|
declare const recallOutputSchema: z.ZodObject<{
|
|
554
567
|
revision_hash: z.ZodString;
|
|
@@ -607,38 +620,41 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
607
620
|
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
608
621
|
relevance_scope: z.ZodOptional<z.ZodEnum<["narrow", "broad"]>>;
|
|
609
622
|
relevance_paths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
623
|
+
related: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
610
624
|
}, "strip", z.ZodTypeAny, {
|
|
611
625
|
summary: string;
|
|
612
626
|
intent_clues: string[];
|
|
613
627
|
tech_stack: string[];
|
|
614
628
|
impact: string[];
|
|
615
629
|
must_read_if: string;
|
|
630
|
+
created_at?: string | undefined;
|
|
631
|
+
id?: string | undefined;
|
|
616
632
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
617
633
|
relevance_paths?: string[] | undefined;
|
|
618
634
|
entities?: string[] | undefined;
|
|
619
|
-
id?: string | undefined;
|
|
620
635
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
621
636
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
622
637
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
623
638
|
layer_reason?: string | undefined;
|
|
624
|
-
created_at?: string | undefined;
|
|
625
639
|
tags?: string[] | undefined;
|
|
640
|
+
related?: string[] | undefined;
|
|
626
641
|
}, {
|
|
627
642
|
summary: string;
|
|
628
643
|
intent_clues: string[];
|
|
629
644
|
tech_stack: string[];
|
|
630
645
|
impact: string[];
|
|
631
646
|
must_read_if: string;
|
|
647
|
+
created_at?: string | undefined;
|
|
648
|
+
id?: string | undefined;
|
|
632
649
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
633
650
|
relevance_paths?: string[] | undefined;
|
|
634
651
|
entities?: string[] | undefined;
|
|
635
|
-
id?: string | undefined;
|
|
636
652
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
637
653
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
638
654
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
639
655
|
layer_reason?: string | undefined;
|
|
640
|
-
created_at?: string | undefined;
|
|
641
656
|
tags?: string[] | undefined;
|
|
657
|
+
related?: string[] | undefined;
|
|
642
658
|
}>;
|
|
643
659
|
}, "strip", z.ZodTypeAny, {
|
|
644
660
|
description: {
|
|
@@ -647,16 +663,17 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
647
663
|
tech_stack: string[];
|
|
648
664
|
impact: string[];
|
|
649
665
|
must_read_if: string;
|
|
666
|
+
created_at?: string | undefined;
|
|
667
|
+
id?: string | undefined;
|
|
650
668
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
651
669
|
relevance_paths?: string[] | undefined;
|
|
652
670
|
entities?: string[] | undefined;
|
|
653
|
-
id?: string | undefined;
|
|
654
671
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
655
672
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
656
673
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
657
674
|
layer_reason?: string | undefined;
|
|
658
|
-
created_at?: string | undefined;
|
|
659
675
|
tags?: string[] | undefined;
|
|
676
|
+
related?: string[] | undefined;
|
|
660
677
|
};
|
|
661
678
|
stable_id: string;
|
|
662
679
|
}, {
|
|
@@ -666,19 +683,21 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
666
683
|
tech_stack: string[];
|
|
667
684
|
impact: string[];
|
|
668
685
|
must_read_if: string;
|
|
686
|
+
created_at?: string | undefined;
|
|
687
|
+
id?: string | undefined;
|
|
669
688
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
670
689
|
relevance_paths?: string[] | undefined;
|
|
671
690
|
entities?: string[] | undefined;
|
|
672
|
-
id?: string | undefined;
|
|
673
691
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
674
692
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
675
693
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
676
694
|
layer_reason?: string | undefined;
|
|
677
|
-
created_at?: string | undefined;
|
|
678
695
|
tags?: string[] | undefined;
|
|
696
|
+
related?: string[] | undefined;
|
|
679
697
|
};
|
|
680
698
|
stable_id: string;
|
|
681
699
|
}>, "many">;
|
|
700
|
+
omitted_candidate_count: z.ZodOptional<z.ZodNumber>;
|
|
682
701
|
preflight_diagnostics: z.ZodArray<z.ZodObject<{
|
|
683
702
|
code: z.ZodEnum<["missing_description", "empty_shell_suppressed"]>;
|
|
684
703
|
severity: z.ZodLiteral<"warn">;
|
|
@@ -750,6 +769,18 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
750
769
|
auto_healed: z.ZodOptional<z.ZodBoolean>;
|
|
751
770
|
previous_revision_hash: z.ZodOptional<z.ZodString>;
|
|
752
771
|
redirects: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
772
|
+
directive: z.ZodString;
|
|
773
|
+
next_steps: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
774
|
+
truncation: z.ZodOptional<z.ZodObject<{
|
|
775
|
+
omitted_candidate_count: z.ZodNumber;
|
|
776
|
+
returned_candidate_count: z.ZodNumber;
|
|
777
|
+
}, "strip", z.ZodTypeAny, {
|
|
778
|
+
omitted_candidate_count: number;
|
|
779
|
+
returned_candidate_count: number;
|
|
780
|
+
}, {
|
|
781
|
+
omitted_candidate_count: number;
|
|
782
|
+
returned_candidate_count: number;
|
|
783
|
+
}>>;
|
|
753
784
|
}, "strip", z.ZodTypeAny, {
|
|
754
785
|
entries: {
|
|
755
786
|
path: string;
|
|
@@ -770,16 +801,17 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
770
801
|
tech_stack: string[];
|
|
771
802
|
impact: string[];
|
|
772
803
|
must_read_if: string;
|
|
804
|
+
created_at?: string | undefined;
|
|
805
|
+
id?: string | undefined;
|
|
773
806
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
774
807
|
relevance_paths?: string[] | undefined;
|
|
775
808
|
entities?: string[] | undefined;
|
|
776
|
-
id?: string | undefined;
|
|
777
809
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
778
810
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
779
811
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
780
812
|
layer_reason?: string | undefined;
|
|
781
|
-
created_at?: string | undefined;
|
|
782
813
|
tags?: string[] | undefined;
|
|
814
|
+
related?: string[] | undefined;
|
|
783
815
|
};
|
|
784
816
|
stable_id: string;
|
|
785
817
|
}[];
|
|
@@ -803,6 +835,8 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
803
835
|
stable_id: string;
|
|
804
836
|
severity: "warn";
|
|
805
837
|
}[];
|
|
838
|
+
directive: string;
|
|
839
|
+
omitted_candidate_count?: number | undefined;
|
|
806
840
|
warnings?: {
|
|
807
841
|
code: string;
|
|
808
842
|
file: string;
|
|
@@ -812,6 +846,11 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
812
846
|
auto_healed?: boolean | undefined;
|
|
813
847
|
previous_revision_hash?: string | undefined;
|
|
814
848
|
redirects?: Record<string, string> | undefined;
|
|
849
|
+
next_steps?: string[] | undefined;
|
|
850
|
+
truncation?: {
|
|
851
|
+
omitted_candidate_count: number;
|
|
852
|
+
returned_candidate_count: number;
|
|
853
|
+
} | undefined;
|
|
815
854
|
}, {
|
|
816
855
|
entries: {
|
|
817
856
|
path: string;
|
|
@@ -832,16 +871,17 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
832
871
|
tech_stack: string[];
|
|
833
872
|
impact: string[];
|
|
834
873
|
must_read_if: string;
|
|
874
|
+
created_at?: string | undefined;
|
|
875
|
+
id?: string | undefined;
|
|
835
876
|
relevance_scope?: "narrow" | "broad" | undefined;
|
|
836
877
|
relevance_paths?: string[] | undefined;
|
|
837
878
|
entities?: string[] | undefined;
|
|
838
|
-
id?: string | undefined;
|
|
839
879
|
knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
|
|
840
880
|
maturity?: "draft" | "verified" | "proven" | undefined;
|
|
841
881
|
knowledge_layer?: "personal" | "team" | undefined;
|
|
842
882
|
layer_reason?: string | undefined;
|
|
843
|
-
created_at?: string | undefined;
|
|
844
883
|
tags?: string[] | undefined;
|
|
884
|
+
related?: string[] | undefined;
|
|
845
885
|
};
|
|
846
886
|
stable_id: string;
|
|
847
887
|
}[];
|
|
@@ -865,6 +905,8 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
865
905
|
stable_id: string;
|
|
866
906
|
severity: "warn";
|
|
867
907
|
}[];
|
|
908
|
+
directive: string;
|
|
909
|
+
omitted_candidate_count?: number | undefined;
|
|
868
910
|
warnings?: {
|
|
869
911
|
code: string;
|
|
870
912
|
file: string;
|
|
@@ -874,6 +916,11 @@ declare const recallOutputSchema: z.ZodObject<{
|
|
|
874
916
|
auto_healed?: boolean | undefined;
|
|
875
917
|
previous_revision_hash?: string | undefined;
|
|
876
918
|
redirects?: Record<string, string> | undefined;
|
|
919
|
+
next_steps?: string[] | undefined;
|
|
920
|
+
truncation?: {
|
|
921
|
+
omitted_candidate_count: number;
|
|
922
|
+
returned_candidate_count: number;
|
|
923
|
+
} | undefined;
|
|
877
924
|
}>;
|
|
878
925
|
declare const recallAnnotations: {
|
|
879
926
|
readonly readOnlyHint: true;
|
|
@@ -2305,18 +2352,18 @@ declare const KnowledgeEntryFrontmatterSchema: z.ZodObject<{
|
|
|
2305
2352
|
layer_reason: z.ZodOptional<z.ZodString>;
|
|
2306
2353
|
created_at: z.ZodString;
|
|
2307
2354
|
}, "strip", z.ZodTypeAny, {
|
|
2355
|
+
created_at: string;
|
|
2308
2356
|
type: "models" | "decisions" | "guidelines" | "pitfalls" | "processes";
|
|
2309
|
-
layer: "personal" | "team";
|
|
2310
2357
|
id: string;
|
|
2358
|
+
layer: "personal" | "team";
|
|
2311
2359
|
maturity: "draft" | "verified" | "proven";
|
|
2312
|
-
created_at: string;
|
|
2313
2360
|
layer_reason?: string | undefined;
|
|
2314
2361
|
}, {
|
|
2362
|
+
created_at: string;
|
|
2315
2363
|
type: "models" | "decisions" | "guidelines" | "pitfalls" | "processes";
|
|
2316
|
-
layer: "personal" | "team";
|
|
2317
2364
|
id: string;
|
|
2365
|
+
layer: "personal" | "team";
|
|
2318
2366
|
maturity: "draft" | "verified" | "proven";
|
|
2319
|
-
created_at: string;
|
|
2320
2367
|
layer_reason?: string | undefined;
|
|
2321
2368
|
}>;
|
|
2322
2369
|
type KnowledgeEntryFrontmatter = z.infer<typeof KnowledgeEntryFrontmatterSchema>;
|
|
@@ -51,6 +51,6 @@ declare const LEGACY_KB_REGEX: RegExp;
|
|
|
51
51
|
*
|
|
52
52
|
* Length guarantee: ≥ 800 bytes (rc.24: grew from ≥400 with cite-contract syntax).
|
|
53
53
|
*/
|
|
54
|
-
declare const BOOTSTRAP_CANONICAL = "# Fabric Bootstrap\n\n\u672C\u9879\u76EE\u4F7F\u7528 Fabric \u7BA1\u7406\u8DE8\u5BA2\u6237\u7AEF AI \u77E5\u8BC6\u4E0E\u884C\u4E3A\u89C4\u5219\u3002\u672C\u6587\u4EF6\u7531 `fabric install` \u540C\u6B65\u5230\u4E09\u7AEF managed block,**\u4E0D\u8981\u624B\u52A8\u7F16\u8F91\u4E09\u7AEF\u7684 block**,\u53EA\u6539\u8FD9\u91CC + \u91CD\u8DD1 `fabric install`\u3002\n\n## For Developers\n\n\u8FD9\u4E2A\u6587\u4EF6\u662F **AI \u5BA2\u6237\u7AEF\u7684\u7B56\u7565\u4E0E\u89C4\u7EA6\u914D\u7F6E**,\u4E0D\u662F dev onboarding\u3002\u4F60\u4E0D\u9700\u8981\u8BFB Self-archive / Cite / Phase 0.4 \u7B49\u7EC6\u8282\u3002\n\u4F5C\u4E3A dev \u4F60\u53EA\u9700\u8981:\u5728\u6BCF\u4E2A repo \u8DD1\u4E00\u6B21 `fabric install`,\u51FA\u95EE\u9898\u8DD1 `fabric doctor`,\u5728 `.fabric/knowledge/<type>/` \u4E0B\u5199 markdown\u3002\n**\u4E25\u7981\u624B\u52A8\u7F16\u8F91 `.fabric/agents.meta.json`** \u2014 \u6D3E\u751F\u72B6\u6001\u7531 engine \u91CD\u5EFA\u3002\n\n## 5 \u5206\u949F\u4E0A\u624B (Dev Quickstart)\n\n**Fabric \u662F\u4EC0\u4E48**:\u8DE8\u5BA2\u6237\u7AEF(Claude Code / Codex CLI / Cursor)\u7684 AI \u77E5\u8BC6\u5C42\u3002\u628A\u56E2\u961F/\u9879\u76EE\u7684 **decisions / pitfalls / guidelines / models / processes** \u5B58\u4E3A markdown,hook \u81EA\u52A8 surface \u7ED9 AI,\u8BA9 AI \u4E0D\u7528\u6BCF\u6B21\u91CD\u5B66\u3002\n\n**\u4F60\u8981\u505A\u7684 (DO)** vs **engine \u81EA\u52A8\u7684 (DON'T \u624B\u52A8)**:\n\n| \u4F60 DO | \u4F60 DON'T |\n| --- | --- |\n| \u6BCF\u4E2A repo \u8DD1\u4E00\u6B21 `fabric install` | \u624B\u7F16 `.fabric/agents.meta.json` |\n| \u5F02\u5E38\u65F6\u8DD1 `fabric doctor` (--fix \u81EA\u6108) | \u624B\u7F16 `.claude/hooks/` \u4E0B `.cjs` |\n| \u5728 `.fabric/knowledge/<type>/` \u4E0B\u5199 markdown | \u64CD\u5FC3 Phase 0.4 / E3 / cite policy |\n| `npm install -g @fenglimg/fabric-cli@latest` \u5347\u7EA7 | \u80CC 35 \u6761 doctor lint \u4EE3\u7801 |\n\n**4 \u6B65\u5FAA\u73AF**: `fabric install` (\u4E00\u6B21) \u2192 AI \u6B63\u5E38\u5DE5\u4F5C (hook on session start + edit) \u2192 AI \u63D0\u8BAE\u6761\u76EE\u5165 `.fabric/knowledge/pending/` \u2192 \u7528 `fabric-review` skill \u6216 `fabric doctor --fix` \u5BA1\u6838\u5F52\u6863\u3002\n\n**\u771F\u4F8B**:\u67D0 sprite \u9ED1\u8FB9 root cause \u662F `atlas.premultiplyAlpha` flag \u53CD\u5411 \u2014 \u5199\u8FDB `.fabric/knowledge/pitfalls/` \u540E,\u4E0B\u6B21\u540C\u7C7B\u95EE\u9898 AI \u81EA\u52A8 reference\u3002\n\n\u5B8C\u6574 maintainer \u7248\u89C1 `docs/USER-QUICKSTART.md`\u3002\n\n## \u884C\u4E3A\u89C4\u5219\n- **\u4FEE\u6539\u4EFB\u4F55\u6587\u4EF6\u524D**:\u4F18\u5148\u5355\u6B65 `fab_recall(paths=[<\u88AB\u6539\u6587\u4EF6>])` \u2014\u2014 \u4E00\u6B21\u8C03\u7528\u76F4\u63A5\u62FF\u56DE\u6240\u6709\u76F8\u5173 KB \u6B63\u6587(rc.37+ \u9ED8\u8BA4\u8DEF\u5F84,\u7701\u6389\u624B\u52A8\u6311 id \u7684\u73AF\u8282)\u3002**\u4EC5\u5F53\u5355\u6B65\u62C9\u56DE\u7684\u6B63\u6587\u8FC7\u591A\u3001\u5BFC\u81F4\u4E0A\u4E0B\u6587\u8FC7\u8F7D\u9700\u7CBE\u786E\u88C1\u526A\u566A\u97F3\u65F6**\u624D\u8D70\u4E24\u6B65:\u5148 `fab_plan_context(paths=[...])` \u62FF `selection_token` + \u9876\u5C42 `candidates[]`(\u4ECE `candidates[].stable_id` \u6311),\u518D `fab_get_knowledge_sections({ selection_token, ai_selected_stable_ids: [<id>...] })` \u53D6\u6B63\u6587\u3002\n- **`.fabric/agents.meta.json` \u4E25\u7981\u624B\u52A8\u7F16\u8F91**;engine \u4F1A\u81EA\u52A8\u540C\u6B65\u6D3E\u751F\u72B6\u6001,\u663E\u5F0F reconcile \u8DD1 `fabric doctor --fix`\u3002\n\n## \u77E5\u8BC6\u5E93(KB)\n- **Discovery**:SessionStart hook \u5217 broad-scoped \u6761\u76EE(\u542B personal layer `KP-*` \u6761\u76EE,\u5F15\u7528\u65B9\u5F0F\u76F8\u540C);edit \u6587\u4EF6\u65F6 PreToolUse hook \u53EF\u80FD\u89E6\u53D1 narrow hint\u3002\n- **Usage**:\u5E38\u6001\u8D70\u5355\u6B65 `fab_recall(paths=[...])` \u4E00\u6B21\u62FF\u56DE\u76F8\u5173 KB \u6B63\u6587\u3002\u4EC5\u5F53\u5355\u6B65\u6B63\u6587\u8FC7\u591A\u81F4\u4E0A\u4E0B\u6587\u8FC7\u8F7D\u3001\u9700\u7CBE\u786E\u88C1\u526A\u566A\u97F3\u65F6\u624D\u4E24\u6B65:`fab_plan_context(paths=[...])` \u8FD4\u56DE `selection_token` + \u9876\u5C42 `candidates[]`,\u518D `fab_get_knowledge_sections({ selection_token, ai_selected_stable_ids: [<\u4ECE candidates[].stable_id \u6311>...] })` \u62C9\u5168\u6587;`selection_token` \u5FC5\u987B\u6765\u81EA\u6700\u8FD1\u4E00\u6B21 `fab_plan_context`,\u4E0D\u53EF\u51ED\u7A7A\u7F16\u9020\u3002\n- **session_id**: \u8C03\u7528 `fab_recall` / `fab_plan_context` \u65F6, \u52A1\u5FC5\u628A\u5F53\u524D client session id \u4F5C\u4E3A `session_id` \u53C2\u6570\u4F20\u5165(Claude Code \u7684 session id \u5728 stdin payload \u4E2D, Codex \u7684\u5BF9\u5E94 identifier \u540C\u7406)\u3002\u8FD9\u80FD\u8BA9 `fabric doctor --archive-history` \u4E0E archive-hint hook \u51C6\u786E\u8BC6\u522B\u8DE8\u4F1A\u8BDD debt \u72B6\u6001\u3002\n- **Write flows**:`fabric-archive` / `fabric-review` / `fabric-import` \u4E09\u4E2A Skills\u3002\n- **Language**:\u6E32\u67D3\u6309 `.fabric/fabric-config.json` \u7684 `fabric_language` \u5B57\u6BB5\u3002\n- **Archive cadence nudge** (rc.36): \u6BCF\u5B8C\u6210 5+ \u6B21 Edit / \u663E\u8457 decision \u540E,\u5728\u5408\u9002\u56DE\u5408\u4E3B\u52A8 propose \u8C03 `fabric-archive` skill \u2014 archive \u6CA1\u5EFA\u7ACB\u9891\u7387\u4F1A\u8BA9 KB \u6162\u901F\u6B7B\u6389\u3002\n- **Review backlog nudge** (rc.36): `.fabric/knowledge/pending/` \u7D2F\u79EF >10 \u6761\u65F6,\u5728\u5408\u9002\u56DE\u5408\u4E3B\u52A8 propose \u8C03 `fabric-review` skill \u6279\u91CF\u5BA1,\u907F\u514D draft \u5361\u6B7B\u3002\n\n## Self-archive policy (v2.0.0-rc.37 NEW-2: \u7B80\u5316 4 \u4FE1\u53F7 \u2192 2 \u5927\u7C7B)\n\n- **\u89E6\u53D1** (\u672C\u4F1A\u8BDD\u51FA\u73B0\u4EE5\u4E0B\u4EFB\u4E00\u4FE1\u53F7, \u5728\u8BE5 turn \u56DE\u590D\u672B\u5C3E\u81EA\u4E3B\u8C03\u7528 `fabric-archive` skill, \u8D70 AI \u81EA\u89E6\u53D1\u5165\u53E3 E3_ai_self_trigger):\n 1. **User-driven normative** \u2014 \u7528\u6237\u6D88\u606F\u4E2D\u663E\u5F0F\u8868\u8FBE normative \u610F\u56FE: `\u4EE5\u540E` / `always` / `never` / `from now on` / `\u4E0B\u6B21\u6CE8\u610F` / `\u8BB0\u4E00\u4E0B` / `\u6C38\u8FDC\u4E0D\u8981`, OR \u7528\u6237\u5728 \u22652 \u5019\u9009\u95F4\u6743\u8861\u540E\u7ED9\u51FA rationale \u9501\u5B9A\u65B9\u5411, OR \u7528\u6237\u62D2\u4E86\u67D0\u5EFA\u8BAE**\u5E76**\u8BF4\u4E86\u539F\u56E0 (\u62D2\u7EDD\u7406\u7531\u672C\u8EAB\u662F\u77E5\u8BC6)\n 2. **Wrong-turn-and-revert** \u2014 AI \u5C1D\u8BD5 path X, \u53CD\u601D\u540E\u6539\u8D70 path Y (\u5C24\u5176\u5F53 path X \u662F\u975E\u663E\u7136\u8E29\u5751); \u6DB5\u76D6\u6280\u672F\u51B3\u7B56\u53CD\u8F6C + \u5DE5\u5177/\u8303\u5F0F\u5207\u6362 + \u5931\u8D25\u91CD\u8BD5\u3002Anchor: \u4E00\u5B9A\u6709\"\u5426\u5B9A+\u66FF\u4EE3\"\u7684\u4E24\u6B65\u7ED3\u6784, \u4E0D\u662F\u5355\u7EAF\u63A2\u7D22\u5931\u8D25\n\n \u8001 4-state (Normative / Decision-confirmation / Explicit-dismissal / Wrong-turn) \u73B0\u5408\u5E76: \u524D 3 \u4E2A\u5168\u662F\"\u7528\u6237\u6D88\u606F\u4E2D\u663E\u5F0F\u8868\u8FBE\"\u6027\u8D28, \u6298\u6210 1 \u7C7B; \u7B2C 4 \u662F\"AI \u81EA\u5DF1\u7684\u53CD\u601D\u8DEF\u5F84\", \u72EC\u7ACB 1 \u7C7B\u3002\u4E24\u7C7B\u5404\u81EA\u7684\u672C\u8D28\u5224\u522B\u4E0D\u53D8, \u89E6\u53D1\u9762\u6CA1\u53D8\u7A84\u3002\n\n- **Anti-trigger** (\u660E\u786E\u4E0D\u89E6\u53D1):\n - \u7528\u6237\u7EAF\u8BE2\u95EE (\u65E0 normative \u8868\u8FBE)\n - \u7B80\u5355 refactor / typo fix\n - AI \u81EA\u5DF1\u4EA7\u751F\u7684'\u6D1E\u5BDF' (\u5FC5\u987B\u7531\u7528\u6237\u6D88\u606F\u4E2D\u4FE1\u53F7\u6216 AI \u81EA\u5DF1\u7684 wrong-turn \u89E6\u53D1, \u4E0D\u662F\u51ED\u7A7A\"\u6211\u5B66\u5230\u4E86\"\u6027\u8D28)\n\n- **Anti-loop \u4E09\u6761\u9632\u62A4**:\n - \u540C turn \u6700\u591A\u81EA\u8C03 1 \u6B21\n - \u540C session \u540C outcome \u4E0D\u91CD\u590D (\u82E5 user_dismissed, \u672C\u4F1A\u8BDD\u4E0D\u518D\u81EA\u8C03\u76F8\u540C\u4E3B\u9898)\n - Phase 2.5 viability gate \u515C\u5E95 (skill \u5185\u90E8\u4ECD\u8DD1 gate, AI \u5224\u9519\u4E0D\u4F1A\u4E71\u5199 pending)\n\n- **\u5448\u73B0\u6A21\u677F** (turn \u672B\u5C3E\u63D2\u5165, \u4E24\u884C: \u5148 marker \u884C\u4F9B Phase 1.5 \u68C0\u6D4B, \u518D user-facing \u63D0\u793A):\n ```\n self-archive policy triggered by signal: <User-driven normative|Wrong-turn-and-revert>\n \u987A\u624B\u5F52\u6863: \u6CE8\u610F\u5230\u4F60\u8BF4 `<\u89E6\u53D1\u77ED\u8BED>`, \u5DF2\u8C03\u7528 fabric-archive \u6293 N \u6761\u5019\u9009 \u2192 .fabric/knowledge/pending/...\n \u82E5\u4E0D\u8BE5\u8BB0, \u7B54 '\u64A4\u9500' \u6211\u4F1A\u8C03 fab_review reject\u3002\n ```\n \u7B2C\u4E00\u884C\u662F Phase 1.5 Trigger Gate \u8BC6\u522B E3 \u5165\u53E3\u7684 structured marker (verbatim \u5B57\u7B26\u4E32 `self-archive policy triggered by signal`, \u540E\u63A5\u5192\u53F7 + \u89E6\u53D1\u4FE1\u53F7\u540D)\u3002\u7B2C\u4E8C\u884C\u8D77\u662F\u7ED9\u7528\u6237\u770B\u7684\u4E2D\u6587\u63D0\u793A\u3002\u4E24\u884C\u90FD\u5FC5\u987B\u51FA\u73B0; \u7F3A marker \u884C Phase 1.5 \u65E0\u6CD5\u8DEF\u7531\u5230 E3_ai_self_trigger\u3002\n\n Backward compat: Phase 1.5 entry-point regex \u540C\u65F6\u8BC6\u522B\u8001 4 \u4E2A\u4FE1\u53F7\u540D (Normative / Wrong-turn-and-revert / Decision confirmation / Explicit dismissal) \u4E0E\u65B0 2 \u5927\u7C7B\u540D, \u65E7 session marker \u4ECD\u80FD\u6B63\u786E\u8DEF\u7531\u3002\n\n## Cite policy (v2.0.0-rc.37 NEW-1: \u7B80\u5316 4-state \u2192 2-state)\n\n- **\u89E6\u53D1**: \u505A edit / decide / propose plan \u4E4B\u524D,**\u56DE\u590D\u9996\u884C**\u5FC5\u987B\u5199 `KB: <id> (<\u22648\u5B57 \u7528\u6CD5>) [applied|dismissed:<reason>]` \u6216 `KB: none [<reason>]`\u3002\n- **`[applied]` \u9A8C\u8BC1\u4E49\u52A1**: \u5F15\u7528\u4EFB\u4F55 id \u524D\u5FC5\u987B\u5148\u7528 fab_recall (\u6216\u4E24\u6B65 fab_plan_context \u2192 fab_get_knowledge_sections) \u5B9E\u9645\u6293 KB body, \u9632\u6B62\u7F16\u9020 id\u3002\u9A8C\u8BC1\u4E0D\u901A\u8FC7 = \u4E0D\u80FD cite\u3002\n- **contract \u8BED\u6CD5**: decisions/pitfalls \u7C7B `[applied]` cite \u5C3E\u6BB5\u52A0 contract: `\u2192 <operator> [<operator> ...]`,operator \u2208 {`edit:<glob>` `!edit:<glob>` `require:<symbol>` `forbid:<symbol>` `skip:<reason>`}\u3002\u4F8B:`KB: K-001 (auth) [applied] \u2192 edit:src/auth/**/*.ts !edit:src/legacy/**`\u3002\n- **skip reason \u8BCD\u5178**: `sequencing | conditional | semantic | aesthetic | architectural | other:<text>`\u3002\n- **type \u8DEF\u7531**: models \u7C7B\u5F15\u7528\u4E3A reference cite,\u4E0D\u9700\u8981 contract;guidelines/processes \u7C7B\u6682\u4E0D\u5F3A\u5236,\u63A8\u540E LLM-judge\u3002\n- **\u7528\u6237\u53E3\u5934\u63D0\u89C4\u5219\u6CA1\u7ED9 id**: \u5148\u8C03 `fab_recall(paths)` \u6216 `fab_extract_knowledge` \u53CD\u67E5\u3002\n- **dismissed reason**: \u679A\u4E3E `scope-mismatch | outdated | not-applicable | other:<text>`\u3002\n- **`KB: none` sentinel**: \u679A\u4E3E\u4E24\u79CD\u5408\u89C4\u7406\u7531\u2014\u2014`[no-relevant]` \u5DF2\u8C03 `fab_recall` / `fab_plan_context`(\u6216 hook \u8F93\u51FA\u53EF\u89C1)\u4F46\u65E0\u53EF\u7528\u6761\u76EE;`[not-applicable]` \u5F53\u524D\u52A8\u4F5C\u4E0D\u5728 cite \u8303\u56F4(\u7EAF\u63A2\u7D22 / Bash \u53EA\u8BFB / \u7528\u6237\u95EE\u7B54)\u3002\u88F8 `KB: none`(\u65E0\u540E\u7F00)\u4ECD\u7136 valid,\u5F52\u7C7B\u4E3A `[unspecified]`(legacy \u517C\u5BB9,\u9F13\u52B1\u540E\u7EED\u8865\u6CE8)\u3002\n- **\u7A3D\u6838**: `fabric doctor --cite-coverage [--since=7d] [--client=cc|codex|all]` \u8F93\u51FA cite \u8986\u76D6\u7387,\u542B `KB: none` sentinel \u62C6\u5206\u3002\u672C\u89C4\u5219\u4E0D\u963B\u65AD\u4F60\u5DE5\u4F5C,\u53EA\u8BB0\u5F55\u3002\n- **Backward compat**: \u89E3\u6790\u5668\u540C\u65F6\u63A5\u53D7\u8001 4-state tags (`planned` / `recalled` / `chained-from <id>`) \u2014 \u90FD\u6620\u5C04\u5230 `[applied]` \u8BED\u4E49,gradually \u8FC1\u5230\u65B0\u7B80\u5316\u5F62\u6001\u5373\u53EF,\u65E7 session \u7559\u4E0B\u7684 cite \u4ECD\u7136\u8BA1\u5165 cite-coverage\u3002\n";
|
|
54
|
+
declare const BOOTSTRAP_CANONICAL = "# Fabric Bootstrap\n\n\u672C\u9879\u76EE\u4F7F\u7528 Fabric \u7BA1\u7406\u8DE8\u5BA2\u6237\u7AEF AI \u77E5\u8BC6\u4E0E\u884C\u4E3A\u89C4\u5219\u3002\u672C\u6587\u4EF6\u7531 `fabric install` \u540C\u6B65\u5230\u4E09\u7AEF managed block,**\u4E0D\u8981\u624B\u52A8\u7F16\u8F91\u4E09\u7AEF\u7684 block**,\u53EA\u6539\u8FD9\u91CC + \u91CD\u8DD1 `fabric install`\u3002\n\n## For Developers\n\n\u8FD9\u4E2A\u6587\u4EF6\u662F **AI \u5BA2\u6237\u7AEF\u7684\u7B56\u7565\u4E0E\u89C4\u7EA6\u914D\u7F6E**,\u4E0D\u662F dev onboarding\u3002\u4F60\u4E0D\u9700\u8981\u8BFB Self-archive / Cite / Phase 0.4 \u7B49\u7EC6\u8282\u3002\n\u4F5C\u4E3A dev \u4F60\u53EA\u9700\u8981:\u5728\u6BCF\u4E2A repo \u8DD1\u4E00\u6B21 `fabric install`,\u51FA\u95EE\u9898\u8DD1 `fabric doctor`,\u5728 `.fabric/knowledge/<type>/` \u4E0B\u5199 markdown\u3002\n**\u4E25\u7981\u624B\u52A8\u7F16\u8F91 `.fabric/agents.meta.json`** \u2014 \u6D3E\u751F\u72B6\u6001\u7531 engine \u91CD\u5EFA\u3002\n\n## 5 \u5206\u949F\u4E0A\u624B (Dev Quickstart)\n\n**Fabric \u662F\u4EC0\u4E48**:\u8DE8\u5BA2\u6237\u7AEF(Claude Code / Codex CLI / Cursor)\u7684 AI \u77E5\u8BC6\u5C42\u3002\u628A\u56E2\u961F/\u9879\u76EE\u7684 **decisions / pitfalls / guidelines / models / processes** \u5B58\u4E3A markdown,hook \u81EA\u52A8 surface \u7ED9 AI,\u8BA9 AI \u4E0D\u7528\u6BCF\u6B21\u91CD\u5B66\u3002\n\n**\u4F60\u8981\u505A\u7684 (DO)** vs **engine \u81EA\u52A8\u7684 (DON'T \u624B\u52A8)**:\n\n| \u4F60 DO | \u4F60 DON'T |\n| --- | --- |\n| \u6BCF\u4E2A repo \u8DD1\u4E00\u6B21 `fabric install` | \u624B\u7F16 `.fabric/agents.meta.json` |\n| \u5F02\u5E38\u65F6\u8DD1 `fabric doctor` (--fix \u81EA\u6108) | \u624B\u7F16 `.claude/hooks/` \u4E0B `.cjs` |\n| \u5728 `.fabric/knowledge/<type>/` \u4E0B\u5199 markdown | \u64CD\u5FC3 Phase 0.4 / E3 / cite policy |\n| `npm install -g @fenglimg/fabric-cli@latest` \u5347\u7EA7 | \u80CC 35 \u6761 doctor lint \u4EE3\u7801 |\n\n**4 \u6B65\u5FAA\u73AF**: `fabric install` (\u4E00\u6B21) \u2192 AI \u6B63\u5E38\u5DE5\u4F5C (hook on session start + edit) \u2192 AI \u63D0\u8BAE\u6761\u76EE\u5165 `.fabric/knowledge/pending/` \u2192 \u7528 `fabric-review` skill \u6216 `fabric doctor --fix` \u5BA1\u6838\u5F52\u6863\u3002\n\n**\u771F\u4F8B**:\u67D0 sprite \u9ED1\u8FB9 root cause \u662F `atlas.premultiplyAlpha` flag \u53CD\u5411 \u2014 \u5199\u8FDB `.fabric/knowledge/pitfalls/` \u540E,\u4E0B\u6B21\u540C\u7C7B\u95EE\u9898 AI \u81EA\u52A8 reference\u3002\n\n\u5B8C\u6574 maintainer \u7248\u89C1 `docs/USER-QUICKSTART.md`\u3002\n\n## \u884C\u4E3A\u89C4\u5219\n- **\u4FEE\u6539\u4EFB\u4F55\u6587\u4EF6\u524D**:\u4F18\u5148\u5355\u6B65 `fab_recall(paths=[<\u88AB\u6539\u6587\u4EF6>])` \u2014\u2014 \u4E00\u6B21\u8C03\u7528\u76F4\u63A5\u62FF\u56DE\u6240\u6709\u76F8\u5173 KB \u6B63\u6587(rc.37+ \u9ED8\u8BA4\u8DEF\u5F84,\u7701\u6389\u624B\u52A8\u6311 id \u7684\u73AF\u8282)\u3002**\u4EC5\u5F53\u5355\u6B65\u62C9\u56DE\u7684\u6B63\u6587\u8FC7\u591A\u3001\u5BFC\u81F4\u4E0A\u4E0B\u6587\u8FC7\u8F7D\u9700\u7CBE\u786E\u88C1\u526A\u566A\u97F3\u65F6**\u624D\u8D70\u4E24\u6B65:\u5148 `fab_plan_context(paths=[...])` \u62FF `selection_token` + \u9876\u5C42 `candidates[]`(\u4ECE `candidates[].stable_id` \u6311),\u518D `fab_get_knowledge_sections({ selection_token, ai_selected_stable_ids: [<id>...] })` \u53D6\u6B63\u6587\u3002\n- **`.fabric/agents.meta.json` \u4E25\u7981\u624B\u52A8\u7F16\u8F91**;engine \u4F1A\u81EA\u52A8\u540C\u6B65\u6D3E\u751F\u72B6\u6001,\u663E\u5F0F reconcile \u8DD1 `fabric doctor --fix`\u3002\n\n## \u77E5\u8BC6\u5E93(KB)\n- **Discovery**:SessionStart hook \u5217 broad-scoped \u6761\u76EE(\u542B personal layer `KP-*` \u6761\u76EE,\u5F15\u7528\u65B9\u5F0F\u76F8\u540C);edit \u6587\u4EF6\u65F6 PreToolUse hook \u53EF\u80FD\u89E6\u53D1 narrow hint\u3002\n- **Usage**:\u5E38\u6001\u8D70\u5355\u6B65 `fab_recall(paths=[...])` \u4E00\u6B21\u62FF\u56DE\u76F8\u5173 KB \u6B63\u6587\u3002\u4EC5\u5F53\u5355\u6B65\u6B63\u6587\u8FC7\u591A\u81F4\u4E0A\u4E0B\u6587\u8FC7\u8F7D\u3001\u9700\u7CBE\u786E\u88C1\u526A\u566A\u97F3\u65F6\u624D\u4E24\u6B65:`fab_plan_context(paths=[...])` \u8FD4\u56DE `selection_token` + \u9876\u5C42 `candidates[]`,\u518D `fab_get_knowledge_sections({ selection_token, ai_selected_stable_ids: [<\u4ECE candidates[].stable_id \u6311>...] })` \u62C9\u5168\u6587;`selection_token` \u5FC5\u987B\u6765\u81EA\u6700\u8FD1\u4E00\u6B21 `fab_plan_context`,\u4E0D\u53EF\u51ED\u7A7A\u7F16\u9020\u3002\n- **session_id**: \u8C03\u7528 `fab_recall` / `fab_plan_context` \u65F6, \u52A1\u5FC5\u628A\u5F53\u524D client session id \u4F5C\u4E3A `session_id` \u53C2\u6570\u4F20\u5165(Claude Code \u7684 session id \u5728 stdin payload \u4E2D, Codex \u7684\u5BF9\u5E94 identifier \u540C\u7406)\u3002\u8FD9\u80FD\u8BA9 `fabric doctor --archive-history` \u4E0E archive-hint hook \u51C6\u786E\u8BC6\u522B\u8DE8\u4F1A\u8BDD debt \u72B6\u6001\u3002\n- **Write flows**:`fabric-archive` / `fabric-review` / `fabric-import` \u4E09\u4E2A Skills\u3002\n- **Language**:\u6E32\u67D3\u6309 `.fabric/fabric-config.json` \u7684 `fabric_language` \u5B57\u6BB5\u3002\n- **Archive cadence nudge** (rc.36): \u6BCF\u5B8C\u6210 5+ \u6B21 Edit / \u663E\u8457 decision \u540E,\u5728\u5408\u9002\u56DE\u5408\u4E3B\u52A8 propose \u8C03 `fabric-archive` skill \u2014 archive \u6CA1\u5EFA\u7ACB\u9891\u7387\u4F1A\u8BA9 KB \u6162\u901F\u6B7B\u6389\u3002\n- **Review backlog nudge** (rc.36): `.fabric/knowledge/pending/` \u7D2F\u79EF >10 \u6761\u65F6,\u5728\u5408\u9002\u56DE\u5408\u4E3B\u52A8 propose \u8C03 `fabric-review` skill \u6279\u91CF\u5BA1,\u907F\u514D draft \u5361\u6B7B\u3002\n\n## Self-archive policy (v2.0.0-rc.37 NEW-2: \u7B80\u5316 4 \u4FE1\u53F7 \u2192 2 \u5927\u7C7B)\n\n- **\u89E6\u53D1** (\u672C\u4F1A\u8BDD\u51FA\u73B0\u4EE5\u4E0B\u4EFB\u4E00\u4FE1\u53F7, \u5728\u8BE5 turn \u56DE\u590D\u672B\u5C3E\u81EA\u4E3B\u8C03\u7528 `fabric-archive` skill, \u8D70 AI \u81EA\u89E6\u53D1\u5165\u53E3 E3_ai_self_trigger):\n 1. **User-driven normative** \u2014 \u7528\u6237\u6D88\u606F\u4E2D\u663E\u5F0F\u8868\u8FBE normative \u610F\u56FE: `\u4EE5\u540E` / `always` / `never` / `from now on` / `\u4E0B\u6B21\u6CE8\u610F` / `\u8BB0\u4E00\u4E0B` / `\u6C38\u8FDC\u4E0D\u8981`, OR \u7528\u6237\u5728 \u22652 \u5019\u9009\u95F4\u6743\u8861\u540E\u7ED9\u51FA rationale \u9501\u5B9A\u65B9\u5411, OR \u7528\u6237\u62D2\u4E86\u67D0\u5EFA\u8BAE**\u5E76**\u8BF4\u4E86\u539F\u56E0 (\u62D2\u7EDD\u7406\u7531\u672C\u8EAB\u662F\u77E5\u8BC6)\n 2. **Wrong-turn-and-revert** \u2014 AI \u5C1D\u8BD5 path X, \u53CD\u601D\u540E\u6539\u8D70 path Y (\u5C24\u5176\u5F53 path X \u662F\u975E\u663E\u7136\u8E29\u5751); \u6DB5\u76D6\u6280\u672F\u51B3\u7B56\u53CD\u8F6C + \u5DE5\u5177/\u8303\u5F0F\u5207\u6362 + \u5931\u8D25\u91CD\u8BD5\u3002Anchor: \u4E00\u5B9A\u6709\"\u5426\u5B9A+\u66FF\u4EE3\"\u7684\u4E24\u6B65\u7ED3\u6784, \u4E0D\u662F\u5355\u7EAF\u63A2\u7D22\u5931\u8D25\n\n \u8001 4-state (Normative / Decision-confirmation / Explicit-dismissal / Wrong-turn) \u73B0\u5408\u5E76: \u524D 3 \u4E2A\u5168\u662F\"\u7528\u6237\u6D88\u606F\u4E2D\u663E\u5F0F\u8868\u8FBE\"\u6027\u8D28, \u6298\u6210 1 \u7C7B; \u7B2C 4 \u662F\"AI \u81EA\u5DF1\u7684\u53CD\u601D\u8DEF\u5F84\", \u72EC\u7ACB 1 \u7C7B\u3002\u4E24\u7C7B\u5404\u81EA\u7684\u672C\u8D28\u5224\u522B\u4E0D\u53D8, \u89E6\u53D1\u9762\u6CA1\u53D8\u7A84\u3002\n\n- **Anti-trigger** (\u660E\u786E\u4E0D\u89E6\u53D1):\n - \u7528\u6237\u7EAF\u8BE2\u95EE (\u65E0 normative \u8868\u8FBE)\n - \u7B80\u5355 refactor / typo fix\n - AI \u81EA\u5DF1\u4EA7\u751F\u7684'\u6D1E\u5BDF' (\u5FC5\u987B\u7531\u7528\u6237\u6D88\u606F\u4E2D\u4FE1\u53F7\u6216 AI \u81EA\u5DF1\u7684 wrong-turn \u89E6\u53D1, \u4E0D\u662F\u51ED\u7A7A\"\u6211\u5B66\u5230\u4E86\"\u6027\u8D28)\n\n- **Anti-loop \u4E09\u6761\u9632\u62A4**:\n - \u540C turn \u6700\u591A\u81EA\u8C03 1 \u6B21\n - \u540C session \u540C outcome \u4E0D\u91CD\u590D (\u82E5 user_dismissed, \u672C\u4F1A\u8BDD\u4E0D\u518D\u81EA\u8C03\u76F8\u540C\u4E3B\u9898)\n - Phase 2.5 viability gate \u515C\u5E95 (skill \u5185\u90E8\u4ECD\u8DD1 gate, AI \u5224\u9519\u4E0D\u4F1A\u4E71\u5199 pending)\n\n- **\u5448\u73B0\u6A21\u677F** (turn \u672B\u5C3E\u63D2\u5165, \u4E24\u884C: \u5148 marker \u884C\u4F9B Phase 1.5 \u68C0\u6D4B, \u518D user-facing \u63D0\u793A):\n ```\n self-archive policy triggered by signal: <User-driven normative|Wrong-turn-and-revert>\n \u987A\u624B\u5F52\u6863: \u6CE8\u610F\u5230\u4F60\u8BF4 `<\u89E6\u53D1\u77ED\u8BED>`, \u5DF2\u8C03\u7528 fabric-archive \u6293 N \u6761\u5019\u9009 \u2192 .fabric/knowledge/pending/...\n \u82E5\u4E0D\u8BE5\u8BB0, \u7B54 '\u64A4\u9500' \u6211\u4F1A\u8C03 fab_review reject\u3002\n ```\n \u7B2C\u4E00\u884C\u662F Phase 1.5 Trigger Gate \u8BC6\u522B E3 \u5165\u53E3\u7684 structured marker (verbatim \u5B57\u7B26\u4E32 `self-archive policy triggered by signal`, \u540E\u63A5\u5192\u53F7 + \u89E6\u53D1\u4FE1\u53F7\u540D)\u3002\u7B2C\u4E8C\u884C\u8D77\u662F\u7ED9\u7528\u6237\u770B\u7684\u4E2D\u6587\u63D0\u793A\u3002\u4E24\u884C\u90FD\u5FC5\u987B\u51FA\u73B0; \u7F3A marker \u884C Phase 1.5 \u65E0\u6CD5\u8DEF\u7531\u5230 E3_ai_self_trigger\u3002\n\n Backward compat: Phase 1.5 entry-point regex \u540C\u65F6\u8BC6\u522B\u8001 4 \u4E2A\u4FE1\u53F7\u540D (Normative / Wrong-turn-and-revert / Decision confirmation / Explicit dismissal) \u4E0E\u65B0 2 \u5927\u7C7B\u540D, \u65E7 session marker \u4ECD\u80FD\u6B63\u786E\u8DEF\u7531\u3002\n\n## Cite policy (v2.0.0-rc.37 NEW-1: \u7B80\u5316 4-state \u2192 2-state)\n\n- **\u89E6\u53D1**: \u505A edit / decide / propose plan \u4E4B\u524D,**\u56DE\u590D\u9996\u884C**\u5FC5\u987B\u5199 `KB: <id> (<\u22648\u5B57 \u7528\u6CD5>) [applied|dismissed:<reason>]` \u6216 `KB: none [<reason>]`\u3002\n- **`[applied]` \u9A8C\u8BC1\u4E49\u52A1**: \u5F15\u7528\u4EFB\u4F55 id \u524D\u5FC5\u987B\u5148\u7528 fab_recall (\u6216\u4E24\u6B65 fab_plan_context \u2192 fab_get_knowledge_sections) \u5B9E\u9645\u6293 KB body, \u9632\u6B62\u7F16\u9020 id\u3002\u9A8C\u8BC1\u4E0D\u901A\u8FC7 = \u4E0D\u80FD cite\u3002\n- **store \u524D\u7F00 (v2.1, \u591A store)**: \u5F53 read-set \u542B\u591A\u4E2A store \u4E14\u540C\u4E00 local id \u5728\u591A store \u95F4 shadow \u65F6,cite \u5FC5\u987B store-qualified: `KB: <store-alias>:<id> ...`(\u5982 `KB: team:KT-DEC-0001 (auth) [applied]`);alias \u7528\u6237\u81EA\u5B9A/canonical,\u5E95\u5C42 UUID\u3002\u5355 store \u6216\u65E0\u6B67\u4E49\u65F6\u88F8 `KB: <id>` \u4ECD valid\u3002personal-only \u6761\u76EE cite \u8FDB\u56E2\u961F\u4EA7\u7269=\u5F3A warning(\u63A5 P2 \u5199\u8DEF\u5F84\u9632\u6CC4\u6F0F R5#3)\u3002\n- **contract \u8BED\u6CD5**: decisions/pitfalls \u7C7B `[applied]` cite \u5C3E\u6BB5\u52A0 contract: `\u2192 <operator> [<operator> ...]`,operator \u2208 {`edit:<glob>` `!edit:<glob>` `require:<symbol>` `forbid:<symbol>` `skip:<reason>`}\u3002\u4F8B:`KB: K-001 (auth) [applied] \u2192 edit:src/auth/**/*.ts !edit:src/legacy/**`\u3002\n- **skip reason \u8BCD\u5178**: `sequencing | conditional | semantic | aesthetic | architectural | other:<text>`\u3002\n- **type \u8DEF\u7531**: models \u7C7B\u5F15\u7528\u4E3A reference cite,\u4E0D\u9700\u8981 contract;guidelines/processes \u7C7B\u6682\u4E0D\u5F3A\u5236,\u63A8\u540E LLM-judge\u3002\n- **\u7528\u6237\u53E3\u5934\u63D0\u89C4\u5219\u6CA1\u7ED9 id**: \u5148\u8C03 `fab_recall(paths)` \u6216 `fab_extract_knowledge` \u53CD\u67E5\u3002\n- **dismissed reason**: \u679A\u4E3E `scope-mismatch | outdated | not-applicable | other:<text>`\u3002\n- **`KB: none` sentinel**: \u679A\u4E3E\u4E24\u79CD\u5408\u89C4\u7406\u7531\u2014\u2014`[no-relevant]` \u5DF2\u8C03 `fab_recall` / `fab_plan_context`(\u6216 hook \u8F93\u51FA\u53EF\u89C1)\u4F46\u65E0\u53EF\u7528\u6761\u76EE;`[not-applicable]` \u5F53\u524D\u52A8\u4F5C\u4E0D\u5728 cite \u8303\u56F4(\u7EAF\u63A2\u7D22 / Bash \u53EA\u8BFB / \u7528\u6237\u95EE\u7B54)\u3002\u88F8 `KB: none`(\u65E0\u540E\u7F00)\u4ECD\u7136 valid,\u5F52\u7C7B\u4E3A `[unspecified]`(legacy \u517C\u5BB9,\u9F13\u52B1\u540E\u7EED\u8865\u6CE8)\u3002\n- **\u7A3D\u6838**: `fabric doctor --cite-coverage [--since=7d] [--client=cc|codex|all]` \u8F93\u51FA cite \u8986\u76D6\u7387,\u542B `KB: none` sentinel \u62C6\u5206\u3002\u672C\u89C4\u5219\u4E0D\u963B\u65AD\u4F60\u5DE5\u4F5C,\u53EA\u8BB0\u5F55\u3002\n- **Backward compat**: \u89E3\u6790\u5668\u540C\u65F6\u63A5\u53D7\u8001 4-state tags (`planned` / `recalled` / `chained-from <id>`) \u2014 \u90FD\u6620\u5C04\u5230 `[applied]` \u8BED\u4E49,gradually \u8FC1\u5230\u65B0\u7B80\u5316\u5F62\u6001\u5373\u53EF,\u65E7 session \u7559\u4E0B\u7684 cite \u4ECD\u7136\u8BA1\u5165 cite-coverage\u3002\n- **\u5B8C\u6574\u53C2\u8003\u4E0B\u6C89** (v2.2 SK5): contract operator / skip\u00B7dismissed \u8BCD\u5178 / \u7C7B\u578B\u8DEF\u7531 / \u7A3D\u6838\u53E3\u5F84 / **\u88C1\u51B3\u9636\u68AF** (AI\u81EA\u51B3 \u2192 \u591A-LLM \u542B\u96F6\u4E0A\u4E0B\u6587\u51B7\u8BC4 \u2192 \u975E\u963B\u585E\u961F\u5217) \u7684\u6743\u5A01\u8BE6\u53C2\u5728 `fabric-review` skill \u7684 `ref/cite-contract.md` \u2014\u2014 bootstrap \u53EA\u7559\u53EF\u6267\u884C core,\u6CBB\u7406\u7EC6\u8282\u5F52 ref \u4E0D\u518D\u6491\u5927 bootstrap\u3002\n";
|
|
55
55
|
|
|
56
56
|
export { BOOTSTRAP_CANONICAL, BOOTSTRAP_MARKER_BEGIN, BOOTSTRAP_MARKER_END, BOOTSTRAP_REGEX, LEGACY_KB_MARKER_BEGIN, LEGACY_KB_MARKER_END, LEGACY_KB_REGEX };
|