@nklisch/pi-enhanced 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/node_modules/@nklisch/pi-astral-pocket/README.md +127 -93
- package/node_modules/@nklisch/pi-astral-pocket/package.json +2 -2
- package/node_modules/@nklisch/pi-astral-pocket/src/distiller.ts +196 -183
- package/node_modules/@nklisch/pi-astral-pocket/src/guidance.ts +26 -62
- package/node_modules/@nklisch/pi-astral-pocket/src/index.ts +8 -5
- package/node_modules/@nklisch/pi-astral-pocket/src/sessions.ts +10 -3
- package/node_modules/@nklisch/pi-astral-pocket/src/store.ts +439 -321
- package/node_modules/@nklisch/pi-astral-pocket/src/tools.ts +172 -66
- package/node_modules/@nklisch/pi-clearance/docs/CONFIGURATION.md +3 -3
- package/node_modules/@nklisch/pi-clearance/docs/DEVELOPER_GUIDE.md +11 -12
- package/node_modules/@nklisch/pi-clearance/docs/PACK_AUTHORING.md +5 -5
- package/node_modules/@nklisch/pi-clearance/docs/PRINCIPLES.md +1 -2
- package/node_modules/@nklisch/pi-clearance/docs/REFERENCE_PATTERNS.md +13 -19
- package/node_modules/@nklisch/pi-clearance/docs/SPEC.md +4 -4
- package/node_modules/@nklisch/pi-clearance/docs/USER_GUIDE.md +2 -3
- package/node_modules/@nklisch/pi-clearance/docs/VISION.md +1 -1
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-x64-msvc.node +0 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/README.md +2 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/VISION.md +2 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/architecture.md +105 -886
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/decisions/0002-extensions-on-a-minimal-core.md +44 -78
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/decisions/0003-publish-bundled-type-declarations.md +28 -57
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/decisions/0004-reconsider-ui-direction.md +49 -261
- package/node_modules/@nklisch/pi-plugins/package.json +2 -2
- package/package.json +2 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/client-server-opportunities.md +0 -127
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-1-api-boundary.md +0 -8
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-10-structural-decomposition.md +0 -141
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-11-closure-to-class.md +0 -100
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-12-complexity-test-fixtures.md +0 -55
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-13-remaining-smells.md +0 -88
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-14-strip-policy.md +0 -49
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-15-domain-model-evolution.md +0 -73
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-16-invert-dependencies.md +0 -144
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-17-core-consolidation.md +0 -214
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-18-reconsider-ui.md +0 -166
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-19-implement-ui-decisions.md +0 -282
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-2-remove-scheduling.md +0 -9
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-3-remove-rpc-groupjoin.md +0 -11
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-4-implement-service.md +0 -8
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-5-decompose-index.md +0 -42
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-7-encapsulation.md +0 -173
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-8-testability.md +0 -103
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/history/phase-9-observation-ctx.md +0 -122
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/decisions/0001-deferred-patches.md +0 -80
|
@@ -2,140 +2,246 @@ import { Type } from "typebox";
|
|
|
2
2
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
|
|
6
5
|
import type { ActivationState } from "./activation.js";
|
|
7
6
|
import { resolveProjectIdentity } from "./scope.js";
|
|
8
7
|
import { searchAstraSessions } from "./sessions.js";
|
|
9
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
MAX_BODY_CHARS,
|
|
10
|
+
MAX_EVIDENCE_CHARS,
|
|
11
|
+
MAX_TITLE_CHARS,
|
|
12
|
+
retireNote,
|
|
13
|
+
searchPocket,
|
|
14
|
+
writeNote,
|
|
15
|
+
} from "./store.js";
|
|
10
16
|
|
|
11
17
|
const INACTIVE_MESSAGE =
|
|
12
18
|
"Pocket tools are only active in gpt-6-astra sessions with the pocket enabled (/pocket on).";
|
|
13
|
-
const DEFAULT_RECALL_LIMIT = 10;
|
|
14
19
|
export const MAX_RECALL_LIMIT_PER_SOURCE = 20;
|
|
15
|
-
|
|
16
20
|
function normalizeRecallLimit(value: unknown): number {
|
|
17
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return
|
|
21
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 10;
|
|
18
22
|
return Math.min(MAX_RECALL_LIMIT_PER_SOURCE, Math.max(1, Math.trunc(value)));
|
|
19
23
|
}
|
|
20
|
-
|
|
21
24
|
export interface ToolDeps {
|
|
22
25
|
state: ActivationState;
|
|
23
|
-
/** Pocket root directory (~/.pi/agent/astral-pocket). */
|
|
24
26
|
root: string;
|
|
25
|
-
/** Sessions directory (~/.pi/agent/sessions). */
|
|
26
27
|
sessionsDir: string;
|
|
27
28
|
maxSessionAgeDays: () => number;
|
|
28
29
|
}
|
|
29
|
-
|
|
30
30
|
function textResult(text: string) {
|
|
31
31
|
return { content: [{ type: "text" as const, text }], details: {} };
|
|
32
32
|
}
|
|
33
|
-
|
|
34
33
|
export function registerPocketTools(pi: ExtensionAPI, deps: ToolDeps): void {
|
|
35
34
|
pi.registerTool({
|
|
36
35
|
name: "pocket_note",
|
|
37
36
|
label: "Pocket Note",
|
|
38
37
|
description:
|
|
39
|
-
"
|
|
40
|
-
promptSnippet:
|
|
38
|
+
"Save, replace or retire a current-repository navigation clue or hard-to-rediscover technical pitfall. Never save preferences, user policy, delivery history or facts already covered by current docs. New notes are project-only.",
|
|
39
|
+
promptSnippet:
|
|
40
|
+
"Save or retire a repository navigation clue or technical pitfall",
|
|
41
41
|
promptGuidelines: [
|
|
42
|
-
"Use pocket_note
|
|
43
|
-
"
|
|
44
|
-
"Keep pocket_note project-scoped by default; use global scope only for a clearly general preference or conditional portable observation.",
|
|
42
|
+
"Use pocket_note only for actionable repository navigation or verified technical pitfalls worth avoiding rediscovery; never preferences, policy, architecture/status summaries, ordinary docs facts or personal data.",
|
|
43
|
+
"Retire obsolete notes; replace updates agent-authored notes in place, supersedes retires source notes when saving a new learning.",
|
|
45
44
|
],
|
|
46
45
|
parameters: Type.Object({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
action: Type.Optional(
|
|
47
|
+
Type.Union([Type.Literal("save"), Type.Literal("retire")], {
|
|
48
|
+
description: "Default save. Retire needs noteFile only.",
|
|
49
|
+
}),
|
|
50
|
+
),
|
|
51
|
+
noteFile: Type.Optional(
|
|
52
|
+
Type.String({
|
|
53
|
+
description: "Canonical filename to retire (not a path)",
|
|
54
|
+
}),
|
|
55
|
+
),
|
|
56
|
+
kind: Type.Optional(
|
|
57
|
+
Type.Union([Type.Literal("navigation"), Type.Literal("pitfall")], {
|
|
58
|
+
description: "Required for save",
|
|
59
|
+
}),
|
|
60
|
+
),
|
|
61
|
+
title: Type.Optional(
|
|
62
|
+
Type.String({
|
|
63
|
+
minLength: 1,
|
|
64
|
+
maxLength: MAX_TITLE_CHARS,
|
|
65
|
+
description: "Required for save: descriptive technical title",
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
68
|
+
body: Type.Optional(
|
|
69
|
+
Type.String({
|
|
70
|
+
minLength: 1,
|
|
71
|
+
maxLength: MAX_BODY_CHARS,
|
|
72
|
+
description:
|
|
73
|
+
"Required for save: one complete actionable learning, not a status summary",
|
|
74
|
+
}),
|
|
75
|
+
),
|
|
76
|
+
evidence: Type.Optional(
|
|
77
|
+
Type.String({
|
|
78
|
+
maxLength: MAX_EVIDENCE_CHARS,
|
|
79
|
+
description:
|
|
80
|
+
"Optional source path, symbol, command or other evidence pointer",
|
|
81
|
+
}),
|
|
82
|
+
),
|
|
83
|
+
keywords: Type.Optional(
|
|
84
|
+
Type.Array(Type.String({ maxLength: 64 }), { maxItems: 5 }),
|
|
85
|
+
),
|
|
86
|
+
replace: Type.Optional(
|
|
87
|
+
Type.String({
|
|
88
|
+
description: "Existing agent-authored note filename to update",
|
|
89
|
+
}),
|
|
90
|
+
),
|
|
91
|
+
supersedes: Type.Optional(
|
|
92
|
+
Type.Array(Type.String(), {
|
|
93
|
+
maxItems: 10,
|
|
94
|
+
description:
|
|
95
|
+
"Current-repository note filenames to retire when saving this learning",
|
|
96
|
+
}),
|
|
97
|
+
),
|
|
53
98
|
}),
|
|
54
|
-
async execute(
|
|
99
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
55
100
|
if (!deps.state.active) throw new Error(INACTIVE_MESSAGE);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
101
|
+
const projectId = resolveProjectIdentity(ctx.cwd);
|
|
102
|
+
return withFileMutationQueue(join(deps.root, "POCKET.md"), async () => {
|
|
103
|
+
if (signal?.aborted || !deps.state.active)
|
|
104
|
+
throw new Error("Pocket note cancelled");
|
|
105
|
+
if (params.action === "retire") {
|
|
106
|
+
if (!params.noteFile) throw new Error("Retire requires noteFile");
|
|
107
|
+
retireNote(deps.root, params.noteFile, projectId);
|
|
108
|
+
return textResult(
|
|
109
|
+
`Retired notes/${params.noteFile}; excluded from startup and default recall. Retiring generated learning also prevents further automatic extraction of its source session.`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
if (params.action !== undefined && params.action !== "save")
|
|
113
|
+
throw new Error("Unknown note action");
|
|
114
|
+
if (!params.kind || !params.title || !params.body)
|
|
115
|
+
throw new Error("Save requires kind, title and body");
|
|
116
|
+
if (params.noteFile)
|
|
117
|
+
throw new Error(
|
|
118
|
+
"Use replace to update a note, or action: retire with noteFile",
|
|
119
|
+
);
|
|
120
|
+
const fileName = writeNote(
|
|
121
|
+
deps.root,
|
|
122
|
+
{
|
|
123
|
+
kind: params.kind,
|
|
124
|
+
title: params.title,
|
|
125
|
+
body: params.body,
|
|
126
|
+
evidence: params.evidence,
|
|
127
|
+
keywords: params.keywords,
|
|
128
|
+
project: ctx.cwd,
|
|
129
|
+
projectId,
|
|
130
|
+
},
|
|
131
|
+
new Date(),
|
|
132
|
+
{ replace: params.replace, supersedes: params.supersedes },
|
|
133
|
+
);
|
|
134
|
+
return textResult(`Learning saved: notes/${fileName}`);
|
|
71
135
|
});
|
|
72
|
-
return textResult(`Note saved to the pocket: notes/${fileName}`);
|
|
73
136
|
},
|
|
74
137
|
});
|
|
75
|
-
|
|
76
138
|
pi.registerTool({
|
|
77
139
|
name: "pocket_recall",
|
|
78
140
|
label: "Pocket Recall",
|
|
79
141
|
description:
|
|
80
|
-
"Search current-repository
|
|
81
|
-
promptSnippet:
|
|
142
|
+
"Search active current-repository learning notes by default. source: sessions or both explicitly includes historical transcripts. includeHistory: true includes legacy/retired notes; scope: all searches other repositories but does not enable history. full: true returns larger excerpts, not full files.",
|
|
143
|
+
promptSnippet:
|
|
144
|
+
"Search repository learning or explicitly requested historical excerpts",
|
|
82
145
|
promptGuidelines: [
|
|
83
|
-
"
|
|
84
|
-
"Keep recall cheap: at most 4-6 lookup steps, summarized results first, full: true only when you need exact commands or error text.",
|
|
146
|
+
"Start with one focused recall when a concrete navigation or rediscovery problem makes it useful; expand only if results help. Recall is not mandatory for every repository task.",
|
|
85
147
|
],
|
|
86
148
|
parameters: Type.Object({
|
|
87
|
-
query: Type.String({
|
|
149
|
+
query: Type.String({
|
|
150
|
+
description: "Keywords to search for (all must match)",
|
|
151
|
+
}),
|
|
88
152
|
source: Type.Optional(
|
|
89
|
-
Type.Union(
|
|
90
|
-
|
|
153
|
+
Type.Union(
|
|
154
|
+
[
|
|
155
|
+
Type.Literal("pocket"),
|
|
156
|
+
Type.Literal("sessions"),
|
|
157
|
+
Type.Literal("both"),
|
|
158
|
+
],
|
|
159
|
+
{
|
|
160
|
+
description:
|
|
161
|
+
"Default pocket. Sessions are historical precedent, not active learning.",
|
|
162
|
+
},
|
|
163
|
+
),
|
|
164
|
+
),
|
|
165
|
+
includeHistory: Type.Optional(
|
|
166
|
+
Type.Boolean({
|
|
167
|
+
description:
|
|
168
|
+
"Include labeled legacy, unclassified, retired and global notes (default false)",
|
|
169
|
+
}),
|
|
170
|
+
),
|
|
171
|
+
full: Type.Optional(
|
|
172
|
+
Type.Boolean({
|
|
173
|
+
description: "Larger excerpts, not complete files (default false)",
|
|
174
|
+
}),
|
|
175
|
+
),
|
|
176
|
+
limit: Type.Optional(
|
|
177
|
+
Type.Integer({
|
|
178
|
+
minimum: 1,
|
|
179
|
+
maximum: MAX_RECALL_LIMIT_PER_SOURCE,
|
|
180
|
+
description: "Max hits per source; default 10",
|
|
181
|
+
}),
|
|
182
|
+
),
|
|
183
|
+
scope: Type.Optional(
|
|
184
|
+
Type.Union([Type.Literal("current"), Type.Literal("all")], {
|
|
185
|
+
description:
|
|
186
|
+
"Current repository by default; all adds foreign precedent, independently of includeHistory.",
|
|
91
187
|
}),
|
|
92
188
|
),
|
|
93
|
-
full: Type.Optional(Type.Boolean({ description: "Return larger excerpts (default: false)" })),
|
|
94
|
-
limit: Type.Optional(Type.Integer({
|
|
95
|
-
minimum: 1,
|
|
96
|
-
maximum: MAX_RECALL_LIMIT_PER_SOURCE,
|
|
97
|
-
description: "Max hits from each source (default: 10, maximum: 20)",
|
|
98
|
-
})),
|
|
99
|
-
scope: Type.Optional(Type.Union([Type.Literal("current"), Type.Literal("all")], {
|
|
100
|
-
description: "Current repository plus global notes by default; all includes foreign repositories as precedent.",
|
|
101
|
-
})),
|
|
102
189
|
}),
|
|
103
|
-
async execute(
|
|
190
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
104
191
|
if (!deps.state.active) throw new Error(INACTIVE_MESSAGE);
|
|
105
|
-
|
|
192
|
+
if (signal?.aborted) throw new Error("Pocket recall cancelled");
|
|
193
|
+
const source = params.source ?? "pocket";
|
|
106
194
|
const limit = normalizeRecallLimit(params.limit);
|
|
107
|
-
const
|
|
195
|
+
const scope = params.scope ?? "current";
|
|
108
196
|
const projectId = resolveProjectIdentity(ctx.cwd);
|
|
197
|
+
const excludeSession = {
|
|
198
|
+
id: ctx.sessionManager.getSessionId(),
|
|
199
|
+
path: ctx.sessionManager.getSessionFile(),
|
|
200
|
+
};
|
|
109
201
|
const sections: string[] = [];
|
|
110
|
-
|
|
111
202
|
if (source === "pocket" || source === "both") {
|
|
112
|
-
const hits = searchPocket(
|
|
203
|
+
const hits = searchPocket(
|
|
204
|
+
deps.root,
|
|
205
|
+
params.query,
|
|
206
|
+
projectId,
|
|
207
|
+
limit,
|
|
208
|
+
params.full,
|
|
209
|
+
scope,
|
|
210
|
+
params.includeHistory,
|
|
211
|
+
excludeSession,
|
|
212
|
+
);
|
|
113
213
|
sections.push(
|
|
114
214
|
hits.length === 0
|
|
115
215
|
? "Pocket notes: no matches."
|
|
116
216
|
: `Pocket notes (${hits.length}):\n${hits
|
|
117
|
-
.map(
|
|
217
|
+
.map(
|
|
218
|
+
(hit) =>
|
|
219
|
+
`- ${hit.title} [notes/${hit.noteFile}] (${hit.project || "unknown"}) · ${hit.scope} · ${hit.date}${hit.historical ? " · historical precedent (not current authority)" : ""}${hit.retired ? " · retired" : ""}\n ${hit.excerpt}`,
|
|
220
|
+
)
|
|
118
221
|
.join("\n")}`,
|
|
119
222
|
);
|
|
120
223
|
}
|
|
121
|
-
|
|
122
224
|
if (source === "sessions" || source === "both") {
|
|
123
225
|
const hits = await searchAstraSessions(deps.sessionsDir, params.query, {
|
|
124
226
|
full: params.full,
|
|
125
227
|
limit,
|
|
126
228
|
maxAgeDays: deps.maxSessionAgeDays(),
|
|
127
229
|
projectId,
|
|
128
|
-
recallScope,
|
|
230
|
+
recallScope: scope,
|
|
231
|
+
excludeSession,
|
|
129
232
|
});
|
|
233
|
+
if (signal?.aborted) throw new Error("Pocket recall cancelled");
|
|
130
234
|
sections.push(
|
|
131
235
|
hits.length === 0
|
|
132
236
|
? "Past astra sessions: no matches."
|
|
133
|
-
: `Past astra sessions (${hits.length}):\n${hits
|
|
134
|
-
.map(
|
|
237
|
+
: `Past astra sessions (${hits.length}) — historical precedent, not current authority:\n${hits
|
|
238
|
+
.map(
|
|
239
|
+
(hit) =>
|
|
240
|
+
`- [${hit.kind}] ${hit.timestamp} (${hit.project}) · session ${hit.sessionId}\n ${hit.excerpt}`,
|
|
241
|
+
)
|
|
135
242
|
.join("\n")}`,
|
|
136
243
|
);
|
|
137
244
|
}
|
|
138
|
-
|
|
139
245
|
return textResult(sections.join("\n\n"));
|
|
140
246
|
},
|
|
141
247
|
});
|
|
@@ -34,7 +34,7 @@ display, pack, and posture fields are supplied by runtime normalization.
|
|
|
34
34
|
| `ask` | human prompt; unattended calls block-and-log | deny |
|
|
35
35
|
| `auto` | model first, then human/block fallback | deny |
|
|
36
36
|
|
|
37
|
-
`gatedTools` is a global exact-name list and defaults to empty. Non-Bash tools absent from the list bypass Clearance analysis and policy entirely, execute, and receive an audit entry marked as an allow/bypass. There are no wildcards or future-tool opt-ins, and `bash` cannot be listed. Bash remains fully gated.
|
|
37
|
+
`gatedTools` is a global exact-name list and defaults to empty. Non-Bash tools absent from the list bypass Clearance analysis and policy entirely, execute, and receive an audit entry marked as an allow/bypass. There are no wildcards or future-tool opt-ins, and `bash` cannot be listed. Bash remains fully gated. Typed edit/read protections are opt-in.
|
|
38
38
|
|
|
39
39
|
`unknownToolPosture` remains a config-file-only knob and applies only to an opted-in non-Bash tool that has no registered analyzer. It defaults to `"allow"`; it does not re-gate tools absent from `gatedTools`. Setting it to `"review"` or `"deny"` tightens opted-in unknown tools. The sealed floor and all active user/shipped deny rules run in every mode.
|
|
40
40
|
|
|
@@ -71,7 +71,7 @@ The reviewer settings selector exposes `promptPosture` and `model` interactively
|
|
|
71
71
|
|
|
72
72
|
## Packs
|
|
73
73
|
|
|
74
|
-
The baseline is
|
|
74
|
+
The built-in baseline is described in [RULE_PACKS.md](RULE_PACKS.md#baseline), including `bash.network.read`, `pi.extension.network-research`, and `pi.home.safe`. Mode never changes baseline activation. Package packs remain available until explicitly enabled through `packEnablement.enabledPackagePacks`; user-owned config packs can be disabled with `disabledConfigPacks`.
|
|
75
75
|
|
|
76
76
|
## Commands
|
|
77
77
|
|
|
@@ -81,4 +81,4 @@ The baseline is always the old default pack set plus `bash.network.read`, `pi.ex
|
|
|
81
81
|
- `/clearance status`, `/clearance packs`, `/clearance scope`, `/clearance tune`, `/clearance why` — unchanged surfaces with mode/baseline vocabulary. Scope management also supports `scope agent-support add|remove <path>` and `scope agent-support-defaults <on|off>`.
|
|
82
82
|
- `/clearance allow <plain language>` or `/clearance allow` — hand an agent-authored structural allow request to the shared proposal card. Accepted rules land in the user-global pack; this command adds no separate config surface.
|
|
83
83
|
|
|
84
|
-
`/clearance profile` and `/clearance auto` are
|
|
84
|
+
`/clearance profile` and `/clearance auto` are unsupported and have no aliases.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This guide is for people changing Pi Clearance itself.
|
|
4
4
|
|
|
5
|
-
> The
|
|
5
|
+
> The command surface is `/clearance`; unsupported commands have no compatibility aliases.
|
|
6
6
|
|
|
7
7
|
For product behavior, start with [README.md](../README.md) and [USER_GUIDE.md](USER_GUIDE.md). For design intent, read the foundation docs linked at the end of this file.
|
|
8
8
|
|
|
@@ -127,7 +127,7 @@ package README snippets.
|
|
|
127
127
|
| `src/skill/clearance-tune/` | internal tune helper harness plus display-only structured proposal presentation seam |
|
|
128
128
|
| `src/skill/clearance-*/` | thin agent guidance that points to canonical docs |
|
|
129
129
|
| `test/` | unit, fixture, replay, runtime, and skill tests |
|
|
130
|
-
| `.work/` | Workbench state (active items, backlog, conventions) |
|
|
130
|
+
| [Repository `.work/`](../../../.work/) | Workbench state (active items, backlog, conventions) |
|
|
131
131
|
|
|
132
132
|
## Settings command surface and dispatcher seam
|
|
133
133
|
|
|
@@ -262,23 +262,22 @@ Public docs should stay practical and low-hype:
|
|
|
262
262
|
|
|
263
263
|
The root README and these reference docs are user/developer docs. The foundation docs remain the design source of truth.
|
|
264
264
|
|
|
265
|
-
##
|
|
265
|
+
## Contributor workflow
|
|
266
266
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
files directly; there is no separate query binary.
|
|
271
|
-
|
|
272
|
-
Before design, implementation, or review work, read `.work/CONVENTIONS.md` and
|
|
273
|
-
the relevant `docs/` foundation docs.
|
|
267
|
+
Follow the repository's [AGENTS.md](../../../AGENTS.md) and
|
|
268
|
+
[Workbench conventions](../../../.work/CONVENTIONS.md) for work tracking,
|
|
269
|
+
verification, and review.
|
|
274
270
|
|
|
275
271
|
## Foundation docs
|
|
276
272
|
|
|
277
|
-
- [VISION.md](VISION.md) — product direction
|
|
273
|
+
- [VISION.md](VISION.md) — product direction.
|
|
278
274
|
- [SPEC.md](SPEC.md) — behavior contract.
|
|
279
275
|
- [ARCHITECTURE.md](ARCHITECTURE.md) — module boundaries.
|
|
280
276
|
- [PRINCIPLES.md](PRINCIPLES.md) — safety and execution rules.
|
|
277
|
+
|
|
278
|
+
## Focused references
|
|
279
|
+
|
|
281
280
|
- [RULE_PACKS.md](RULE_PACKS.md) — shipped pack intent.
|
|
282
281
|
- [PACK_AUTHORING.md](PACK_AUTHORING.md) — data-pack, TypeScript-pack, and package distribution guidance.
|
|
283
282
|
- [REVIEWER_PROMPTS.md](REVIEWER_PROMPTS.md) — prompt and reviewer contract.
|
|
284
|
-
- [REFERENCE_PATTERNS.md](REFERENCE_PATTERNS.md) —
|
|
283
|
+
- [REFERENCE_PATTERNS.md](REFERENCE_PATTERNS.md) — policy-corpus vocabulary, command-family lessons, and capture provenance; not an implementation-pattern catalog or foundation.
|
|
@@ -305,11 +305,11 @@ is not covered makes a project-local allow return `false`. For `none-in` without
|
|
|
305
305
|
`deny > review > allow` — so a `review` rule for `mkdir -m` and a sealed-floor `deny` for
|
|
306
306
|
`sudo` still win over a matching path-scoped allow.
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
308
|
+
Runtime enrichment receives cwd, project scope, and the resolved `homeDirectory` when
|
|
309
|
+
available. Supported unquoted `~/...` operands resolve lexically against that home before
|
|
310
|
+
scope classification; the winning scope still follows configured precedence, so it is not
|
|
311
|
+
necessarily `home`. Without a usable home directory, these operands remain `unknown` and
|
|
312
|
+
cannot satisfy a constructive allow.
|
|
313
313
|
|
|
314
314
|
## Compound shell matchers
|
|
315
315
|
|
|
@@ -56,8 +56,7 @@ the host approval boundary. Global `gatedTools` is an exact-name opt-in list wit
|
|
|
56
56
|
wildcards or future-tool consent; Bash is always fully gated and cannot be listed. An
|
|
57
57
|
opted-in tool without a registered analyzer uses `unknownToolPosture`, which defaults to
|
|
58
58
|
`"allow"` and may be tightened to `"review"` or `"deny"`. The posture does not apply to
|
|
59
|
-
absent names
|
|
60
|
-
protection break.
|
|
59
|
+
absent names.
|
|
61
60
|
|
|
62
61
|
**Implication:** the interpreter must be pure and total for gated calls: every analyzed
|
|
63
62
|
or opted-in unknown input returns `allow`, `deny`, or `review` with a reason; bypasses are
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose statement
|
|
4
4
|
|
|
5
|
-
This
|
|
6
|
-
|
|
5
|
+
This policy-corpus reference preserves vocabulary, command-family lessons, and
|
|
6
|
+
provenance from two sources:
|
|
7
7
|
|
|
8
8
|
- the local `pi-config` clearance proof of concept; and
|
|
9
|
-
-
|
|
9
|
+
- a fork-shaped permission-system scaffold.
|
|
10
10
|
|
|
11
11
|
These sources are **command-pattern, fixture-vocabulary, package-shape, and
|
|
12
12
|
tune-report inspiration only**. They are not runtime architecture for
|
|
@@ -252,10 +252,9 @@ Additional shape notes:
|
|
|
252
252
|
|
|
253
253
|
## Package-metadata reference note
|
|
254
254
|
|
|
255
|
-
The old fork `package.json`
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
identity.
|
|
255
|
+
The old fork `package.json` supplies package-shape reference facts only. Its name,
|
|
256
|
+
version, and description do not define Pi Clearance's product identity; the current
|
|
257
|
+
package manifest owns that metadata.
|
|
259
258
|
|
|
260
259
|
Package-shape facts to carry forward:
|
|
261
260
|
|
|
@@ -268,14 +267,10 @@ Package-shape facts to carry forward:
|
|
|
268
267
|
dependency shape.
|
|
269
268
|
- Node engine: `node >=22.18`, matching the Pi host runtime expectation. Pi loads the package's TypeScript extension entrypoint directly.
|
|
270
269
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
- The old fork exports, files list, schemas, config examples, permission-system keywords,
|
|
276
|
-
and extra permission-manager package surface are not behavior contracts. Future package
|
|
277
|
-
metadata should be derived from `docs/VISION.md`, `docs/SPEC.md`, and the clean module
|
|
278
|
-
spine.
|
|
270
|
+
The old fork exports, files list, schemas, config examples, permission-system keywords,
|
|
271
|
+
and extra permission-manager package surface are not behavior contracts. Package metadata
|
|
272
|
+
must follow the current product boundaries in [VISION.md](VISION.md),
|
|
273
|
+
[SPEC.md](SPEC.md), and [ARCHITECTURE.md](ARCHITECTURE.md), not the reference scaffold.
|
|
279
274
|
|
|
280
275
|
## Do-not-port architecture bullets
|
|
281
276
|
|
|
@@ -329,7 +324,6 @@ categories the downstream fixture harness must preserve:
|
|
|
329
324
|
`mkfs -t ext4 /dev/sda`, including when hidden inside `&&`, semicolon, or newline
|
|
330
325
|
chains.
|
|
331
326
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
categories become allow, review, or deny under the clean interpreter.
|
|
327
|
+
These categories describe reference-corpus coverage, not the product's policy outcomes.
|
|
328
|
+
Corpus maintenance should preserve their representation; the current packs and core
|
|
329
|
+
interpreter determine which cases become allow, review, or deny.
|
|
@@ -14,14 +14,14 @@ Pi Clearance is a Pi extension that structurally analyzes tool calls, evaluates
|
|
|
14
14
|
- User-owned global/project config may add policy; repository policy is tighten-only unless Pi reports the project as trusted.
|
|
15
15
|
- Package installation makes packs available, not active. Explicit user-owned enablement is required. Clearance defines no npm install lifecycle hooks and package installation never reads or writes user config.
|
|
16
16
|
- Global and project config written through Clearance is sparse: `version` plus recursively retained non-default user choices. Defaults remain runtime-only. Invalid or obsolete files fail strict validation and runtime falls back to floor-only policy; package installation does not migrate them.
|
|
17
|
-
-
|
|
17
|
+
- Unsupported config keys fail strict schema validation; there are no translators or aliases for removed keys. Executable TypeScript rule modules are never loaded.
|
|
18
18
|
- The native engine is distributed as prebuilt Node-API artifacts for Linux x64 glibc, Linux arm64 glibc, macOS x64, macOS arm64, and Windows x64 MSVC. Windows ARM is not a release target. Installation never runs Cargo; a missing or unsupported artifact fails closed.
|
|
19
19
|
|
|
20
20
|
## Config
|
|
21
21
|
|
|
22
22
|
`GlobalConfigSchema` contains `version`, `mode` (default `ask`), exact `gatedTools` (default empty; Bash and wildcards rejected), `unknownToolPosture`, packs, package/config enablement, reviewer advanced fields, and display preferences. Project overlays contain packs, enablement, project scope, and trusted prompt appends. Repository policy has no mode or posture. The complete schemas normalize runtime views; `src/config/persistence.ts` owns the sparse persisted representation.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Reviewer model pinning and the compact selector/toggle settings controls are confirm-backed. Explicit `mode: "auto"` is the acknowledgment for model review; no separate reviewer consent file is read or written. [CONFIGURATION.md](CONFIGURATION.md) lists unsupported legacy keys and their strict-validation behavior.
|
|
25
25
|
|
|
26
26
|
## Native boundary
|
|
27
27
|
|
|
@@ -39,8 +39,8 @@ corpus acquisition, proposal heuristics, presentation, and Pi I/O.
|
|
|
39
39
|
4. user-project packs and scope;
|
|
40
40
|
5. trusted repository/package inputs.
|
|
41
41
|
|
|
42
|
-
The baseline
|
|
42
|
+
The baseline comprises the built-in packs described in [RULE_PACKS.md](RULE_PACKS.md#baseline), including `bash.network.read`, `pi.extension.network-research`, and `pi.home.safe`. Individual pack ids flow into provenance; no posture pseudo-pack exists.
|
|
43
43
|
|
|
44
44
|
## Commands
|
|
45
45
|
|
|
46
|
-
`/clearance`, `/clearance setup`, `/clearance mode [off|ask|auto]`, `/clearance settings`, `/clearance status`, `/clearance packs`, `/clearance scope`, `/clearance tune`, `/clearance why`, `/clearance allow <plain language>`, and `/clearance allow`. The allow handler only hands a deterministic brief to the agent; it does not construct policy or call the reviewer. `/clearance profile` and `/clearance auto` are
|
|
46
|
+
`/clearance`, `/clearance setup`, `/clearance mode [off|ask|auto]`, `/clearance settings`, `/clearance status`, `/clearance packs`, `/clearance scope`, `/clearance tune`, `/clearance why`, `/clearance allow <plain language>`, and `/clearance allow`. The allow handler only hands a deterministic brief to the agent; it does not construct policy or call the reviewer. `/clearance profile` and `/clearance auto` are unsupported and have no aliases.
|
|
@@ -34,7 +34,7 @@ Global and project config written through Clearance is persisted sparsely. Packa
|
|
|
34
34
|
/clearance allow
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Bare `/clearance` opens guided setup. `/clearance mode` without an argument still opens settings. `/clearance profile` and `/clearance auto`
|
|
37
|
+
Bare `/clearance` opens guided setup. `/clearance mode` without an argument still opens settings. `/clearance profile` and `/clearance auto` are unsupported and have no aliases. Settings mutations require interactive confirmation and write only user-owned config.
|
|
38
38
|
|
|
39
39
|
## Allow a command family
|
|
40
40
|
|
|
@@ -59,14 +59,13 @@ Review surfaces speak plain language. The human approval card shows what the com
|
|
|
59
59
|
|
|
60
60
|
The settings control center uses compact selector/toggle rows. It exposes mode, reviewer model and evidence posture, scope preset and unknown-path behavior, a pack explorer, exact gated non-Bash tools, and Stream briefing preferences (note mode, model label, accent). Every mutation uses confirmation, the config planner, atomic write, reload, and policy invalidation. Advanced context, budget, escalation, prompt appends, and overrides remain config-file settings; status names their customization categories without dumping values.
|
|
61
61
|
|
|
62
|
-
The baseline is broad by default:
|
|
62
|
+
The baseline is broad by default: the [built-in packs](RULE_PACKS.md#baseline) cover inspection, shell-builtin and system/service reads, bounded development verification, network reads, typed network research, non-secret home and agent-support typed Pi reads, and safe-home typed Pi mutations. Literal project/temp output redirects and `/dev/null` are eligible, while dynamic, `.git`, unknown-fd, and network output redirects remain review-gated. Installed package packs are merely available until explicitly enabled by user-owned config.
|
|
63
63
|
|
|
64
64
|
## Safety model
|
|
65
65
|
|
|
66
66
|
- Parsed structure, not raw shell text, drives policy.
|
|
67
67
|
- Non-Bash tools bypass Clearance unless their exact name appears in global `gatedTools` (default `[]`); Bash is always gated and cannot be listed.
|
|
68
68
|
- Opted-in unknown tools follow `unknownToolPosture` (default `allow`). Wildcards and future-tool opt-in are not supported.
|
|
69
|
-
- This default typed-tool bypass is an intentional published behavior break and must be called out in the next minor release.
|
|
70
69
|
- Parser uncertainty and unsupported forms fail closed to review.
|
|
71
70
|
- Model decisions resolve one call and never create permanent policy.
|
|
72
71
|
- Tune mode proposes user-approved inspectable data-pack changes after replay and adversarial evidence; executable TypeScript rule modules are not supported.
|
|
@@ -20,4 +20,4 @@ The sealed floor always wins. Invalid config fails closed to floor-only policy.
|
|
|
20
20
|
|
|
21
21
|
## Trust and growth
|
|
22
22
|
|
|
23
|
-
User-owned global/project config may widen policy. Repository policy and installed packs cannot silently widen it. Persisted settings written through Clearance contain only non-default choices, while runtime normalization supplies the rest. Package installation neither changes config nor enables packs. Tune replay, adversarial checks, explicit confirmation, and post-write validation make policy growth auditable.
|
|
23
|
+
User-owned global/project config may widen policy. Repository policy and installed packs cannot silently widen it. Persisted settings written through Clearance contain only non-default choices, while runtime normalization supplies the rest. Package installation neither changes config nor enables packs. Tune replay, adversarial checks, explicit confirmation, and post-write validation make policy growth auditable.
|
|
Binary file
|
|
@@ -33,7 +33,7 @@ Run them in joined or detached mode, steer them while active, resume retained se
|
|
|
33
33
|
## Install
|
|
34
34
|
|
|
35
35
|
This branch is locally qualified but unpublished, so it cannot be installed from npm yet.
|
|
36
|
-
|
|
36
|
+
The published package is `@nklisch/pi-subagents`. [Fork maintenance](./docs/FORK-MAINTENANCE.md) records its provenance, release policy, and compatibility commitments.
|
|
37
37
|
|
|
38
38
|
Load it directly for development:
|
|
39
39
|
|
|
@@ -458,7 +458,7 @@ It never throws — all error conditions produce a `console.warn` and return `{}
|
|
|
458
458
|
|
|
459
459
|
This extension is a minimal, composable core: it owns agent spawning, execution, and result retrieval, and exposes a typed `SubagentsService` plus lifecycle events that other extensions build on.
|
|
460
460
|
|
|
461
|
-
See [`docs/architecture/architecture.md`](./docs/architecture/architecture.md) for
|
|
461
|
+
See [`docs/architecture/architecture.md`](./docs/architecture/architecture.md) for design principles, domain ownership, lifecycle and service contracts, and module dependency diagrams.
|
|
462
462
|
|
|
463
463
|
## Relationship to upstream
|
|
464
464
|
|
|
@@ -28,9 +28,8 @@ model, exact effective thinking level, active or final runtime, run id, delivery
|
|
|
28
28
|
mode, and terminal reason when one exists. Parent-only lifecycle tools are
|
|
29
29
|
centrally registered and removed from child tool definitions, preventing
|
|
30
30
|
recursive orchestration while preserving ordinary inherited extension tools.
|
|
31
|
-
The package excludes
|
|
32
|
-
conversation viewer
|
|
33
|
-
history).
|
|
31
|
+
The package excludes agent-definition editors, wizards, and a bespoke
|
|
32
|
+
conversation viewer; ADR 0004 defines the narrow operator UI contract.
|
|
34
33
|
|
|
35
34
|
## Fork posture
|
|
36
35
|
|