@deftai/directive-core 0.70.0 → 0.71.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/branch/evaluate.js +7 -0
- package/dist/doctor/doctor-state.js +2 -2
- package/dist/eval/crud-telemetry.d.ts +59 -0
- package/dist/eval/crud-telemetry.js +307 -0
- package/dist/eval/health.d.ts +52 -0
- package/dist/eval/health.js +240 -0
- package/dist/eval/readback.d.ts +38 -0
- package/dist/eval/readback.js +209 -0
- package/dist/eval/report.d.ts +53 -0
- package/dist/eval/report.js +161 -0
- package/dist/eval/run.d.ts +79 -0
- package/dist/eval/run.js +309 -0
- package/dist/events/attribution-constants.d.ts +13 -0
- package/dist/events/attribution-constants.js +18 -0
- package/dist/events/attribution-ledger.d.ts +43 -0
- package/dist/events/attribution-ledger.js +61 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/init-deposit/gitignore.js +15 -5
- package/dist/intake/candidates-log.d.ts +0 -1
- package/dist/intake/candidates-log.js +5 -2
- package/dist/intake/issue-ingest.d.ts +8 -0
- package/dist/intake/issue-ingest.js +19 -1
- package/dist/intake/reconcile-issues.js +9 -2
- package/dist/layout/resolve.d.ts +2 -2
- package/dist/layout/resolve.js +2 -2
- package/dist/lifecycle/events.js +2 -0
- package/dist/orchestration/subagent-monitor.js +2 -2
- package/dist/policy/index.d.ts +2 -1
- package/dist/policy/index.js +15 -2
- package/dist/policy/value-feedback.d.ts +56 -0
- package/dist/policy/value-feedback.js +284 -0
- package/dist/preflight-cache/evaluate.js +4 -3
- package/dist/scope/audit-log.js +3 -3
- package/dist/scope/transition.js +16 -5
- package/dist/session/session-start.js +20 -0
- package/dist/slice/record.js +3 -3
- package/dist/task-surface/index.js +4 -1
- package/dist/triage/actions/candidates-log.d.ts +4 -4
- package/dist/triage/actions/candidates-log.js +4 -7
- package/dist/triage/actions/index.js +8 -32
- package/dist/triage/bootstrap/gitignore.d.ts +9 -3
- package/dist/triage/bootstrap/gitignore.js +77 -40
- package/dist/triage/bootstrap/index.d.ts +1 -1
- package/dist/triage/bootstrap/index.js +4 -3
- package/dist/triage/bulk/index.js +2 -2
- package/dist/triage/cache-path.d.ts +41 -0
- package/dist/triage/cache-path.js +115 -0
- package/dist/triage/help/registry-data.d.ts +48 -15
- package/dist/triage/help/registry-data.js +86 -15
- package/dist/triage/index.d.ts +2 -0
- package/dist/triage/index.js +2 -0
- package/dist/triage/queue/audit.js +2 -2
- package/dist/triage/queue/cache.js +2 -2
- package/dist/triage/reconcile/reconcile.js +4 -3
- package/dist/triage/scope/mutations-core.js +3 -2
- package/dist/triage/subscribe/index.d.ts +1 -1
- package/dist/triage/subscribe/index.js +4 -3
- package/dist/triage/summary/index.d.ts +2 -2
- package/dist/triage/summary/index.js +4 -3
- package/dist/triage/summary/reconcilable.d.ts +1 -1
- package/dist/triage/summary/reconcilable.js +3 -2
- package/dist/triage/welcome/constants.d.ts +2 -2
- package/dist/triage/welcome/constants.js +2 -2
- package/dist/triage/welcome/prior-state.js +3 -2
- package/dist/triage/welcome/summary.js +5 -4
- package/dist/value/adoption-emit.d.ts +14 -0
- package/dist/value/adoption-emit.js +67 -0
- package/dist/value/adoption-registry.d.ts +62 -0
- package/dist/value/adoption-registry.js +214 -0
- package/dist/value/feedback-file.d.ts +67 -0
- package/dist/value/feedback-file.js +353 -0
- package/dist/value/friction-emit.d.ts +10 -0
- package/dist/value/friction-emit.js +24 -0
- package/dist/value/readback.d.ts +86 -0
- package/dist/value/readback.js +503 -0
- package/dist/vbrief-validate/decomposition.js +1 -1
- package/dist/wip-cap/evaluate.js +3 -0
- package/package.json +35 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { DEFAULT_EVENT_LOG, emit } from "../lifecycle/events.js";
|
|
3
|
+
import { isValueFeedbackPathAllowed, resolveValueFeedback, } from "../policy/value-feedback.js";
|
|
4
|
+
import { ATTRIBUTION_EVENT_NAMES } from "./attribution-constants.js";
|
|
5
|
+
export { ALL_ATTRIBUTION_EVENT_NAMES, ATTRIBUTION_EVENT_NAMES, ATTRIBUTION_REQUIRED_PAYLOAD, } from "./attribution-constants.js";
|
|
6
|
+
function resolveLedgerLogPath(projectRoot, logPath) {
|
|
7
|
+
if (logPath !== undefined && logPath !== null) {
|
|
8
|
+
return resolve(logPath);
|
|
9
|
+
}
|
|
10
|
+
return resolve(projectRoot, DEFAULT_EVENT_LOG);
|
|
11
|
+
}
|
|
12
|
+
function signalClassForEvent(name) {
|
|
13
|
+
const prefix = name.split(":")[0];
|
|
14
|
+
if (prefix === "value" || prefix === "bypass" || prefix === "adoption" || prefix === "friction") {
|
|
15
|
+
return prefix;
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`attribution event '${name}' has unknown signal-class prefix`);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Append an attribution ledger entry when valueFeedback emitEvents is allowed.
|
|
21
|
+
* Returns null when gated OFF (no disk write).
|
|
22
|
+
*/
|
|
23
|
+
export function emitAttributionSignal(name, payload, options) {
|
|
24
|
+
try {
|
|
25
|
+
const policy = options.policyOverride ?? resolveValueFeedback(options.projectRoot);
|
|
26
|
+
if (!isValueFeedbackPathAllowed("emitEvents", policy)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const signalClass = signalClassForEvent(name);
|
|
30
|
+
const logPath = resolveLedgerLogPath(options.projectRoot, options.logPath);
|
|
31
|
+
return emit(name, {
|
|
32
|
+
signal_class: signalClass,
|
|
33
|
+
...payload,
|
|
34
|
+
}, { logPath });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Telemetry is best-effort; any failure must not interrupt gate callers (#1709).
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Record a detection-bound gate catch (value class). */
|
|
42
|
+
export function recordGateCatch(projectRoot, source, detail, options = {}) {
|
|
43
|
+
return emitAttributionSignal(ATTRIBUTION_EVENT_NAMES.valueGateCatch, { source, detail }, { projectRoot, ...options });
|
|
44
|
+
}
|
|
45
|
+
/** Record a WIP-cap protect refusal (value class). */
|
|
46
|
+
export function recordWipCapProtect(projectRoot, count, cap, options = {}) {
|
|
47
|
+
return emitAttributionSignal(ATTRIBUTION_EVENT_NAMES.valueWipCapProtect, { source: "verify:wip-cap", count, cap }, { projectRoot, ...options });
|
|
48
|
+
}
|
|
49
|
+
/** Record a bypass/off-flow signal. */
|
|
50
|
+
export function recordBypassSignal(projectRoot, source, detail, options = {}) {
|
|
51
|
+
return emitAttributionSignal(ATTRIBUTION_EVENT_NAMES.bypassOffFlow, { source, detail }, { projectRoot, ...options });
|
|
52
|
+
}
|
|
53
|
+
/** Record an adoption/unused-capability signal. */
|
|
54
|
+
export function recordAdoptionSignal(projectRoot, capability, detail, options = {}) {
|
|
55
|
+
return emitAttributionSignal(ATTRIBUTION_EVENT_NAMES.adoptionUnusedCapability, { source: "adoption-registry", capability, detail }, { projectRoot, ...options });
|
|
56
|
+
}
|
|
57
|
+
/** Record a friction/directive-gap signal. */
|
|
58
|
+
export function recordFrictionSignal(projectRoot, source, detail, options = {}) {
|
|
59
|
+
return emitAttributionSignal(ATTRIBUTION_EVENT_NAMES.frictionDirectiveGap, { source, detail }, { projectRoot, ...options });
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=attribution-ledger.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export * as capacity from "./capacity/index.js";
|
|
|
15
15
|
export * as codebase from "./codebase/index.js";
|
|
16
16
|
export * as doctor from "./doctor/index.js";
|
|
17
17
|
export * from "./encoding/index.js";
|
|
18
|
+
export * as evalCrud from "./eval/crud-telemetry.js";
|
|
19
|
+
export * as evalHealth from "./eval/health.js";
|
|
20
|
+
export * as evalReport from "./eval/report.js";
|
|
21
|
+
export * as evalRun from "./eval/run.js";
|
|
22
|
+
export * as events from "./events/attribution-ledger.js";
|
|
18
23
|
export * from "./forward-coverage/evaluate.js";
|
|
19
24
|
export * as intake from "./intake/index.js";
|
|
20
25
|
export * as layout from "./layout/index.js";
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,11 @@ export * as capacity from "./capacity/index.js";
|
|
|
15
15
|
export * as codebase from "./codebase/index.js";
|
|
16
16
|
export * as doctor from "./doctor/index.js";
|
|
17
17
|
export * from "./encoding/index.js";
|
|
18
|
+
export * as evalCrud from "./eval/crud-telemetry.js";
|
|
19
|
+
export * as evalHealth from "./eval/health.js";
|
|
20
|
+
export * as evalReport from "./eval/report.js";
|
|
21
|
+
export * as evalRun from "./eval/run.js";
|
|
22
|
+
export * as events from "./events/attribution-ledger.js";
|
|
18
23
|
export * from "./forward-coverage/evaluate.js";
|
|
19
24
|
export * as intake from "./intake/index.js";
|
|
20
25
|
export * as layout from "./layout/index.js";
|
|
@@ -26,11 +26,21 @@ export const CANONICAL_GITIGNORE_BASELINE = [
|
|
|
26
26
|
".deft/ritual-state.json",
|
|
27
27
|
".deft/last-session.json",
|
|
28
28
|
".deft/routing.local.json",
|
|
29
|
-
"vbrief/.
|
|
30
|
-
"vbrief/.
|
|
31
|
-
"vbrief/.
|
|
32
|
-
"vbrief/.
|
|
33
|
-
"vbrief/.
|
|
29
|
+
"vbrief/.triage-cache/candidates.jsonl",
|
|
30
|
+
"vbrief/.triage-cache/summary-history.jsonl",
|
|
31
|
+
"vbrief/.triage-cache/scope-lifecycle.jsonl",
|
|
32
|
+
"vbrief/.triage-cache/decompositions/",
|
|
33
|
+
"vbrief/.triage-cache/doctor-state.json",
|
|
34
|
+
// Symmetric `xbrief/` layout entries (#2348). On the migrated `xbrief/` tree
|
|
35
|
+
// the engine writes operator-private triage-cache files to
|
|
36
|
+
// `xbrief/.triage-cache/`; without these the paths are trackable, violating
|
|
37
|
+
// the #1144 hybrid policy. Both layouts are emitted (harmless extra lines on
|
|
38
|
+
// the layout not in use) to match the both-layout `.eval/` treatment.
|
|
39
|
+
"xbrief/.triage-cache/candidates.jsonl",
|
|
40
|
+
"xbrief/.triage-cache/summary-history.jsonl",
|
|
41
|
+
"xbrief/.triage-cache/scope-lifecycle.jsonl",
|
|
42
|
+
"xbrief/.triage-cache/decompositions/",
|
|
43
|
+
"xbrief/.triage-cache/doctor-state.json",
|
|
34
44
|
"vbrief/*.lock",
|
|
35
45
|
".deft/core.bak-*/",
|
|
36
46
|
".deft/*.bak-*",
|
|
@@ -2,7 +2,10 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, unlinkSync, writeSync, } from "node:fs";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { pyRepr } from "../scm/py-format.js";
|
|
5
|
-
|
|
5
|
+
import { resolveCandidatesLogPath } from "../triage/cache-path.js";
|
|
6
|
+
function defaultLogPath() {
|
|
7
|
+
return resolveCandidatesLogPath(process.cwd());
|
|
8
|
+
}
|
|
6
9
|
const VALID_DECISIONS = new Set([
|
|
7
10
|
"accept",
|
|
8
11
|
"reject",
|
|
@@ -105,7 +108,7 @@ function validateEntry(entry) {
|
|
|
105
108
|
}
|
|
106
109
|
}
|
|
107
110
|
function resolvePath(path) {
|
|
108
|
-
return path !== undefined && path !== null ? resolve(path) :
|
|
111
|
+
return path !== undefined && path !== null ? resolve(path) : defaultLogPath();
|
|
109
112
|
}
|
|
110
113
|
function acquireAppendLock(logPath) {
|
|
111
114
|
while (threadLocked) {
|
|
@@ -44,6 +44,14 @@ export interface FetchIssueOptions {
|
|
|
44
44
|
readonly cacheRoot?: string | null;
|
|
45
45
|
readonly scmCall?: ScmCallFn;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Strip the `# #<number>: <title>` header that `renderContent` prepends when it
|
|
49
|
+
* materializes an issue's `content.md` at cache-put (#2314). The header is the
|
|
50
|
+
* only shape difference between the cache-read body and the live/raw-body path;
|
|
51
|
+
* removing it makes an ingested xBRIEF's `Overview` identical whether the source
|
|
52
|
+
* was a cache hit or a live fetch. A missing/older-shape header is left intact.
|
|
53
|
+
*/
|
|
54
|
+
export declare function stripRenderedIssueHeader(content: string, number: number): string;
|
|
47
55
|
export declare function fetchFromCache(repo: string, number: number, options?: FetchIssueOptions): Record<string, unknown> | null;
|
|
48
56
|
export declare function fetchIssueComments(repo: string, number: number, options?: FetchIssueOptions): IssueComment[];
|
|
49
57
|
export declare function attachIssueCommentThread(issue: Record<string, unknown>, comments: readonly IssueComment[]): Record<string, unknown>;
|
|
@@ -386,6 +386,20 @@ export function targetFilename(number, title, artifactSuffix = LEGACY_ARTIFACT_S
|
|
|
386
386
|
const slug = slugify(title) || `issue-${number}`;
|
|
387
387
|
return `${TODAY}-${number}-${slug}${artifactSuffix}`;
|
|
388
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Strip the `# #<number>: <title>` header that `renderContent` prepends when it
|
|
391
|
+
* materializes an issue's `content.md` at cache-put (#2314). The header is the
|
|
392
|
+
* only shape difference between the cache-read body and the live/raw-body path;
|
|
393
|
+
* removing it makes an ingested xBRIEF's `Overview` identical whether the source
|
|
394
|
+
* was a cache hit or a live fetch. A missing/older-shape header is left intact.
|
|
395
|
+
*/
|
|
396
|
+
export function stripRenderedIssueHeader(content, number) {
|
|
397
|
+
if (!Number.isFinite(number)) {
|
|
398
|
+
return content;
|
|
399
|
+
}
|
|
400
|
+
const header = new RegExp(`^# #${number}:[^\\n]*\\n\\n`);
|
|
401
|
+
return content.replace(header, "");
|
|
402
|
+
}
|
|
389
403
|
export function fetchFromCache(repo, number, options = {}) {
|
|
390
404
|
const key = `${repo}/${number}`;
|
|
391
405
|
try {
|
|
@@ -405,7 +419,11 @@ export function fetchFromCache(repo, number, options = {}) {
|
|
|
405
419
|
// buildIssueVbrief.
|
|
406
420
|
if (result.contentPath !== null) {
|
|
407
421
|
try {
|
|
408
|
-
|
|
422
|
+
// #2314: content.md is `renderContent`-prefixed with a `# #<n>: <title>`
|
|
423
|
+
// header at cache-put. Strip that header so the cache-read Overview
|
|
424
|
+
// matches the live/raw-body path (which has no header), keeping the
|
|
425
|
+
// durable xBRIEF identical for a cache hit vs a live fetch.
|
|
426
|
+
issue.body = stripRenderedIssueHeader(readFileSync(result.contentPath, "utf8"), Number(issue.number));
|
|
409
427
|
}
|
|
410
428
|
catch {
|
|
411
429
|
// fall back to the raw body (re-scanned downstream)
|
|
@@ -6,6 +6,7 @@ import { call } from "../scm/call.js";
|
|
|
6
6
|
import { updateDecomposedChildBackReferences } from "../scope/decomposed-refs.js";
|
|
7
7
|
import { resolveProjectRoot } from "../scope/project-context.js";
|
|
8
8
|
import { resolveProjectRepo } from "../slice/project-context.js";
|
|
9
|
+
import { LEGACY_INFO_ROOT_KEY, MIGRATED_INFO_ROOT_KEY } from "../xbrief-migrate/constants.js";
|
|
9
10
|
export const LIFECYCLE_FOLDERS = [
|
|
10
11
|
"proposed",
|
|
11
12
|
"pending",
|
|
@@ -633,8 +634,14 @@ export function applyLifecycleFixes(vbriefDir, report, projectRoot = null) {
|
|
|
633
634
|
const terminalStatus = destFolder === "cancelled" ? "cancelled" : "completed";
|
|
634
635
|
plan.status = terminalStatus;
|
|
635
636
|
const stamp = utcNowIso();
|
|
636
|
-
|
|
637
|
-
|
|
637
|
+
// Stamp `updated` into whichever info envelope the file already uses (#2346).
|
|
638
|
+
// Canonical v0.8 briefs use `xBRIEFInfo`; stamping `vBRIEFInfo` unconditionally
|
|
639
|
+
// appended a stray, version-less `vBRIEFInfo` block that then failed
|
|
640
|
+
// `vbrief:validate` ('vBRIEFInfo.version' must be one of ..., got 'undefined').
|
|
641
|
+
// Legacy briefs (or files without either envelope) keep the `vBRIEFInfo` key.
|
|
642
|
+
const infoKey = MIGRATED_INFO_ROOT_KEY in data ? MIGRATED_INFO_ROOT_KEY : LEGACY_INFO_ROOT_KEY;
|
|
643
|
+
const info = (data[infoKey] ?? {});
|
|
644
|
+
data[infoKey] = info;
|
|
638
645
|
info.updated = stamp;
|
|
639
646
|
plan.updated = stamp;
|
|
640
647
|
propagateItemStatus(plan.items, terminalStatus, stamp);
|
package/dist/layout/resolve.d.ts
CHANGED
|
@@ -51,9 +51,9 @@ export declare function resolveLifecycleRoot(projectRoot: string): string;
|
|
|
51
51
|
* (e.g. `<root>/<xbrief|vbrief>/active`). Layout-aware (#2109 part 2a).
|
|
52
52
|
*/
|
|
53
53
|
export declare function resolveLifecycleFolder(projectRoot: string, folder: string): string;
|
|
54
|
-
/** Absolute path to the
|
|
54
|
+
/** Absolute path to the layout-aware `.eval/` directory for version-eval results (#1703). */
|
|
55
55
|
export declare function resolveEvalDir(projectRoot: string): string;
|
|
56
|
-
/** Absolute path
|
|
56
|
+
/** Absolute path under `.eval/` for version-eval artefacts (not triage working-set). */
|
|
57
57
|
export declare function resolveEvalPath(projectRoot: string, ...segments: string[]): string;
|
|
58
58
|
/** Absolute path to the resolved lifecycle `.audit` directory (#2109 part 2a). */
|
|
59
59
|
export declare function resolveAuditDir(projectRoot: string): string;
|
package/dist/layout/resolve.js
CHANGED
|
@@ -101,11 +101,11 @@ export function resolveLifecycleRoot(projectRoot) {
|
|
|
101
101
|
export function resolveLifecycleFolder(projectRoot, folder) {
|
|
102
102
|
return join(resolveLifecycleRoot(projectRoot), folder);
|
|
103
103
|
}
|
|
104
|
-
/** Absolute path to the
|
|
104
|
+
/** Absolute path to the layout-aware `.eval/` directory for version-eval results (#1703). */
|
|
105
105
|
export function resolveEvalDir(projectRoot) {
|
|
106
106
|
return join(resolveLifecycleRoot(projectRoot), ".eval");
|
|
107
107
|
}
|
|
108
|
-
/** Absolute path
|
|
108
|
+
/** Absolute path under `.eval/` for version-eval artefacts (not triage working-set). */
|
|
109
109
|
export function resolveEvalPath(projectRoot, ...segments) {
|
|
110
110
|
return join(resolveEvalDir(projectRoot), ...segments);
|
|
111
111
|
}
|
package/dist/lifecycle/events.js
CHANGED
|
@@ -3,10 +3,12 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { contentRoot } from "../content-root.js";
|
|
6
|
+
import { ATTRIBUTION_REQUIRED_PAYLOAD } from "../events/attribution-constants.js";
|
|
6
7
|
/** Default event log location (project-local). */
|
|
7
8
|
export const DEFAULT_EVENT_LOG = join(".deft-cache", "events.jsonl");
|
|
8
9
|
const BEHAVIORAL_CATEGORY = "behavioral";
|
|
9
10
|
const REQUIRED_BEHAVIORAL_PAYLOAD = {
|
|
11
|
+
...ATTRIBUTION_REQUIRED_PAYLOAD,
|
|
10
12
|
"session:interrupted": ["session_id", "reason"],
|
|
11
13
|
"session:resumed": ["session_id", "interrupted_id"],
|
|
12
14
|
"plan:approved": ["plan_ref", "approver"],
|
|
@@ -379,8 +379,8 @@ export function cmdSubagentMonitor(argv, cwd = process.cwd()) {
|
|
|
379
379
|
process.stderr.write(`Error: ${args.error}\n`);
|
|
380
380
|
return EXIT_EXTERNAL_ERROR;
|
|
381
381
|
}
|
|
382
|
-
if (args.thresholdMinutes <= 0) {
|
|
383
|
-
process.stderr.write(`Error: --threshold-minutes must be positive, got ${args.thresholdMinutes}\n`);
|
|
382
|
+
if (Number.isNaN(args.thresholdMinutes) || args.thresholdMinutes <= 0) {
|
|
383
|
+
process.stderr.write(`Error: --threshold-minutes must be a positive number, got ${args.thresholdMinutes}\n`);
|
|
384
384
|
return EXIT_EXTERNAL_ERROR;
|
|
385
385
|
}
|
|
386
386
|
const scratchEntries = args.scratchDirs.length > 0
|
package/dist/policy/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./decisions.js";
|
|
|
5
5
|
export * from "./disclosure.js";
|
|
6
6
|
export * from "./plan-extensions.js";
|
|
7
7
|
export * from "./resolve.js";
|
|
8
|
+
export * from "./value-feedback.js";
|
|
8
9
|
export * from "./wip.js";
|
|
9
10
|
export declare const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
|
10
11
|
export declare const FIELD_WIP_CAP = "plan.policy.wipCap";
|
|
@@ -29,7 +30,7 @@ export interface PolicyField {
|
|
|
29
30
|
}
|
|
30
31
|
/** Walk registered inspectors and return one row per field (#1148). */
|
|
31
32
|
export declare function inspectAllPolicies(projectRoot: string): PolicyField[];
|
|
32
|
-
/** Look up a single registered field by canonical dotted-path name. */
|
|
33
|
+
/** Look up a single registered field by canonical dotted-path name (or CLI alias). */
|
|
33
34
|
export declare function inspectOnePolicy(name: string, projectRoot: string): PolicyField | null;
|
|
34
35
|
/** Return canonical names of every registered typed-policy field. */
|
|
35
36
|
export declare function registeredPolicyNames(): string[];
|
package/dist/policy/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readPlanPolicy } from "./plan-extensions.js";
|
|
2
2
|
import { coerceLegacyNarrative, LEGACY_NARRATIVE_KEY, loadProjectDefinition } from "./resolve.js";
|
|
3
|
+
import { FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, inspectValueFeedback, } from "./value-feedback.js";
|
|
3
4
|
import { DEFAULT_WIP_CAP } from "./wip.js";
|
|
4
5
|
export * from "./agents-md-advisory.js";
|
|
5
6
|
export * from "./autonomy.js";
|
|
@@ -8,6 +9,7 @@ export * from "./decisions.js";
|
|
|
8
9
|
export * from "./disclosure.js";
|
|
9
10
|
export * from "./plan-extensions.js";
|
|
10
11
|
export * from "./resolve.js";
|
|
12
|
+
export * from "./value-feedback.js";
|
|
11
13
|
export * from "./wip.js";
|
|
12
14
|
export const FIELD_ALLOW_DIRECT_COMMITS = "plan.policy.allowDirectCommitsToMaster";
|
|
13
15
|
export const FIELD_WIP_CAP = "plan.policy.wipCap";
|
|
@@ -213,6 +215,15 @@ function inspectSwarmSubagentBackend(data) {
|
|
|
213
215
|
source: "default-on-error",
|
|
214
216
|
};
|
|
215
217
|
}
|
|
218
|
+
function inspectValueFeedbackField(data) {
|
|
219
|
+
const field = inspectValueFeedback(data);
|
|
220
|
+
return {
|
|
221
|
+
name: field.name,
|
|
222
|
+
current: field.current,
|
|
223
|
+
default: field.default,
|
|
224
|
+
source: field.source,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
216
227
|
const REGISTERED_POLICIES = [
|
|
217
228
|
inspectAllowDirectCommits,
|
|
218
229
|
inspectWipCap,
|
|
@@ -225,16 +236,18 @@ const REGISTERED_POLICIES = [
|
|
|
225
236
|
emptyIsTyped: true,
|
|
226
237
|
}),
|
|
227
238
|
inspectSwarmSubagentBackend,
|
|
239
|
+
inspectValueFeedbackField,
|
|
228
240
|
];
|
|
229
241
|
/** Walk registered inspectors and return one row per field (#1148). */
|
|
230
242
|
export function inspectAllPolicies(projectRoot) {
|
|
231
243
|
const [data] = loadProjectDefinition(projectRoot);
|
|
232
244
|
return REGISTERED_POLICIES.map((inspect) => inspect(data));
|
|
233
245
|
}
|
|
234
|
-
/** Look up a single registered field by canonical dotted-path name. */
|
|
246
|
+
/** Look up a single registered field by canonical dotted-path name (or CLI alias). */
|
|
235
247
|
export function inspectOnePolicy(name, projectRoot) {
|
|
248
|
+
const normalized = name === FIELD_VALUE_FEEDBACK_CLI_ALIAS ? FIELD_VALUE_FEEDBACK : name;
|
|
236
249
|
for (const field of inspectAllPolicies(projectRoot)) {
|
|
237
|
-
if (field.name ===
|
|
250
|
+
if (field.name === normalized)
|
|
238
251
|
return field;
|
|
239
252
|
}
|
|
240
253
|
return null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Canonical registered policy field name (matches other FIELD_* dotted paths). */
|
|
2
|
+
export declare const FIELD_VALUE_FEEDBACK = "plan.policy.valueFeedback";
|
|
3
|
+
/** Short alias accepted by `policy:show --field=valueFeedback` (#1709). */
|
|
4
|
+
export declare const FIELD_VALUE_FEEDBACK_CLI_ALIAS = "valueFeedback";
|
|
5
|
+
export declare const DEFAULT_VALUE_FEEDBACK_ENABLED = false;
|
|
6
|
+
/** Sub-flag defaults applied when the master flag is enabled (#1709 tiered-cost decision). */
|
|
7
|
+
export declare const VALUE_FEEDBACK_SUBFLAG_DEFAULTS_WHEN_ENABLED: {
|
|
8
|
+
readonly emitEvents: true;
|
|
9
|
+
readonly sessionLine: true;
|
|
10
|
+
readonly upstreamPrompt: false;
|
|
11
|
+
};
|
|
12
|
+
export type ValueFeedbackSubFlag = keyof typeof VALUE_FEEDBACK_SUBFLAG_DEFAULTS_WHEN_ENABLED;
|
|
13
|
+
export interface ValueFeedbackConfig {
|
|
14
|
+
readonly enabled: boolean;
|
|
15
|
+
readonly emitEvents: boolean;
|
|
16
|
+
readonly sessionLine: boolean;
|
|
17
|
+
readonly upstreamPrompt: boolean;
|
|
18
|
+
}
|
|
19
|
+
export type ValueFeedbackSource = "typed" | "default" | "default-on-error";
|
|
20
|
+
export interface ValueFeedbackResolved extends ValueFeedbackConfig {
|
|
21
|
+
readonly source: ValueFeedbackSource;
|
|
22
|
+
readonly error: string | null;
|
|
23
|
+
}
|
|
24
|
+
export declare const VALUE_FEEDBACK_CAPABILITY_COST_DISCLOSURE: string;
|
|
25
|
+
/** Validate a `plan.policy.valueFeedback` payload. */
|
|
26
|
+
export declare function validateValueFeedback(value: unknown): string[];
|
|
27
|
+
/** Resolve `plan.policy.valueFeedback` from PROJECT-DEFINITION (#1709). */
|
|
28
|
+
export declare function resolveValueFeedback(projectRoot: string): ValueFeedbackResolved;
|
|
29
|
+
/** Master gate: when `enabled` is false, every downstream path is rejected. */
|
|
30
|
+
export declare function isValueFeedbackPathAllowed(path: ValueFeedbackSubFlag, policy: ValueFeedbackResolved): boolean;
|
|
31
|
+
/** Resolved per-path gate booleans for policy:show and enable status output. */
|
|
32
|
+
export declare function valueFeedbackPathGates(policy: ValueFeedbackResolved): Record<ValueFeedbackSubFlag, boolean>;
|
|
33
|
+
/** Human-readable status line for CLI enable/show surfaces. */
|
|
34
|
+
export declare function formatValueFeedbackStatusLine(policy: ValueFeedbackResolved): string;
|
|
35
|
+
export interface ValueFeedbackPolicyField {
|
|
36
|
+
readonly name: typeof FIELD_VALUE_FEEDBACK;
|
|
37
|
+
readonly current: ValueFeedbackConfig;
|
|
38
|
+
readonly default: ValueFeedbackConfig;
|
|
39
|
+
readonly source: string;
|
|
40
|
+
}
|
|
41
|
+
/** Inspector row for `policy:show --field=valueFeedback`. */
|
|
42
|
+
export declare function inspectValueFeedback(data: Record<string, unknown> | null): ValueFeedbackPolicyField;
|
|
43
|
+
export interface EnableValueFeedbackOptions {
|
|
44
|
+
readonly confirm: boolean;
|
|
45
|
+
readonly actor?: string;
|
|
46
|
+
readonly note?: string;
|
|
47
|
+
readonly subFlags?: Partial<Record<ValueFeedbackSubFlag, boolean>>;
|
|
48
|
+
}
|
|
49
|
+
export interface EnableValueFeedbackResult {
|
|
50
|
+
readonly exitCode: 0 | 1 | 2;
|
|
51
|
+
readonly stdout: string;
|
|
52
|
+
readonly changed: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Persist `valueFeedback.enabled=true` after capability-cost disclosure (#1709). */
|
|
55
|
+
export declare function enableValueFeedback(projectRoot: string, options: EnableValueFeedbackOptions): EnableValueFeedbackResult;
|
|
56
|
+
//# sourceMappingURL=value-feedback.d.ts.map
|