@deftai/directive-core 0.79.3 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/coverage-hotspots/evaluate.d.ts +49 -0
- package/dist/coverage-hotspots/evaluate.js +262 -0
- package/dist/coverage-hotspots/index.d.ts +3 -0
- package/dist/coverage-hotspots/index.js +3 -0
- package/dist/coverage-hotspots/thresholds.d.ts +5 -0
- package/dist/coverage-hotspots/thresholds.js +48 -0
- package/dist/hooks/dispatcher.d.ts +25 -3
- package/dist/hooks/dispatcher.js +216 -65
- package/dist/hooks/readonly.d.ts +7 -0
- package/dist/hooks/readonly.js +83 -0
- package/dist/hooks/tools.d.ts +7 -0
- package/dist/hooks/tools.js +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/agent-hooks.d.ts +4 -1
- package/dist/init-deposit/agent-hooks.js +77 -21
- package/dist/init-deposit/xbrief-projections.d.ts +7 -0
- package/dist/init-deposit/xbrief-projections.js +29 -1
- package/dist/integration-e2e/bootstrap-cache-module.d.ts +2 -4
- package/dist/integration-e2e/bootstrap-cache-module.js +2 -20
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.js +31 -1
- package/dist/policy/runtime-authority.d.ts +54 -0
- package/dist/policy/runtime-authority.js +180 -0
- package/dist/policy/staleness-tickler.d.ts +20 -0
- package/dist/policy/staleness-tickler.js +151 -0
- package/dist/pr-merge-readiness/ci-gate.d.ts +7 -1
- package/dist/pr-merge-readiness/ci-gate.js +38 -5
- package/dist/pr-merge-readiness/gh.d.ts +4 -0
- package/dist/pr-merge-readiness/gh.js +10 -3
- package/dist/pr-merge-readiness/index.d.ts +2 -1
- package/dist/pr-merge-readiness/index.js +2 -1
- package/dist/pr-merge-readiness/runner-capacity-stall.d.ts +35 -0
- package/dist/pr-merge-readiness/runner-capacity-stall.js +46 -0
- package/dist/pr-wait-mergeable/cascade.js +8 -1
- package/dist/pr-wait-mergeable/classify.js +5 -1
- package/dist/pr-wait-mergeable/wrappers.js +15 -4
- package/dist/pr-watch/constants.d.ts +15 -0
- package/dist/pr-watch/constants.js +16 -1
- package/dist/pr-watch/main.js +12 -0
- package/dist/pr-watch/probe.js +13 -1
- package/dist/pr-watch/types.d.ts +9 -0
- package/dist/pr-watch/watch.js +24 -1
- package/dist/scope/main.js +12 -0
- package/dist/scope/undo.js +12 -2
- package/dist/session/release-availability.d.ts +21 -0
- package/dist/session/release-availability.js +109 -0
- package/dist/session/ritual-sentinel.d.ts +14 -0
- package/dist/session/ritual-sentinel.js +28 -0
- package/dist/session/session-start.d.ts +10 -0
- package/dist/session/session-start.js +18 -0
- package/dist/staleness-tickler/escalation.d.ts +14 -0
- package/dist/staleness-tickler/escalation.js +106 -0
- package/dist/staleness-tickler/idle.d.ts +18 -0
- package/dist/staleness-tickler/idle.js +47 -0
- package/dist/staleness-tickler/index.d.ts +8 -0
- package/dist/staleness-tickler/index.js +8 -0
- package/dist/staleness-tickler/probe-directive.d.ts +32 -0
- package/dist/staleness-tickler/probe-directive.js +106 -0
- package/dist/staleness-tickler/probe-xbrief.d.ts +12 -0
- package/dist/staleness-tickler/probe-xbrief.js +103 -0
- package/dist/staleness-tickler/run.d.ts +31 -0
- package/dist/staleness-tickler/run.js +227 -0
- package/dist/staleness-tickler/state.d.ts +10 -0
- package/dist/staleness-tickler/state.js +46 -0
- package/dist/staleness-tickler/types.d.ts +85 -0
- package/dist/staleness-tickler/types.js +5 -0
- package/dist/triage/bootstrap/cache-module.d.ts +25 -0
- package/dist/triage/bootstrap/cache-module.js +39 -0
- package/dist/triage/bootstrap/index.d.ts +1 -0
- package/dist/triage/bootstrap/index.js +7 -82
- package/dist/vbrief-validate/plan-hooks.d.ts +4 -0
- package/dist/vbrief-validate/plan-hooks.js +50 -0
- package/dist/verify-env/agent-hooks.js +4 -2
- package/dist/xbrief-migrate/agents-header.d.ts +0 -11
- package/dist/xbrief-migrate/agents-header.js +10 -1
- package/package.json +3 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { assertDepositContained } from "../deposit/contain.js";
|
|
4
|
-
import {
|
|
5
|
-
export
|
|
4
|
+
import { DIRECT_WRITE_HOOK_MATCHER, SPAWN_HOOK_MATCHER } from "../hooks/tools.js";
|
|
5
|
+
export { DIRECT_WRITE_HOOK_MATCHER, SPAWN_HOOK_MATCHER } from "../hooks/tools.js";
|
|
6
6
|
export const DEFT_HOOK_COMMAND_MARKER = "deft hook:dispatch";
|
|
7
7
|
export const AGENT_HOOK_PATHS = [
|
|
8
8
|
".claude/settings.json",
|
|
@@ -67,9 +67,9 @@ function isManagedCursorEntry(value) {
|
|
|
67
67
|
const entry = object(value);
|
|
68
68
|
return typeof entry?.command === "string" && entry.command.includes(DEFT_HOOK_COMMAND_MARKER);
|
|
69
69
|
}
|
|
70
|
-
function nestedGroup(host, event) {
|
|
70
|
+
function nestedGroup(host, event, matcher) {
|
|
71
71
|
return {
|
|
72
|
-
...(event === "tool.before" ? { matcher
|
|
72
|
+
...(event === "tool.before" && matcher !== undefined ? { matcher } : {}),
|
|
73
73
|
hooks: [
|
|
74
74
|
{
|
|
75
75
|
type: "command",
|
|
@@ -79,18 +79,29 @@ function nestedGroup(host, event) {
|
|
|
79
79
|
],
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
function mergeNestedConfig(config, path, host) {
|
|
82
|
+
function mergeNestedConfig(config, path, host, options = {}) {
|
|
83
83
|
const hooks = hooksObject(config, path);
|
|
84
84
|
const session = eventArray(hooks, "SessionStart", path).filter((entry) => !isManagedNestedGroup(entry));
|
|
85
85
|
const preTool = eventArray(hooks, "PreToolUse", path).filter((entry) => !isManagedNestedGroup(entry));
|
|
86
86
|
hooks.SessionStart = [...session, nestedGroup(host, "session.start")];
|
|
87
|
-
hooks.PreToolUse = [
|
|
87
|
+
hooks.PreToolUse = [
|
|
88
|
+
...preTool,
|
|
89
|
+
nestedGroup(host, "tool.before", DIRECT_WRITE_HOOK_MATCHER),
|
|
90
|
+
nestedGroup(host, "tool.before", SPAWN_HOOK_MATCHER),
|
|
91
|
+
];
|
|
92
|
+
if (options.compact) {
|
|
93
|
+
const preCompact = eventArray(hooks, "PreCompact", path).filter((entry) => !isManagedNestedGroup(entry));
|
|
94
|
+
const postCompact = eventArray(hooks, "PostCompact", path).filter((entry) => !isManagedNestedGroup(entry));
|
|
95
|
+
hooks.PreCompact = [...preCompact, nestedGroup(host, "session.compact")];
|
|
96
|
+
hooks.PostCompact = [...postCompact, nestedGroup(host, "session.compact")];
|
|
97
|
+
}
|
|
88
98
|
return { ...config, hooks };
|
|
89
99
|
}
|
|
90
100
|
function mergeCursorConfig(config, path) {
|
|
91
101
|
const hooks = hooksObject(config, path);
|
|
92
102
|
const session = eventArray(hooks, "sessionStart", path).filter((entry) => !isManagedCursorEntry(entry));
|
|
93
103
|
const preTool = eventArray(hooks, "preToolUse", path).filter((entry) => !isManagedCursorEntry(entry));
|
|
104
|
+
const preCompact = eventArray(hooks, "preCompact", path).filter((entry) => !isManagedCursorEntry(entry));
|
|
94
105
|
hooks.sessionStart = [...session, { command: command("cursor", "session.start"), timeout: 5 }];
|
|
95
106
|
hooks.preToolUse = [
|
|
96
107
|
...preTool,
|
|
@@ -100,7 +111,14 @@ function mergeCursorConfig(config, path) {
|
|
|
100
111
|
failClosed: true,
|
|
101
112
|
timeout: 5,
|
|
102
113
|
},
|
|
114
|
+
{
|
|
115
|
+
command: command("cursor", "tool.before"),
|
|
116
|
+
matcher: SPAWN_HOOK_MATCHER,
|
|
117
|
+
failClosed: true,
|
|
118
|
+
timeout: 5,
|
|
119
|
+
},
|
|
103
120
|
];
|
|
121
|
+
hooks.preCompact = [...preCompact, { command: command("cursor", "session.compact"), timeout: 5 }];
|
|
104
122
|
return { ...config, version: 1, hooks };
|
|
105
123
|
}
|
|
106
124
|
function writeJsonIfChanged(path, payload) {
|
|
@@ -119,16 +137,16 @@ export function writeAgentHookDeposit(projectRoot, io = { printf: () => undefine
|
|
|
119
137
|
const definitions = [
|
|
120
138
|
{
|
|
121
139
|
path: AGENT_HOOK_PATHS[0],
|
|
122
|
-
merge: (config, path) => mergeNestedConfig(config, path, "claude"),
|
|
140
|
+
merge: (config, path) => mergeNestedConfig(config, path, "claude", { compact: true }),
|
|
123
141
|
},
|
|
124
142
|
{
|
|
125
143
|
path: AGENT_HOOK_PATHS[1],
|
|
126
|
-
merge: (config, path) => mergeNestedConfig(config, path, "grok"),
|
|
144
|
+
merge: (config, path) => mergeNestedConfig(config, path, "grok", { compact: true }),
|
|
127
145
|
},
|
|
128
146
|
{ path: AGENT_HOOK_PATHS[2], merge: mergeCursorConfig },
|
|
129
147
|
{
|
|
130
148
|
path: AGENT_HOOK_PATHS[3],
|
|
131
|
-
merge: (config, path) => mergeNestedConfig(config, path, "codex"),
|
|
149
|
+
merge: (config, path) => mergeNestedConfig(config, path, "codex", { compact: false }),
|
|
132
150
|
},
|
|
133
151
|
];
|
|
134
152
|
const prepared = definitions.map((definition) => {
|
|
@@ -150,7 +168,7 @@ export function writeAgentHookDeposit(projectRoot, io = { printf: () => undefine
|
|
|
150
168
|
}
|
|
151
169
|
return { changed: changedPaths.length > 0, changedPaths };
|
|
152
170
|
}
|
|
153
|
-
function hasNestedRegistration(config, host) {
|
|
171
|
+
function hasNestedRegistration(config, host, options = {}) {
|
|
154
172
|
const hooks = object(config.hooks);
|
|
155
173
|
if (hooks === null)
|
|
156
174
|
return false;
|
|
@@ -158,11 +176,24 @@ function hasNestedRegistration(config, host) {
|
|
|
158
176
|
const preTool = Array.isArray(hooks.PreToolUse) ? hooks.PreToolUse : [];
|
|
159
177
|
const sessionCommand = command(host, "session.start");
|
|
160
178
|
const toolCommand = command(host, "tool.before");
|
|
161
|
-
|
|
179
|
+
const compactCommand = command(host, "session.compact");
|
|
180
|
+
const base = session.some((entry) => nestedCommands(entry).includes(sessionCommand)) &&
|
|
162
181
|
preTool.some((entry) => {
|
|
163
182
|
const group = object(entry);
|
|
164
183
|
return (group?.matcher === DIRECT_WRITE_HOOK_MATCHER && nestedCommands(entry).includes(toolCommand));
|
|
165
|
-
})
|
|
184
|
+
}) &&
|
|
185
|
+
preTool.some((entry) => {
|
|
186
|
+
const group = object(entry);
|
|
187
|
+
return group?.matcher === SPAWN_HOOK_MATCHER && nestedCommands(entry).includes(toolCommand);
|
|
188
|
+
});
|
|
189
|
+
if (!base)
|
|
190
|
+
return false;
|
|
191
|
+
if (!options.compact)
|
|
192
|
+
return true;
|
|
193
|
+
const preCompact = Array.isArray(hooks.PreCompact) ? hooks.PreCompact : [];
|
|
194
|
+
const postCompact = Array.isArray(hooks.PostCompact) ? hooks.PostCompact : [];
|
|
195
|
+
return (preCompact.some((entry) => nestedCommands(entry).includes(compactCommand)) &&
|
|
196
|
+
postCompact.some((entry) => nestedCommands(entry).includes(compactCommand)));
|
|
166
197
|
}
|
|
167
198
|
function hasCursorRegistration(config) {
|
|
168
199
|
const hooks = object(config.hooks);
|
|
@@ -170,13 +201,21 @@ function hasCursorRegistration(config) {
|
|
|
170
201
|
return false;
|
|
171
202
|
const session = Array.isArray(hooks.sessionStart) ? hooks.sessionStart : [];
|
|
172
203
|
const preTool = Array.isArray(hooks.preToolUse) ? hooks.preToolUse : [];
|
|
204
|
+
const preCompact = Array.isArray(hooks.preCompact) ? hooks.preCompact : [];
|
|
173
205
|
return (session.some((entry) => object(entry)?.command === command("cursor", "session.start")) &&
|
|
174
206
|
preTool.some((entry) => {
|
|
175
207
|
const hook = object(entry);
|
|
176
208
|
return (hook?.command === command("cursor", "tool.before") &&
|
|
177
209
|
hook.matcher === DIRECT_WRITE_HOOK_MATCHER &&
|
|
178
210
|
hook.failClosed === true);
|
|
179
|
-
})
|
|
211
|
+
}) &&
|
|
212
|
+
preTool.some((entry) => {
|
|
213
|
+
const hook = object(entry);
|
|
214
|
+
return (hook?.command === command("cursor", "tool.before") &&
|
|
215
|
+
hook.matcher === SPAWN_HOOK_MATCHER &&
|
|
216
|
+
hook.failClosed === true);
|
|
217
|
+
}) &&
|
|
218
|
+
preCompact.some((entry) => object(entry)?.command === command("cursor", "session.compact")));
|
|
180
219
|
}
|
|
181
220
|
/** Read-only registration probe shared by verify and doctor. */
|
|
182
221
|
export function inspectAgentHookDeposit(projectRoot) {
|
|
@@ -184,28 +223,40 @@ export function inspectAgentHookDeposit(projectRoot) {
|
|
|
184
223
|
{
|
|
185
224
|
host: "claude",
|
|
186
225
|
path: AGENT_HOOK_PATHS[0],
|
|
187
|
-
|
|
226
|
+
compactSupport: "deposited",
|
|
227
|
+
valid: (config) => hasNestedRegistration(config, "claude", { compact: true }),
|
|
188
228
|
},
|
|
189
229
|
{
|
|
190
230
|
host: "grok",
|
|
191
231
|
path: AGENT_HOOK_PATHS[1],
|
|
192
|
-
|
|
232
|
+
compactSupport: "deposited",
|
|
233
|
+
valid: (config) => hasNestedRegistration(config, "grok", { compact: true }),
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
host: "cursor",
|
|
237
|
+
path: AGENT_HOOK_PATHS[2],
|
|
238
|
+
compactSupport: "deposited",
|
|
239
|
+
valid: hasCursorRegistration,
|
|
193
240
|
},
|
|
194
|
-
{ host: "cursor", path: AGENT_HOOK_PATHS[2], valid: hasCursorRegistration },
|
|
195
241
|
{
|
|
196
242
|
host: "codex",
|
|
197
243
|
path: AGENT_HOOK_PATHS[3],
|
|
198
|
-
|
|
244
|
+
compactSupport: "unsupported",
|
|
245
|
+
valid: (config) => hasNestedRegistration(config, "codex", { compact: false }),
|
|
199
246
|
},
|
|
200
247
|
];
|
|
201
248
|
return definitions.map((definition) => {
|
|
202
249
|
const absolute = join(projectRoot, definition.path);
|
|
250
|
+
const compactNote = definition.compactSupport === "unsupported"
|
|
251
|
+
? " Compact re-arm is not deposited for Codex (no native compact hook surface)."
|
|
252
|
+
: " PreCompact/PostCompact or preCompact compact re-arm is deposited.";
|
|
203
253
|
if (!existsSync(absolute)) {
|
|
204
254
|
return {
|
|
205
255
|
host: definition.host,
|
|
206
256
|
path: definition.path,
|
|
207
257
|
status: "missing",
|
|
208
|
-
|
|
258
|
+
compactSupport: definition.compactSupport,
|
|
259
|
+
detail: `${definition.path} is missing.${compactNote}`,
|
|
209
260
|
};
|
|
210
261
|
}
|
|
211
262
|
try {
|
|
@@ -215,14 +266,18 @@ export function inspectAgentHookDeposit(projectRoot) {
|
|
|
215
266
|
host: definition.host,
|
|
216
267
|
path: definition.path,
|
|
217
268
|
status: "healthy",
|
|
218
|
-
|
|
269
|
+
compactSupport: definition.compactSupport,
|
|
270
|
+
detail: "SessionStart, direct-write + spawn PreToolUse, and compact re-arm registrations are current." +
|
|
271
|
+
(definition.compactSupport === "unsupported" ? compactNote : ""),
|
|
219
272
|
};
|
|
220
273
|
}
|
|
221
274
|
return {
|
|
222
275
|
host: definition.host,
|
|
223
276
|
path: definition.path,
|
|
224
277
|
status: "drifted",
|
|
225
|
-
|
|
278
|
+
compactSupport: definition.compactSupport,
|
|
279
|
+
detail: "Directive SessionStart, direct-write/spawn PreToolUse, or compact re-arm registration is missing/drifted." +
|
|
280
|
+
compactNote,
|
|
226
281
|
};
|
|
227
282
|
}
|
|
228
283
|
catch (cause) {
|
|
@@ -230,7 +285,8 @@ export function inspectAgentHookDeposit(projectRoot) {
|
|
|
230
285
|
host: definition.host,
|
|
231
286
|
path: definition.path,
|
|
232
287
|
status: "drifted",
|
|
233
|
-
|
|
288
|
+
compactSupport: definition.compactSupport,
|
|
289
|
+
detail: `${String(cause)}${compactNote}`,
|
|
234
290
|
};
|
|
235
291
|
}
|
|
236
292
|
});
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
* freshness. A current `.deft/core/VERSION` therefore cannot short-circuit
|
|
6
6
|
* these repairs.
|
|
7
7
|
*/
|
|
8
|
+
/** Rewrite legacy vbrief/.eval description paths for xbrief/schemas projection (#2670). */
|
|
9
|
+
export declare function rewriteProjectedSchemaContent(content: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Fail closed when a projected xbrief/schemas file still cites vbrief/.eval/.
|
|
12
|
+
* Upstream vbrief/schemas/ may keep legacy paths; consumer copies must not (#2670).
|
|
13
|
+
*/
|
|
14
|
+
export declare function assertProjectedSchemaDescriptionsRooted(projectDir: string, destinationDir: string): void;
|
|
8
15
|
/**
|
|
9
16
|
* Synchronize framework-owned xBRIEF schemas while preserving unknown consumer
|
|
10
17
|
* files. The obsolete v0.6 root schema is the only destination-only file this
|
|
@@ -13,6 +13,10 @@ import { DEV_FALLBACK } from "../platform/constants.js";
|
|
|
13
13
|
import { MIGRATED_ARTIFACT_DIR } from "../xbrief-migrate/constants.js";
|
|
14
14
|
const OBSOLETE_CORE_SCHEMA = "vbrief-core.schema.json";
|
|
15
15
|
const CURRENT_CORE_SCHEMA = "xbrief-core-0.8.schema.json";
|
|
16
|
+
/** Legacy lifecycle eval prefix in framework vbrief/schemas source copies. */
|
|
17
|
+
const LEGACY_EVAL_PATH_PREFIX = "vbrief/.eval/";
|
|
18
|
+
/** Consumer xbrief/schemas projection must root description paths here (#2670). */
|
|
19
|
+
const XBRIEF_EVAL_PATH_PREFIX = "xbrief/.eval/";
|
|
16
20
|
function normalizeVersion(version) {
|
|
17
21
|
return version.trim().replace(/^v/, "");
|
|
18
22
|
}
|
|
@@ -39,6 +43,28 @@ function collectSchemaFiles(root, dir = root, files = []) {
|
|
|
39
43
|
}
|
|
40
44
|
return files;
|
|
41
45
|
}
|
|
46
|
+
/** Rewrite legacy vbrief/.eval description paths for xbrief/schemas projection (#2670). */
|
|
47
|
+
export function rewriteProjectedSchemaContent(content) {
|
|
48
|
+
return content.includes(LEGACY_EVAL_PATH_PREFIX)
|
|
49
|
+
? content.replaceAll(LEGACY_EVAL_PATH_PREFIX, XBRIEF_EVAL_PATH_PREFIX)
|
|
50
|
+
: content;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Fail closed when a projected xbrief/schemas file still cites vbrief/.eval/.
|
|
54
|
+
* Upstream vbrief/schemas/ may keep legacy paths; consumer copies must not (#2670).
|
|
55
|
+
*/
|
|
56
|
+
export function assertProjectedSchemaDescriptionsRooted(projectDir, destinationDir) {
|
|
57
|
+
assertProjectionContained(projectDir, destinationDir);
|
|
58
|
+
if (!isDirectory(destinationDir))
|
|
59
|
+
return;
|
|
60
|
+
for (const rel of collectSchemaFiles(destinationDir)) {
|
|
61
|
+
const full = join(destinationDir, rel);
|
|
62
|
+
const text = readFileSync(full, "utf8");
|
|
63
|
+
if (text.includes(LEGACY_EVAL_PATH_PREFIX)) {
|
|
64
|
+
throw new Error(`projected xbrief schema still cites ${LEGACY_EVAL_PATH_PREFIX}: ${join(MIGRATED_ARTIFACT_DIR, "schemas", rel)}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
42
68
|
function writeFileIfChanged(projectDir, target, content) {
|
|
43
69
|
assertProjectionContained(projectDir, target);
|
|
44
70
|
const desired = Buffer.isBuffer(content) ? content : Buffer.from(content, "utf8");
|
|
@@ -73,7 +99,8 @@ export function syncConsumerXbriefSchemas(projectDir, deftDir) {
|
|
|
73
99
|
continue;
|
|
74
100
|
const source = join(sourceDir, rel);
|
|
75
101
|
const destination = join(destinationDir, rel);
|
|
76
|
-
|
|
102
|
+
const projected = rewriteProjectedSchemaContent(readFileSync(source, "utf8"));
|
|
103
|
+
changed = writeFileIfChanged(projectDir, destination, projected) || changed;
|
|
77
104
|
}
|
|
78
105
|
const obsoleteDestination = join(destinationDir, OBSOLETE_CORE_SCHEMA);
|
|
79
106
|
assertProjectionContained(projectDir, obsoleteDestination);
|
|
@@ -81,6 +108,7 @@ export function syncConsumerXbriefSchemas(projectDir, deftDir) {
|
|
|
81
108
|
rmSync(obsoleteDestination, { force: true });
|
|
82
109
|
changed = true;
|
|
83
110
|
}
|
|
111
|
+
assertProjectedSchemaDescriptionsRooted(projectDir, destinationDir);
|
|
84
112
|
return changed;
|
|
85
113
|
}
|
|
86
114
|
function syncBareVersionMarkerWithPolicy(projectDir, version, allowRootFallback) {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** Adapt TS cache reports to the bootstrap `FetchAllReport` shape. */
|
|
4
|
-
export declare function bootstrapCacheModule(cacheFetchAll: (options: Parameters<typeof import("../cache/fetch.js").cacheFetchAll>[0]) => FetchAllReportImpl): CacheModule;
|
|
1
|
+
/** Re-export bootstrap TS cache adapter (canonical home: triage/bootstrap). */
|
|
2
|
+
export { bootstrapCacheModule } from "../triage/bootstrap/cache-module.js";
|
|
5
3
|
//# sourceMappingURL=bootstrap-cache-module.d.ts.map
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
3
|
-
return {
|
|
4
|
-
cacheFetchAll(kwargs) {
|
|
5
|
-
const report = cacheFetchAll({
|
|
6
|
-
source: kwargs.source,
|
|
7
|
-
repo: kwargs.repo,
|
|
8
|
-
batchSize: kwargs.batchSize,
|
|
9
|
-
delayMs: kwargs.delayMs,
|
|
10
|
-
cacheRoot: kwargs.cacheRoot,
|
|
11
|
-
});
|
|
12
|
-
return Promise.resolve({
|
|
13
|
-
succeeded: report.issuesWritten,
|
|
14
|
-
failed: report.issuesFailed,
|
|
15
|
-
skipped: report.alreadyFresh,
|
|
16
|
-
summaryLine: (source, repo) => report.summaryLine(source, repo),
|
|
17
|
-
});
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
}
|
|
1
|
+
/** Re-export bootstrap TS cache adapter (canonical home: triage/bootstrap). */
|
|
2
|
+
export { bootstrapCacheModule } from "../triage/bootstrap/cache-module.js";
|
|
21
3
|
//# sourceMappingURL=bootstrap-cache-module.js.map
|
package/dist/policy/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./disclosure.js";
|
|
|
6
6
|
export * from "./plan-extensions.js";
|
|
7
7
|
export * from "./policy-invocation.js";
|
|
8
8
|
export * from "./resolve.js";
|
|
9
|
+
export * from "./runtime-authority.js";
|
|
10
|
+
export * from "./staleness-tickler.js";
|
|
9
11
|
export * from "./value-feedback.js";
|
|
10
12
|
export * from "./wip.js";
|
|
11
13
|
export declare const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
package/dist/policy/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { readPlanPolicy } from "./plan-extensions.js";
|
|
2
2
|
import { coerceLegacyNarrative, LEGACY_NARRATIVE_KEY, loadProjectDefinition } from "./resolve.js";
|
|
3
|
+
import { FIELD_RUNTIME_AUTHORITY, FIELD_RUNTIME_AUTHORITY_CLI_ALIAS, inspectRuntimeAuthority, } from "./runtime-authority.js";
|
|
4
|
+
import { FIELD_STALENESS_TICKLER, FIELD_STALENESS_TICKLER_CLI_ALIAS, inspectStalenessTickler, } from "./staleness-tickler.js";
|
|
3
5
|
import { FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, inspectValueFeedback, } from "./value-feedback.js";
|
|
4
6
|
import { DEFAULT_WIP_CAP } from "./wip.js";
|
|
5
7
|
export * from "./agents-md-advisory.js";
|
|
@@ -10,6 +12,8 @@ export * from "./disclosure.js";
|
|
|
10
12
|
export * from "./plan-extensions.js";
|
|
11
13
|
export * from "./policy-invocation.js";
|
|
12
14
|
export * from "./resolve.js";
|
|
15
|
+
export * from "./runtime-authority.js";
|
|
16
|
+
export * from "./staleness-tickler.js";
|
|
13
17
|
export * from "./value-feedback.js";
|
|
14
18
|
export * from "./wip.js";
|
|
15
19
|
export const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
|
@@ -225,6 +229,24 @@ function inspectValueFeedbackField(data, projectRoot) {
|
|
|
225
229
|
source: field.source,
|
|
226
230
|
};
|
|
227
231
|
}
|
|
232
|
+
function inspectStalenessTicklerField(data) {
|
|
233
|
+
const field = inspectStalenessTickler(data);
|
|
234
|
+
return {
|
|
235
|
+
name: field.name,
|
|
236
|
+
current: field.current,
|
|
237
|
+
default: field.default,
|
|
238
|
+
source: field.source,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function inspectRuntimeAuthorityField(data) {
|
|
242
|
+
const field = inspectRuntimeAuthority(data);
|
|
243
|
+
return {
|
|
244
|
+
name: field.name,
|
|
245
|
+
current: field.current,
|
|
246
|
+
default: field.default,
|
|
247
|
+
source: field.source,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
228
250
|
const REGISTERED_POLICIES = [
|
|
229
251
|
inspectAllowDirectCommits,
|
|
230
252
|
inspectWipCap,
|
|
@@ -237,6 +259,8 @@ const REGISTERED_POLICIES = [
|
|
|
237
259
|
emptyIsTyped: true,
|
|
238
260
|
}),
|
|
239
261
|
inspectSwarmSubagentBackend,
|
|
262
|
+
inspectStalenessTicklerField,
|
|
263
|
+
inspectRuntimeAuthorityField,
|
|
240
264
|
inspectValueFeedbackField,
|
|
241
265
|
];
|
|
242
266
|
/** Walk registered inspectors and return one row per field (#1148). */
|
|
@@ -246,7 +270,13 @@ export function inspectAllPolicies(projectRoot) {
|
|
|
246
270
|
}
|
|
247
271
|
/** Look up a single registered field by canonical dotted-path name (or CLI alias). */
|
|
248
272
|
export function inspectOnePolicy(name, projectRoot) {
|
|
249
|
-
const normalized = name === FIELD_VALUE_FEEDBACK_CLI_ALIAS
|
|
273
|
+
const normalized = name === FIELD_VALUE_FEEDBACK_CLI_ALIAS
|
|
274
|
+
? FIELD_VALUE_FEEDBACK
|
|
275
|
+
: name === FIELD_STALENESS_TICKLER_CLI_ALIAS
|
|
276
|
+
? FIELD_STALENESS_TICKLER
|
|
277
|
+
: name === FIELD_RUNTIME_AUTHORITY_CLI_ALIAS
|
|
278
|
+
? FIELD_RUNTIME_AUTHORITY
|
|
279
|
+
: name;
|
|
250
280
|
for (const field of inspectAllPolicies(projectRoot)) {
|
|
251
281
|
if (field.name === normalized)
|
|
252
282
|
return field;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const FIELD_RUNTIME_AUTHORITY = "plan.policy.runtimeAuthority";
|
|
2
|
+
export declare const FIELD_RUNTIME_AUTHORITY_CLI_ALIAS = "runtimeAuthority";
|
|
3
|
+
/** Graduated permission scopes (#1394 steipete ladder). */
|
|
4
|
+
export interface RuntimeAuthorityScopes {
|
|
5
|
+
/** Direct edit/write tools (PreToolUse classifiable today). */
|
|
6
|
+
readonly edits: boolean;
|
|
7
|
+
/** git push / tag push — enforced only when Shell payload is classifiable (host gap). */
|
|
8
|
+
readonly push: boolean;
|
|
9
|
+
/** merge / close / release — enforced only when Shell payload is classifiable (host gap). */
|
|
10
|
+
readonly merge: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface RuntimeAuthorityPolicy {
|
|
13
|
+
readonly enabled: boolean;
|
|
14
|
+
/** When non-empty, write targets must match at least one pattern. Empty = allow all paths. */
|
|
15
|
+
readonly allowPaths: readonly string[];
|
|
16
|
+
/** Deny wins over allow. */
|
|
17
|
+
readonly denyPaths: readonly string[];
|
|
18
|
+
readonly scopes: RuntimeAuthorityScopes;
|
|
19
|
+
}
|
|
20
|
+
export declare const DEFAULT_RUNTIME_AUTHORITY_SCOPES: RuntimeAuthorityScopes;
|
|
21
|
+
/** Safe default: opt-in only — existing consumers see no runtime authority until enabled. */
|
|
22
|
+
export declare const DEFAULT_RUNTIME_AUTHORITY_POLICY: RuntimeAuthorityPolicy;
|
|
23
|
+
export interface RuntimeAuthorityPolicyField {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly current: RuntimeAuthorityPolicy;
|
|
26
|
+
readonly default: RuntimeAuthorityPolicy;
|
|
27
|
+
readonly source: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function resolveRuntimeAuthorityPolicy(raw: unknown): RuntimeAuthorityPolicy;
|
|
30
|
+
export declare function validateRuntimeAuthority(value: unknown): string[];
|
|
31
|
+
/** Inspector row for `policy:show --field=runtimeAuthority`. */
|
|
32
|
+
export declare function inspectRuntimeAuthority(data: Record<string, unknown> | null): RuntimeAuthorityPolicyField;
|
|
33
|
+
/** Resolve typed runtime authority policy from PROJECT-DEFINITION. */
|
|
34
|
+
export declare function loadRuntimeAuthorityPolicy(data: Record<string, unknown> | null): RuntimeAuthorityPolicy;
|
|
35
|
+
/** Load runtime authority from a project root (PROJECT-DEFINITION on disk). */
|
|
36
|
+
export declare function loadRuntimeAuthorityFromProject(projectRoot: string): RuntimeAuthorityPolicy;
|
|
37
|
+
export type RuntimeAuthorityPathVerdict = "allow" | "deny-allowlist" | "deny-denylist";
|
|
38
|
+
/** Evaluate a project-relative POSIX path against allow/deny globs. */
|
|
39
|
+
export declare function evaluateRuntimeAuthorityPath(policy: RuntimeAuthorityPolicy, relPathPosix: string): RuntimeAuthorityPathVerdict;
|
|
40
|
+
export interface RuntimeAuthorityDirectWriteInput {
|
|
41
|
+
readonly policy: RuntimeAuthorityPolicy;
|
|
42
|
+
readonly relPathPosix: string | null;
|
|
43
|
+
}
|
|
44
|
+
export interface RuntimeAuthorityDirectWriteResult {
|
|
45
|
+
readonly allowed: boolean;
|
|
46
|
+
readonly reason: string | null;
|
|
47
|
+
readonly code: "runtime-policy-deny-scope" | "runtime-policy-deny-path" | null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Evaluate direct-write runtime authority after ritual/scope gates (#1394).
|
|
51
|
+
* Unclassifiable paths (null) pass — host gap documented for Shell/MCP.
|
|
52
|
+
*/
|
|
53
|
+
export declare function evaluateRuntimeAuthorityDirectWrite(input: RuntimeAuthorityDirectWriteInput): RuntimeAuthorityDirectWriteResult;
|
|
54
|
+
//# sourceMappingURL=runtime-authority.d.ts.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { matchAny } from "../orchestration/pathspec.js";
|
|
2
|
+
import { readPlanPolicy } from "./plan-extensions.js";
|
|
3
|
+
import { loadProjectDefinition } from "./resolve.js";
|
|
4
|
+
export const FIELD_RUNTIME_AUTHORITY = "plan.policy.runtimeAuthority";
|
|
5
|
+
export const FIELD_RUNTIME_AUTHORITY_CLI_ALIAS = "runtimeAuthority";
|
|
6
|
+
export const DEFAULT_RUNTIME_AUTHORITY_SCOPES = {
|
|
7
|
+
edits: true,
|
|
8
|
+
push: false,
|
|
9
|
+
merge: false,
|
|
10
|
+
};
|
|
11
|
+
/** Safe default: opt-in only — existing consumers see no runtime authority until enabled. */
|
|
12
|
+
export const DEFAULT_RUNTIME_AUTHORITY_POLICY = {
|
|
13
|
+
enabled: false,
|
|
14
|
+
allowPaths: [],
|
|
15
|
+
denyPaths: [],
|
|
16
|
+
scopes: DEFAULT_RUNTIME_AUTHORITY_SCOPES,
|
|
17
|
+
};
|
|
18
|
+
function readBoolean(rec, key, fallback) {
|
|
19
|
+
if (key in rec && typeof rec[key] === "boolean") {
|
|
20
|
+
return rec[key];
|
|
21
|
+
}
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
function readStringArray(raw) {
|
|
25
|
+
if (!Array.isArray(raw))
|
|
26
|
+
return [];
|
|
27
|
+
return raw.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
28
|
+
}
|
|
29
|
+
function readScopes(raw) {
|
|
30
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
31
|
+
return DEFAULT_RUNTIME_AUTHORITY_SCOPES;
|
|
32
|
+
}
|
|
33
|
+
const rec = raw;
|
|
34
|
+
return {
|
|
35
|
+
edits: readBoolean(rec, "edits", DEFAULT_RUNTIME_AUTHORITY_SCOPES.edits),
|
|
36
|
+
push: readBoolean(rec, "push", DEFAULT_RUNTIME_AUTHORITY_SCOPES.push),
|
|
37
|
+
merge: readBoolean(rec, "merge", DEFAULT_RUNTIME_AUTHORITY_SCOPES.merge),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function resolveRuntimeAuthorityPolicy(raw) {
|
|
41
|
+
if (raw === null || raw === undefined) {
|
|
42
|
+
return DEFAULT_RUNTIME_AUTHORITY_POLICY;
|
|
43
|
+
}
|
|
44
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
45
|
+
return DEFAULT_RUNTIME_AUTHORITY_POLICY;
|
|
46
|
+
}
|
|
47
|
+
const rec = raw;
|
|
48
|
+
return {
|
|
49
|
+
enabled: readBoolean(rec, "enabled", DEFAULT_RUNTIME_AUTHORITY_POLICY.enabled),
|
|
50
|
+
allowPaths: readStringArray(rec.allowPaths),
|
|
51
|
+
denyPaths: readStringArray(rec.denyPaths),
|
|
52
|
+
scopes: readScopes(rec.scopes),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function validateRuntimeAuthority(value) {
|
|
56
|
+
if (value === null || value === undefined) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
60
|
+
return [`${FIELD_RUNTIME_AUTHORITY} must be an object; got ${typeof value}`];
|
|
61
|
+
}
|
|
62
|
+
const rec = value;
|
|
63
|
+
const errors = [];
|
|
64
|
+
if ("enabled" in rec && typeof rec.enabled !== "boolean") {
|
|
65
|
+
errors.push(`${FIELD_RUNTIME_AUTHORITY}.enabled must be a boolean`);
|
|
66
|
+
}
|
|
67
|
+
for (const key of ["allowPaths", "denyPaths"]) {
|
|
68
|
+
if (key in rec && !Array.isArray(rec[key])) {
|
|
69
|
+
errors.push(`${FIELD_RUNTIME_AUTHORITY}.${key} must be an array of path globs`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if ("scopes" in rec) {
|
|
73
|
+
const scopes = rec.scopes;
|
|
74
|
+
if (typeof scopes !== "object" || scopes === null || Array.isArray(scopes)) {
|
|
75
|
+
errors.push(`${FIELD_RUNTIME_AUTHORITY}.scopes must be an object`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
for (const key of ["edits", "push", "merge"]) {
|
|
79
|
+
if (key in scopes &&
|
|
80
|
+
typeof scopes[key] !== "boolean") {
|
|
81
|
+
errors.push(`${FIELD_RUNTIME_AUTHORITY}.scopes.${key} must be a boolean`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return errors;
|
|
87
|
+
}
|
|
88
|
+
function fieldFromResolved(resolved, source) {
|
|
89
|
+
return {
|
|
90
|
+
name: FIELD_RUNTIME_AUTHORITY,
|
|
91
|
+
current: resolved,
|
|
92
|
+
default: DEFAULT_RUNTIME_AUTHORITY_POLICY,
|
|
93
|
+
source,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Inspector row for `policy:show --field=runtimeAuthority`. */
|
|
97
|
+
export function inspectRuntimeAuthority(data) {
|
|
98
|
+
if (data === null) {
|
|
99
|
+
return fieldFromResolved(DEFAULT_RUNTIME_AUTHORITY_POLICY, "default");
|
|
100
|
+
}
|
|
101
|
+
const policyBlock = readPlanPolicy(data.plan);
|
|
102
|
+
if (typeof policyBlock !== "object" ||
|
|
103
|
+
policyBlock === null ||
|
|
104
|
+
Array.isArray(policyBlock) ||
|
|
105
|
+
!("runtimeAuthority" in policyBlock)) {
|
|
106
|
+
return fieldFromResolved(DEFAULT_RUNTIME_AUTHORITY_POLICY, "default");
|
|
107
|
+
}
|
|
108
|
+
const resolved = resolveRuntimeAuthorityPolicy(policyBlock.runtimeAuthority);
|
|
109
|
+
return fieldFromResolved(resolved, "typed");
|
|
110
|
+
}
|
|
111
|
+
/** Resolve typed runtime authority policy from PROJECT-DEFINITION. */
|
|
112
|
+
export function loadRuntimeAuthorityPolicy(data) {
|
|
113
|
+
if (data === null) {
|
|
114
|
+
return DEFAULT_RUNTIME_AUTHORITY_POLICY;
|
|
115
|
+
}
|
|
116
|
+
const policyBlock = readPlanPolicy(data.plan);
|
|
117
|
+
if (typeof policyBlock !== "object" ||
|
|
118
|
+
policyBlock === null ||
|
|
119
|
+
Array.isArray(policyBlock) ||
|
|
120
|
+
!("runtimeAuthority" in policyBlock)) {
|
|
121
|
+
return DEFAULT_RUNTIME_AUTHORITY_POLICY;
|
|
122
|
+
}
|
|
123
|
+
return resolveRuntimeAuthorityPolicy(policyBlock.runtimeAuthority);
|
|
124
|
+
}
|
|
125
|
+
/** Load runtime authority from a project root (PROJECT-DEFINITION on disk). */
|
|
126
|
+
export function loadRuntimeAuthorityFromProject(projectRoot) {
|
|
127
|
+
const [data] = loadProjectDefinition(projectRoot);
|
|
128
|
+
return loadRuntimeAuthorityPolicy(data);
|
|
129
|
+
}
|
|
130
|
+
/** Evaluate a project-relative POSIX path against allow/deny globs. */
|
|
131
|
+
export function evaluateRuntimeAuthorityPath(policy, relPathPosix) {
|
|
132
|
+
if (!policy.enabled)
|
|
133
|
+
return "allow";
|
|
134
|
+
if (matchAny(policy.denyPaths, relPathPosix))
|
|
135
|
+
return "deny-denylist";
|
|
136
|
+
if (policy.allowPaths.length > 0 && !matchAny(policy.allowPaths, relPathPosix)) {
|
|
137
|
+
return "deny-allowlist";
|
|
138
|
+
}
|
|
139
|
+
return "allow";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Evaluate direct-write runtime authority after ritual/scope gates (#1394).
|
|
143
|
+
* Unclassifiable paths (null) pass — host gap documented for Shell/MCP.
|
|
144
|
+
*/
|
|
145
|
+
export function evaluateRuntimeAuthorityDirectWrite(input) {
|
|
146
|
+
const { policy, relPathPosix } = input;
|
|
147
|
+
if (!policy.enabled) {
|
|
148
|
+
return { allowed: true, reason: null, code: null };
|
|
149
|
+
}
|
|
150
|
+
if (!policy.scopes.edits) {
|
|
151
|
+
return {
|
|
152
|
+
allowed: false,
|
|
153
|
+
code: "runtime-policy-deny-scope",
|
|
154
|
+
reason: "Directive denied this direct write: plan.policy.runtimeAuthority.scopes.edits is false. " +
|
|
155
|
+
"Grant the edits scope in PROJECT-DEFINITION or disable runtimeAuthority.",
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (relPathPosix === null) {
|
|
159
|
+
return { allowed: true, reason: null, code: null };
|
|
160
|
+
}
|
|
161
|
+
const pathVerdict = evaluateRuntimeAuthorityPath(policy, relPathPosix);
|
|
162
|
+
if (pathVerdict === "deny-denylist") {
|
|
163
|
+
return {
|
|
164
|
+
allowed: false,
|
|
165
|
+
code: "runtime-policy-deny-path",
|
|
166
|
+
reason: `Directive denied this direct write: path ${relPathPosix} matches ` +
|
|
167
|
+
"plan.policy.runtimeAuthority.denyPaths.",
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (pathVerdict === "deny-allowlist") {
|
|
171
|
+
return {
|
|
172
|
+
allowed: false,
|
|
173
|
+
code: "runtime-policy-deny-path",
|
|
174
|
+
reason: `Directive denied this direct write: path ${relPathPosix} is outside ` +
|
|
175
|
+
"plan.policy.runtimeAuthority.allowPaths.",
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return { allowed: true, reason: null, code: null };
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=runtime-authority.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { StalenessTicklerPolicy, StalenessTicklerSnoozePolicy, StalenessTicklerTierThresholds, StalenessTicklerWeights } from "../staleness-tickler/types.js";
|
|
2
|
+
export declare const FIELD_STALENESS_TICKLER = "plan.policy.stalenessTickler";
|
|
3
|
+
export declare const FIELD_STALENESS_TICKLER_CLI_ALIAS = "stalenessTickler";
|
|
4
|
+
export declare const DEFAULT_STALENESS_TICKLER_WEIGHTS: StalenessTicklerWeights;
|
|
5
|
+
export declare const DEFAULT_STALENESS_TICKLER_TIERS: StalenessTicklerTierThresholds;
|
|
6
|
+
export declare const DEFAULT_STALENESS_TICKLER_SNOOZE: StalenessTicklerSnoozePolicy;
|
|
7
|
+
export declare const DEFAULT_STALENESS_TICKLER_POLICY: StalenessTicklerPolicy;
|
|
8
|
+
export interface StalenessTicklerPolicyField {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly current: StalenessTicklerPolicy;
|
|
11
|
+
readonly default: StalenessTicklerPolicy;
|
|
12
|
+
readonly source: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveStalenessTicklerPolicy(raw: unknown): StalenessTicklerPolicy;
|
|
15
|
+
export declare function validateStalenessTickler(value: unknown): string[];
|
|
16
|
+
/** Inspector row for `policy:show --field=stalenessTickler`. */
|
|
17
|
+
export declare function inspectStalenessTickler(data: Record<string, unknown> | null): StalenessTicklerPolicyField;
|
|
18
|
+
/** Resolve typed staleness tickler policy from PROJECT-DEFINITION. */
|
|
19
|
+
export declare function loadStalenessTicklerPolicy(data: Record<string, unknown> | null): StalenessTicklerPolicy;
|
|
20
|
+
//# sourceMappingURL=staleness-tickler.d.ts.map
|