@deftai/directive-core 0.99.0 → 0.101.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/authz/actions.d.ts +6 -0
- package/dist/authz/actions.js +3 -0
- package/dist/authz/classify.js +241 -30
- package/dist/authz/decompose-apply.d.ts +81 -0
- package/dist/authz/decompose-apply.js +377 -0
- package/dist/authz/index.d.ts +3 -1
- package/dist/authz/index.js +3 -1
- package/dist/authz/store.d.ts +53 -0
- package/dist/authz/store.js +219 -1
- package/dist/authz/types.d.ts +19 -2
- package/dist/authz/types.js +5 -1
- package/dist/check/cached-orchestrator.d.ts +26 -5
- package/dist/check/cached-orchestrator.js +228 -6
- package/dist/check/gate-lists.d.ts +10 -4
- package/dist/check/gate-lists.js +19 -5
- package/dist/check/index.d.ts +3 -2
- package/dist/check/index.js +2 -1
- package/dist/check/named-cause.d.ts +45 -0
- package/dist/check/named-cause.js +121 -0
- package/dist/check/orchestrator.js +6 -1
- package/dist/doctor/checks.d.ts +44 -0
- package/dist/doctor/checks.js +428 -2
- package/dist/doctor/help.d.ts +5 -0
- package/dist/doctor/help.js +31 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/main.d.ts +6 -7
- package/dist/doctor/main.js +130 -79
- package/dist/doctor/session-coda.d.ts +82 -0
- package/dist/doctor/session-coda.js +151 -0
- package/dist/doctor/types.d.ts +16 -0
- package/dist/doctor/which.d.ts +20 -1
- package/dist/doctor/which.js +67 -1
- package/dist/finish-loop/pr-finish-loop.d.ts +13 -2
- package/dist/finish-loop/pr-finish-loop.js +116 -5
- package/dist/finish-loop/types.d.ts +1 -1
- package/dist/hooks/dispatcher.d.ts +9 -5
- package/dist/hooks/dispatcher.js +23 -15
- package/dist/hooks/readonly.d.ts +6 -3
- package/dist/hooks/readonly.js +44 -25
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/init-deposit/agent-hooks.d.ts +20 -0
- package/dist/init-deposit/agent-hooks.js +51 -31
- package/dist/init-deposit/gitignore.js +2 -0
- package/dist/intake/issue-ingest.js +36 -0
- package/dist/lifecycle/completed-consistency.d.ts +60 -0
- package/dist/lifecycle/completed-consistency.js +443 -0
- package/dist/lifecycle/completed-tracked-on-delivery.d.ts +47 -0
- package/dist/lifecycle/completed-tracked-on-delivery.js +415 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/literal-acceptance/capture.d.ts +52 -0
- package/dist/literal-acceptance/capture.js +658 -0
- package/dist/literal-acceptance/evaluate.d.ts +47 -0
- package/dist/literal-acceptance/evaluate.js +193 -0
- package/dist/literal-acceptance/index.d.ts +12 -0
- package/dist/literal-acceptance/index.js +12 -0
- package/dist/literal-acceptance/run.d.ts +38 -0
- package/dist/literal-acceptance/run.js +216 -0
- package/dist/literal-acceptance/safety.d.ts +24 -0
- package/dist/literal-acceptance/safety.js +251 -0
- package/dist/literal-acceptance/types.d.ts +82 -0
- package/dist/literal-acceptance/types.js +26 -0
- package/dist/policy/ac-pass-banking.d.ts +58 -0
- package/dist/policy/ac-pass-banking.js +150 -0
- package/dist/policy/ceremony-dial.d.ts +96 -11
- package/dist/policy/ceremony-dial.js +250 -23
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.js +16 -1
- package/dist/policy/merge-approval-head.d.ts +129 -0
- package/dist/policy/merge-approval-head.js +461 -0
- package/dist/policy/require-human-merge.d.ts +5 -0
- package/dist/policy/require-human-merge.js +5 -0
- package/dist/pr-merge-readiness/ci-gate.d.ts +20 -3
- package/dist/pr-merge-readiness/ci-gate.js +65 -5
- package/dist/pr-merge-readiness/compute.d.ts +13 -0
- package/dist/pr-merge-readiness/compute.js +99 -14
- package/dist/pr-merge-readiness/gh.d.ts +49 -0
- package/dist/pr-merge-readiness/gh.js +268 -0
- package/dist/pr-merge-readiness/index.d.ts +2 -2
- package/dist/pr-merge-readiness/index.js +2 -2
- package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +4 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +11 -0
- package/dist/pr-wait-mergeable/cascade.js +115 -1
- package/dist/pr-wait-mergeable/main.d.ts +4 -0
- package/dist/pr-wait-mergeable/main.js +4 -0
- package/dist/pr-wait-mergeable/types.d.ts +3 -1
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -1
- package/dist/pr-wait-mergeable/wrappers.js +7 -1
- package/dist/preflight/evaluate.d.ts +15 -1
- package/dist/preflight/evaluate.js +33 -2
- package/dist/preflight-cache/evaluate.d.ts +3 -0
- package/dist/preflight-cache/evaluate.js +3 -0
- package/dist/product-first-done-gate/acceptance.d.ts +25 -0
- package/dist/product-first-done-gate/acceptance.js +247 -0
- package/dist/product-first-done-gate/check-mode.d.ts +45 -0
- package/dist/product-first-done-gate/check-mode.js +148 -0
- package/dist/product-first-done-gate/evaluate.d.ts +50 -0
- package/dist/product-first-done-gate/evaluate.js +255 -0
- package/dist/product-first-done-gate/index.d.ts +11 -0
- package/dist/product-first-done-gate/index.js +11 -0
- package/dist/product-first-done-gate/types.d.ts +64 -0
- package/dist/product-first-done-gate/types.js +61 -0
- package/dist/render/framework-commands.js +4 -0
- package/dist/run-summary/emit.d.ts +56 -0
- package/dist/run-summary/emit.js +171 -0
- package/dist/run-summary/index.d.ts +4 -0
- package/dist/run-summary/index.js +4 -0
- package/dist/run-summary/path.d.ts +25 -0
- package/dist/run-summary/path.js +78 -0
- package/dist/run-summary/types.d.ts +76 -0
- package/dist/run-summary/types.js +21 -0
- package/dist/scope/acceptance-evidence.d.ts +110 -0
- package/dist/scope/acceptance-evidence.js +422 -0
- package/dist/scope/coverage-map.d.ts +98 -0
- package/dist/scope/coverage-map.js +558 -0
- package/dist/scope/decompose.d.ts +5 -0
- package/dist/scope/decompose.js +134 -11
- package/dist/scope/index.d.ts +3 -0
- package/dist/scope/index.js +3 -0
- package/dist/scope/parent-lineage.d.ts +125 -0
- package/dist/scope/parent-lineage.js +626 -0
- package/dist/scope/transition.d.ts +8 -0
- package/dist/scope/transition.js +61 -2
- package/dist/session/ac-pass-banking.d.ts +221 -0
- package/dist/session/ac-pass-banking.js +761 -0
- package/dist/session/active-cli.d.ts +79 -0
- package/dist/session/active-cli.js +382 -0
- package/dist/session/deposit-sha.d.ts +49 -0
- package/dist/session/deposit-sha.js +121 -0
- package/dist/session/effort-budget.d.ts +136 -0
- package/dist/session/effort-budget.js +352 -0
- package/dist/session/index.d.ts +7 -0
- package/dist/session/index.js +7 -0
- package/dist/session/orientation-compression.d.ts +127 -0
- package/dist/session/orientation-compression.js +425 -0
- package/dist/session/orientation-state.d.ts +29 -0
- package/dist/session/orientation-state.js +85 -0
- package/dist/session/session-start.d.ts +31 -0
- package/dist/session/session-start.js +228 -2
- package/dist/session/toolchain-preflight.d.ts +64 -0
- package/dist/session/toolchain-preflight.js +151 -0
- package/dist/session/verify-session-ritual.d.ts +14 -0
- package/dist/session/verify-session-ritual.js +33 -0
- package/dist/story-ready/evaluate.d.ts +11 -0
- package/dist/story-ready/evaluate.js +41 -3
- package/dist/triage/actions/candidates-log.d.ts +1 -2
- package/dist/triage/actions/candidates-log.js +37 -6
- package/dist/triage/bootstrap/gitignore.d.ts +1 -1
- package/dist/triage/bootstrap/gitignore.js +8 -2
- package/dist/triage/bootstrap/index.js +15 -3
- package/dist/triage/classify/index.d.ts +1 -0
- package/dist/triage/classify/index.js +2 -0
- package/dist/triage/classify/label-mirror.js +16 -0
- package/dist/triage/classify/mirror-discovery-tip.d.ts +95 -0
- package/dist/triage/classify/mirror-discovery-tip.js +234 -0
- package/dist/triage/reconcile/reconcile.js +28 -6
- package/dist/triage/summary/index.js +12 -4
- package/dist/triage/welcome/default-mode.js +16 -0
- package/dist/ts-check-lane/run-lane.js +21 -4
- package/dist/vbrief-validate/conformance.js +7 -0
- package/dist/vitest-runner/coverage-debt-teardown.js +16 -4
- package/dist/xbrief-migrate/migrate-project.d.ts +4 -0
- package/dist/xbrief-migrate/migrate-project.js +92 -3
- package/package.json +15 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ceremony dial (#3214): ritual depth = f(task size × model tier × project shape).
|
|
2
|
+
* Ceremony dial (#3214 / #3263): ritual depth = f(task size × model tier × project shape).
|
|
3
3
|
*
|
|
4
4
|
* Selection policy over existing pieces — not a new subsystem.
|
|
5
5
|
* Composes:
|
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
* - #3014 minimal consumer AGENTS profile (research pointer; not yet a shipped deposit)
|
|
8
8
|
* - effort estimate (#1581), model routing (#1976/#818), host capability (#1461)
|
|
9
9
|
*
|
|
10
|
-
* Two-stage dial (#3214 design note / #1581 ordering):
|
|
11
|
-
* cold-start / incomplete
|
|
12
|
-
*
|
|
10
|
+
* Two-stage dial (#3214 design note / #1581 ordering) with tier-conditional cold-start (#3263):
|
|
11
|
+
* cold-start / incomplete size → **tier-conditional**:
|
|
12
|
+
* frontier (or unknown tier) → rapid; mid/low → standard (not rapid)
|
|
13
|
+
* escalate when evidence arrives (provisional M/L size, full matrix)
|
|
13
14
|
* Full matrix: S × frontier → rapid; non-project → minimal; else scales up.
|
|
14
15
|
* Override always available via plan.policy.ceremonyDial.override; audited on write.
|
|
16
|
+
*
|
|
17
|
+
* Audit path (#3263): session:start records depth + provisional reasons on
|
|
18
|
+
* `.deft/ritual-state.json` under `ceremony_dial` — use `readCeremonyDialAudit`.
|
|
15
19
|
*/
|
|
16
20
|
/** Canonical dotted policy field name. */
|
|
17
21
|
export declare const FIELD_CEREMONY_DIAL = "plan.policy.ceremonyDial";
|
|
@@ -60,6 +64,11 @@ export interface CeremonyDialProfile {
|
|
|
60
64
|
readonly skipFatPath: boolean;
|
|
61
65
|
/** How much lifecycle / history write budget this depth intends. */
|
|
62
66
|
readonly lifecycleWrites: "minimal" | "light" | "full";
|
|
67
|
+
/**
|
|
68
|
+
* Literal acceptance-command verification is always required (#3267 / #3156).
|
|
69
|
+
* Ceremony dial never skips capture+verbatim run — including rapid/minimal.
|
|
70
|
+
*/
|
|
71
|
+
readonly literalAcceptanceRequired: true;
|
|
63
72
|
readonly label: string;
|
|
64
73
|
}
|
|
65
74
|
export type CeremonyDialSource = "override" | "matrix" | "default" | "disabled" | "typed" | "default-on-error";
|
|
@@ -97,25 +106,38 @@ export declare function normalizeCeremonyTaskSize(raw: unknown): CeremonyTaskSiz
|
|
|
97
106
|
export declare function normalizeCeremonyModelTier(raw: unknown): CeremonyModelTier | null;
|
|
98
107
|
export declare function normalizeCeremonyProjectShape(raw: unknown): CeremonyProjectShape | null;
|
|
99
108
|
/**
|
|
100
|
-
*
|
|
109
|
+
* Tier-conditional cold-start depth when task size is incomplete (#3263).
|
|
101
110
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
111
|
+
* Mid/low models benefit from structure on hard tasks and should not cold-start
|
|
112
|
+
* at rapid (start-light / escalate-too-late signature). Frontier recovers from a
|
|
113
|
+
* light start. Unknown tier stays rapid (optimistic cold default; pass
|
|
114
|
+
* `--model-tier` / `DEFT_CEREMONY_MODEL_TIER` to unlock the mid/low floor).
|
|
115
|
+
*
|
|
116
|
+
* Escalate-on-evidence still applies when size later arrives (full matrix).
|
|
117
|
+
*/
|
|
118
|
+
export declare function selectCeremonyColdStartDepth(modelTier: CeremonyModelTier | null | undefined): CeremonyDepth;
|
|
119
|
+
/**
|
|
120
|
+
* Two-stage / partial-evidence selection when size or tier is missing
|
|
121
|
+
* (#3214 design note / #3263 tier-conditional cold-start).
|
|
122
|
+
*
|
|
123
|
+
* Cold incomplete size is tier-conditional (#3263): mid/low → standard, frontier
|
|
124
|
+
* or unknown → rapid. When size is known without tier, escalate on substantial
|
|
125
|
+
* size (apps-bank safety). Does not invent plan-item effort (#1581 post-planning only).
|
|
105
126
|
*/
|
|
106
127
|
export declare function selectCeremonyDepthFromPartialEvidence(inputs: {
|
|
107
128
|
readonly taskSize: CeremonyTaskSize | null;
|
|
108
129
|
readonly modelTier: CeremonyModelTier | null;
|
|
109
130
|
}): CeremonyDepth;
|
|
110
131
|
/**
|
|
111
|
-
* Pure default matrix (#3214 acceptance +
|
|
132
|
+
* Pure default matrix (#3214 acceptance + #3263 tier-conditional cold-start):
|
|
112
133
|
* - non-project → minimal (#3014 direction)
|
|
113
134
|
* - S × frontier → rapid (strategies/rapid.md)
|
|
114
135
|
* - S × mid → standard (mid-tier gains from structure)
|
|
115
136
|
* - S × low → elevated
|
|
116
137
|
* - M × low → elevated; M otherwise → standard
|
|
117
138
|
* - L/XL → elevated (except L × frontier stays standard)
|
|
118
|
-
* - Incomplete size
|
|
139
|
+
* - Incomplete size → tier-conditional cold-start (#3263): mid/low → standard; frontier/unknown → rapid
|
|
140
|
+
* - Size known, tier missing → escalate on M/L (partial evidence)
|
|
119
141
|
*/
|
|
120
142
|
export declare function selectCeremonyDepthFromMatrix(inputs: CeremonyDialInputs): CeremonyDepth;
|
|
121
143
|
export interface SelectCeremonyDepthOptions {
|
|
@@ -126,7 +148,7 @@ export interface SelectCeremonyDepthOptions {
|
|
|
126
148
|
* Deterministic depth selection (pure; no IO).
|
|
127
149
|
*
|
|
128
150
|
* Precedence: disabled → standard; override → forced depth; else matrix on inputs;
|
|
129
|
-
* empty inputs → **rapid** (
|
|
151
|
+
* empty inputs → **rapid** (unknown-tier cold default; #3263 mid/low need modelTier set).
|
|
130
152
|
*/
|
|
131
153
|
export declare function selectCeremonyDepth(options?: SelectCeremonyDepthOptions): CeremonyDialSelection;
|
|
132
154
|
export interface ResolveCeremonyDialOptions {
|
|
@@ -230,4 +252,67 @@ export declare function resolveSessionCeremonyDialInputs(projectRoot: string, ex
|
|
|
230
252
|
readonly inputs: CeremonyDialInputs;
|
|
231
253
|
readonly provisional: ProvisionalCeremonyEstimate;
|
|
232
254
|
};
|
|
255
|
+
export interface CeremonyDialAuditProvisional {
|
|
256
|
+
readonly taskSize: CeremonyTaskSize | null;
|
|
257
|
+
readonly modelTier: CeremonyModelTier | null;
|
|
258
|
+
readonly projectShape: CeremonyProjectShape | null;
|
|
259
|
+
readonly reasons: readonly string[];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Snapshot of dial selection recorded on `.deft/ritual-state.json` at session:start.
|
|
263
|
+
* Operators audit failed-task depth / provisional reasons without re-running ritual.
|
|
264
|
+
*/
|
|
265
|
+
export interface CeremonyDialAuditSnapshot {
|
|
266
|
+
readonly path: string;
|
|
267
|
+
readonly depth: CeremonyDepth | null;
|
|
268
|
+
readonly source: string | null;
|
|
269
|
+
readonly inputs: {
|
|
270
|
+
readonly taskSize: CeremonyTaskSize | null;
|
|
271
|
+
readonly modelTier: CeremonyModelTier | null;
|
|
272
|
+
readonly projectShape: CeremonyProjectShape | null;
|
|
273
|
+
} | null;
|
|
274
|
+
readonly provisional: CeremonyDialAuditProvisional | null;
|
|
275
|
+
readonly raw: Record<string, unknown> | null;
|
|
276
|
+
readonly error: string | null;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Read ceremony dial depth + provisional reasons from ritual-state (#3263 audit path).
|
|
280
|
+
* session:start already writes `ceremony_dial` (incl. provisional) — this is the
|
|
281
|
+
* operator/read path so failed runs can confirm start-light vs escalate timing.
|
|
282
|
+
*
|
|
283
|
+
* Returns `error` when ritual-state is missing/unreadable or lacks `ceremony_dial`;
|
|
284
|
+
* does not throw.
|
|
285
|
+
*/
|
|
286
|
+
export declare function readCeremonyDialAudit(projectRoot: string): CeremonyDialAuditSnapshot;
|
|
287
|
+
/** One-line operator summary for audit tooling / failed-task forensics (#3263). */
|
|
288
|
+
export declare function formatCeremonyDialAuditLine(audit: CeremonyDialAuditSnapshot): string;
|
|
289
|
+
/**
|
|
290
|
+
* Reified dial transition for run-summary telemetry (#3282).
|
|
291
|
+
*
|
|
292
|
+
* IMPLEMENTATION PREREQUISITE from the issue: dial transitions must be
|
|
293
|
+
* engine-managed events, not prose-only policy. This function is the CLI-facing
|
|
294
|
+
* transition hook (`policy:set-ceremony-dial` / dial escalate): it persists the
|
|
295
|
+
* override (when confirm) and always emits a `dial_transition` run-summary line
|
|
296
|
+
* when a depth change is applied.
|
|
297
|
+
*/
|
|
298
|
+
export interface EscalateCeremonyDialOptions {
|
|
299
|
+
readonly to: CeremonyDepth;
|
|
300
|
+
readonly reason: string;
|
|
301
|
+
readonly evidence?: string;
|
|
302
|
+
readonly sessionId?: string;
|
|
303
|
+
readonly confirm?: boolean;
|
|
304
|
+
readonly actor?: string;
|
|
305
|
+
readonly note?: string;
|
|
306
|
+
/** When false, skip run-summary emission (tests). Default true. */
|
|
307
|
+
readonly emitRunSummary?: boolean;
|
|
308
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
309
|
+
}
|
|
310
|
+
export interface EscalateCeremonyDialResult {
|
|
311
|
+
readonly exitCode: number;
|
|
312
|
+
readonly from: CeremonyDepth | null;
|
|
313
|
+
readonly to: CeremonyDepth;
|
|
314
|
+
readonly changed: boolean;
|
|
315
|
+
readonly lines: readonly string[];
|
|
316
|
+
}
|
|
317
|
+
export declare function escalateCeremonyDial(projectRoot: string, options: EscalateCeremonyDialOptions): EscalateCeremonyDialResult;
|
|
233
318
|
//# sourceMappingURL=ceremony-dial.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ceremony dial (#3214): ritual depth = f(task size × model tier × project shape).
|
|
2
|
+
* Ceremony dial (#3214 / #3263): ritual depth = f(task size × model tier × project shape).
|
|
3
3
|
*
|
|
4
4
|
* Selection policy over existing pieces — not a new subsystem.
|
|
5
5
|
* Composes:
|
|
@@ -7,14 +7,19 @@
|
|
|
7
7
|
* - #3014 minimal consumer AGENTS profile (research pointer; not yet a shipped deposit)
|
|
8
8
|
* - effort estimate (#1581), model routing (#1976/#818), host capability (#1461)
|
|
9
9
|
*
|
|
10
|
-
* Two-stage dial (#3214 design note / #1581 ordering):
|
|
11
|
-
* cold-start / incomplete
|
|
12
|
-
*
|
|
10
|
+
* Two-stage dial (#3214 design note / #1581 ordering) with tier-conditional cold-start (#3263):
|
|
11
|
+
* cold-start / incomplete size → **tier-conditional**:
|
|
12
|
+
* frontier (or unknown tier) → rapid; mid/low → standard (not rapid)
|
|
13
|
+
* escalate when evidence arrives (provisional M/L size, full matrix)
|
|
13
14
|
* Full matrix: S × frontier → rapid; non-project → minimal; else scales up.
|
|
14
15
|
* Override always available via plan.policy.ceremonyDial.override; audited on write.
|
|
16
|
+
*
|
|
17
|
+
* Audit path (#3263): session:start records depth + provisional reasons on
|
|
18
|
+
* `.deft/ritual-state.json` under `ceremony_dial` — use `readCeremonyDialAudit`.
|
|
15
19
|
*/
|
|
16
20
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
17
21
|
import { join } from "node:path";
|
|
22
|
+
import { RunSummaryEmitter } from "../run-summary/emit.js";
|
|
18
23
|
import { atomicWriteProjectDefinition, projectDefinitionMutationLock, } from "../vbrief-build/project-definition-io.js";
|
|
19
24
|
import { migrateLegacyPolicyKey, PLAN_POLICY_KEY, readPlanPolicy } from "./plan-extensions.js";
|
|
20
25
|
import { policyColonInvocation } from "./policy-invocation.js";
|
|
@@ -45,6 +50,9 @@ export const CEREMONY_MINIMAL_AGENTS_PROFILE_POINTER = "docs/analysis/2026-07-31
|
|
|
45
50
|
* (`verify:session-ritual --tier=gated`). Gated verify treats
|
|
46
51
|
* `deferred_reason` as satisfied, so dial-driven deferral would skip gates.
|
|
47
52
|
* ! `verify_tools` also remains required on every dial depth (not skipFatPath).
|
|
53
|
+
* ! Literal acceptance-command verification (#3267) is required at every depth
|
|
54
|
+
* (`literalAcceptanceRequired: true`), including rapid/minimal — capture exact
|
|
55
|
+
* stated commands at intake and run them verbatim before done. Extends #973.
|
|
48
56
|
* ~ Rapid/minimal MAY lighten informational cold path only: triage welcome,
|
|
49
57
|
* optional network/release probe, staleness tickler.
|
|
50
58
|
*/
|
|
@@ -55,6 +63,7 @@ const PROFILES = {
|
|
|
55
63
|
autoDeferSteps: ["triage_welcome"],
|
|
56
64
|
skipFatPath: true,
|
|
57
65
|
lifecycleWrites: "minimal",
|
|
66
|
+
literalAcceptanceRequired: true,
|
|
58
67
|
label: "minimal (non-project / #3014 direction)",
|
|
59
68
|
},
|
|
60
69
|
rapid: {
|
|
@@ -62,6 +71,7 @@ const PROFILES = {
|
|
|
62
71
|
autoDeferSteps: ["triage_welcome"],
|
|
63
72
|
skipFatPath: true,
|
|
64
73
|
lifecycleWrites: "light",
|
|
74
|
+
literalAcceptanceRequired: true,
|
|
65
75
|
label: "rapid (strategies/rapid.md light path)",
|
|
66
76
|
},
|
|
67
77
|
standard: {
|
|
@@ -69,6 +79,7 @@ const PROFILES = {
|
|
|
69
79
|
autoDeferSteps: [],
|
|
70
80
|
skipFatPath: false,
|
|
71
81
|
lifecycleWrites: "full",
|
|
82
|
+
literalAcceptanceRequired: true,
|
|
72
83
|
label: "standard (full session ritual)",
|
|
73
84
|
},
|
|
74
85
|
elevated: {
|
|
@@ -76,6 +87,7 @@ const PROFILES = {
|
|
|
76
87
|
autoDeferSteps: [],
|
|
77
88
|
skipFatPath: false,
|
|
78
89
|
lifecycleWrites: "full",
|
|
90
|
+
literalAcceptanceRequired: true,
|
|
79
91
|
label: "elevated (full ritual; prefer more gates for weaker tiers / large tasks)",
|
|
80
92
|
},
|
|
81
93
|
};
|
|
@@ -186,11 +198,29 @@ export function normalizeCeremonyProjectShape(raw) {
|
|
|
186
198
|
return null;
|
|
187
199
|
}
|
|
188
200
|
/**
|
|
189
|
-
*
|
|
201
|
+
* Tier-conditional cold-start depth when task size is incomplete (#3263).
|
|
202
|
+
*
|
|
203
|
+
* Mid/low models benefit from structure on hard tasks and should not cold-start
|
|
204
|
+
* at rapid (start-light / escalate-too-late signature). Frontier recovers from a
|
|
205
|
+
* light start. Unknown tier stays rapid (optimistic cold default; pass
|
|
206
|
+
* `--model-tier` / `DEFT_CEREMONY_MODEL_TIER` to unlock the mid/low floor).
|
|
207
|
+
*
|
|
208
|
+
* Escalate-on-evidence still applies when size later arrives (full matrix).
|
|
209
|
+
*/
|
|
210
|
+
export function selectCeremonyColdStartDepth(modelTier) {
|
|
211
|
+
if (modelTier === "mid" || modelTier === "low") {
|
|
212
|
+
return "standard";
|
|
213
|
+
}
|
|
214
|
+
// frontier or unknown → rapid
|
|
215
|
+
return "rapid";
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Two-stage / partial-evidence selection when size or tier is missing
|
|
219
|
+
* (#3214 design note / #3263 tier-conditional cold-start).
|
|
190
220
|
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* Does not invent plan-item effort (#1581 post-planning only).
|
|
221
|
+
* Cold incomplete size is tier-conditional (#3263): mid/low → standard, frontier
|
|
222
|
+
* or unknown → rapid. When size is known without tier, escalate on substantial
|
|
223
|
+
* size (apps-bank safety). Does not invent plan-item effort (#1581 post-planning only).
|
|
194
224
|
*/
|
|
195
225
|
export function selectCeremonyDepthFromPartialEvidence(inputs) {
|
|
196
226
|
const size = inputs.taskSize;
|
|
@@ -203,26 +233,20 @@ export function selectCeremonyDepthFromPartialEvidence(inputs) {
|
|
|
203
233
|
return "standard";
|
|
204
234
|
return "elevated"; // L / XL
|
|
205
235
|
}
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return "rapid";
|
|
210
|
-
if (tier === "mid")
|
|
211
|
-
return "standard";
|
|
212
|
-
return "elevated"; // low
|
|
213
|
-
}
|
|
214
|
-
// Both unknown: two-stage cold default.
|
|
215
|
-
return "rapid";
|
|
236
|
+
// Size incomplete (null), any tier including unknown: tier-conditional cold-start (#3263).
|
|
237
|
+
// Callers with both size and tier set use the full matrix instead.
|
|
238
|
+
return selectCeremonyColdStartDepth(tier);
|
|
216
239
|
}
|
|
217
240
|
/**
|
|
218
|
-
* Pure default matrix (#3214 acceptance +
|
|
241
|
+
* Pure default matrix (#3214 acceptance + #3263 tier-conditional cold-start):
|
|
219
242
|
* - non-project → minimal (#3014 direction)
|
|
220
243
|
* - S × frontier → rapid (strategies/rapid.md)
|
|
221
244
|
* - S × mid → standard (mid-tier gains from structure)
|
|
222
245
|
* - S × low → elevated
|
|
223
246
|
* - M × low → elevated; M otherwise → standard
|
|
224
247
|
* - L/XL → elevated (except L × frontier stays standard)
|
|
225
|
-
* - Incomplete size
|
|
248
|
+
* - Incomplete size → tier-conditional cold-start (#3263): mid/low → standard; frontier/unknown → rapid
|
|
249
|
+
* - Size known, tier missing → escalate on M/L (partial evidence)
|
|
226
250
|
*/
|
|
227
251
|
export function selectCeremonyDepthFromMatrix(inputs) {
|
|
228
252
|
const shape = inputs.projectShape ?? null;
|
|
@@ -279,7 +303,7 @@ function parseConfig(raw) {
|
|
|
279
303
|
* Deterministic depth selection (pure; no IO).
|
|
280
304
|
*
|
|
281
305
|
* Precedence: disabled → standard; override → forced depth; else matrix on inputs;
|
|
282
|
-
* empty inputs → **rapid** (
|
|
306
|
+
* empty inputs → **rapid** (unknown-tier cold default; #3263 mid/low need modelTier set).
|
|
283
307
|
*/
|
|
284
308
|
export function selectCeremonyDepth(options = {}) {
|
|
285
309
|
const config = {
|
|
@@ -317,8 +341,8 @@ export function selectCeremonyDepth(options = {}) {
|
|
|
317
341
|
}
|
|
318
342
|
const hasAnyInput = inputs.taskSize !== null || inputs.modelTier !== null || inputs.projectShape !== null;
|
|
319
343
|
if (!hasAnyInput) {
|
|
320
|
-
//
|
|
321
|
-
const depth =
|
|
344
|
+
// Unknown-tier cold default (#3214 / #3263): rapid until modelTier or size arrives.
|
|
345
|
+
const depth = selectCeremonyColdStartDepth(null);
|
|
322
346
|
return {
|
|
323
347
|
depth,
|
|
324
348
|
source: "default",
|
|
@@ -408,6 +432,7 @@ export function ceremonyDialToDict(selection) {
|
|
|
408
432
|
autoDeferSteps: [...selection.profile.autoDeferSteps],
|
|
409
433
|
skipFatPath: selection.profile.skipFatPath,
|
|
410
434
|
lifecycleWrites: selection.profile.lifecycleWrites,
|
|
435
|
+
literalAcceptanceRequired: selection.profile.literalAcceptanceRequired,
|
|
411
436
|
label: selection.profile.label,
|
|
412
437
|
},
|
|
413
438
|
composition: {
|
|
@@ -826,4 +851,206 @@ export function resolveSessionCeremonyDialInputs(projectRoot, explicit, options
|
|
|
826
851
|
provisional,
|
|
827
852
|
};
|
|
828
853
|
}
|
|
854
|
+
function asOptionalDepth(value) {
|
|
855
|
+
return isCeremonyDepth(value) ? value : null;
|
|
856
|
+
}
|
|
857
|
+
function asOptionalTaskSize(value) {
|
|
858
|
+
return isTaskSize(value) ? value : null;
|
|
859
|
+
}
|
|
860
|
+
function asOptionalModelTier(value) {
|
|
861
|
+
return isModelTier(value) ? value : null;
|
|
862
|
+
}
|
|
863
|
+
function asOptionalProjectShape(value) {
|
|
864
|
+
return isProjectShape(value) ? value : null;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Read ceremony dial depth + provisional reasons from ritual-state (#3263 audit path).
|
|
868
|
+
* session:start already writes `ceremony_dial` (incl. provisional) — this is the
|
|
869
|
+
* operator/read path so failed runs can confirm start-light vs escalate timing.
|
|
870
|
+
*
|
|
871
|
+
* Returns `error` when ritual-state is missing/unreadable or lacks `ceremony_dial`;
|
|
872
|
+
* does not throw.
|
|
873
|
+
*/
|
|
874
|
+
export function readCeremonyDialAudit(projectRoot) {
|
|
875
|
+
const path = join(projectRoot, ".deft", "ritual-state.json");
|
|
876
|
+
const empty = (error) => ({
|
|
877
|
+
path,
|
|
878
|
+
depth: null,
|
|
879
|
+
source: null,
|
|
880
|
+
inputs: null,
|
|
881
|
+
provisional: null,
|
|
882
|
+
raw: null,
|
|
883
|
+
error,
|
|
884
|
+
});
|
|
885
|
+
try {
|
|
886
|
+
if (!existsSync(path) || !statSync(path).isFile()) {
|
|
887
|
+
return empty(`ritual-state missing at ${path}`);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
catch (exc) {
|
|
891
|
+
return empty(`ritual-state unreadable at ${path}: ${String(exc)}`);
|
|
892
|
+
}
|
|
893
|
+
let payload;
|
|
894
|
+
try {
|
|
895
|
+
payload = JSON.parse(readFileSync(path, { encoding: "utf8" }));
|
|
896
|
+
}
|
|
897
|
+
catch (exc) {
|
|
898
|
+
if (exc instanceof SyntaxError) {
|
|
899
|
+
return empty(`ritual-state is not valid JSON: ${exc.message}`);
|
|
900
|
+
}
|
|
901
|
+
return empty(`ritual-state cannot be read: ${String(exc)}`);
|
|
902
|
+
}
|
|
903
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
904
|
+
return empty("ritual-state top-level value must be an object");
|
|
905
|
+
}
|
|
906
|
+
const root = payload;
|
|
907
|
+
const dialRaw = root.ceremony_dial;
|
|
908
|
+
if (dialRaw === undefined || dialRaw === null) {
|
|
909
|
+
return empty("ritual-state has no ceremony_dial field (pre-#3214 or non-mutation session)");
|
|
910
|
+
}
|
|
911
|
+
if (typeof dialRaw !== "object" || Array.isArray(dialRaw)) {
|
|
912
|
+
return empty("ritual-state ceremony_dial must be an object");
|
|
913
|
+
}
|
|
914
|
+
const dial = dialRaw;
|
|
915
|
+
const depth = asOptionalDepth(dial.depth);
|
|
916
|
+
const source = typeof dial.source === "string" ? dial.source : null;
|
|
917
|
+
let inputs = null;
|
|
918
|
+
const inputsRaw = dial.inputs;
|
|
919
|
+
if (typeof inputsRaw === "object" && inputsRaw !== null && !Array.isArray(inputsRaw)) {
|
|
920
|
+
const rec = inputsRaw;
|
|
921
|
+
inputs = {
|
|
922
|
+
taskSize: asOptionalTaskSize(rec.taskSize),
|
|
923
|
+
modelTier: asOptionalModelTier(rec.modelTier),
|
|
924
|
+
projectShape: asOptionalProjectShape(rec.projectShape),
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
let provisional = null;
|
|
928
|
+
const provRaw = dial.provisional;
|
|
929
|
+
if (typeof provRaw === "object" && provRaw !== null && !Array.isArray(provRaw)) {
|
|
930
|
+
const rec = provRaw;
|
|
931
|
+
const reasons = Array.isArray(rec.reasons)
|
|
932
|
+
? rec.reasons.filter((r) => typeof r === "string")
|
|
933
|
+
: [];
|
|
934
|
+
provisional = {
|
|
935
|
+
taskSize: asOptionalTaskSize(rec.taskSize),
|
|
936
|
+
modelTier: asOptionalModelTier(rec.modelTier),
|
|
937
|
+
projectShape: asOptionalProjectShape(rec.projectShape),
|
|
938
|
+
reasons,
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
return {
|
|
942
|
+
path,
|
|
943
|
+
depth,
|
|
944
|
+
source,
|
|
945
|
+
inputs,
|
|
946
|
+
provisional,
|
|
947
|
+
raw: { ...dial },
|
|
948
|
+
error: null,
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
/** Collapse whitespace so operator audit lines stay single-line (Greptile P2 #3263). */
|
|
952
|
+
function oneLineAuditToken(value) {
|
|
953
|
+
return value
|
|
954
|
+
.replace(/[\r\n\t]+/g, " ")
|
|
955
|
+
.replace(/ {2,}/g, " ")
|
|
956
|
+
.trim();
|
|
957
|
+
}
|
|
958
|
+
/** One-line operator summary for audit tooling / failed-task forensics (#3263). */
|
|
959
|
+
export function formatCeremonyDialAuditLine(audit) {
|
|
960
|
+
if (audit.error !== null) {
|
|
961
|
+
return `[deft ceremony-dial audit] error=${oneLineAuditToken(audit.error)}`;
|
|
962
|
+
}
|
|
963
|
+
const parts = [
|
|
964
|
+
`[deft ceremony-dial audit] depth=${audit.depth ?? "-"}`,
|
|
965
|
+
`source=${audit.source ?? "-"}`,
|
|
966
|
+
`taskSize=${audit.inputs?.taskSize ?? "-"}`,
|
|
967
|
+
`modelTier=${audit.inputs?.modelTier ?? "-"}`,
|
|
968
|
+
`projectShape=${audit.inputs?.projectShape ?? "-"}`,
|
|
969
|
+
];
|
|
970
|
+
if (audit.provisional !== null) {
|
|
971
|
+
const reasons = audit.provisional.reasons.length > 0
|
|
972
|
+
? audit.provisional.reasons
|
|
973
|
+
.map(oneLineAuditToken)
|
|
974
|
+
.filter((r) => r.length > 0)
|
|
975
|
+
.join("; ")
|
|
976
|
+
: "(none)";
|
|
977
|
+
parts.push(`provisional.reasons=${reasons.length > 0 ? reasons : "(none)"}`);
|
|
978
|
+
}
|
|
979
|
+
return parts.join(" ");
|
|
980
|
+
}
|
|
981
|
+
export function escalateCeremonyDial(projectRoot, options) {
|
|
982
|
+
const prior = resolveCeremonyDial(projectRoot);
|
|
983
|
+
const from = prior.depth;
|
|
984
|
+
if (options.confirm !== true) {
|
|
985
|
+
return {
|
|
986
|
+
exitCode: 1,
|
|
987
|
+
from,
|
|
988
|
+
to: options.to,
|
|
989
|
+
changed: false,
|
|
990
|
+
lines: [
|
|
991
|
+
"Ceremony dial escalate changes ritual depth for future session:start.",
|
|
992
|
+
" Re-run with --confirm to apply.",
|
|
993
|
+
` Proposed: ${from} -> ${options.to} (reason: ${oneLineAuditToken(options.reason)})`,
|
|
994
|
+
],
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
const setResult = setCeremonyDial(projectRoot, {
|
|
998
|
+
override: options.to,
|
|
999
|
+
confirm: true,
|
|
1000
|
+
actor: options.actor ?? policyColonInvocation("set-ceremony-dial"),
|
|
1001
|
+
note: options.note ?? `escalate: ${options.reason}`,
|
|
1002
|
+
});
|
|
1003
|
+
if (setResult.exitCode !== 0) {
|
|
1004
|
+
return {
|
|
1005
|
+
exitCode: setResult.exitCode,
|
|
1006
|
+
from,
|
|
1007
|
+
to: options.to,
|
|
1008
|
+
changed: false,
|
|
1009
|
+
lines: setResult.stdout
|
|
1010
|
+
.split("\n")
|
|
1011
|
+
.map((l) => l.trimEnd())
|
|
1012
|
+
.filter((l) => l.length > 0),
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
// #3282: event-driven dial_transition line (fail-open).
|
|
1016
|
+
if (options.emitRunSummary !== false) {
|
|
1017
|
+
try {
|
|
1018
|
+
const audit = readCeremonyDialAudit(projectRoot);
|
|
1019
|
+
const rawSid = audit.raw?.session_id;
|
|
1020
|
+
const sid = options.sessionId ??
|
|
1021
|
+
(typeof rawSid === "string" && rawSid.length > 0
|
|
1022
|
+
? rawSid
|
|
1023
|
+
: `dial-${Date.now().toString(36)}`);
|
|
1024
|
+
const emitter = new RunSummaryEmitter({
|
|
1025
|
+
projectRoot,
|
|
1026
|
+
sessionId: sid,
|
|
1027
|
+
env: options.env,
|
|
1028
|
+
});
|
|
1029
|
+
emitter.emitDialTransition({
|
|
1030
|
+
from,
|
|
1031
|
+
to: options.to,
|
|
1032
|
+
reason: options.reason,
|
|
1033
|
+
evidence: options.evidence,
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
catch {
|
|
1037
|
+
// fail-open
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
return {
|
|
1041
|
+
exitCode: 0,
|
|
1042
|
+
from,
|
|
1043
|
+
to: options.to,
|
|
1044
|
+
changed: setResult.changed || from !== options.to,
|
|
1045
|
+
lines: [
|
|
1046
|
+
`✓ ceremony dial escalate: ${from} -> ${options.to}`,
|
|
1047
|
+
` reason: ${oneLineAuditToken(options.reason)}`,
|
|
1048
|
+
...(options.evidence ? [` evidence: ${oneLineAuditToken(options.evidence)}`] : []),
|
|
1049
|
+
...setResult.stdout
|
|
1050
|
+
.split("\n")
|
|
1051
|
+
.map((l) => l.trimEnd())
|
|
1052
|
+
.filter((l) => l.length > 0),
|
|
1053
|
+
],
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
829
1056
|
//# sourceMappingURL=ceremony-dial.js.map
|
package/dist/policy/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from "./ac-pass-banking.js";
|
|
1
2
|
export * from "./agents-md-advisory.js";
|
|
2
3
|
export * from "./autonomy.js";
|
|
3
4
|
export * from "./capacity.js";
|
|
@@ -13,6 +14,7 @@ export * from "./host-hooks.js";
|
|
|
13
14
|
export * from "./host-slash-commands.js";
|
|
14
15
|
export * from "./hotfix-criteria.js";
|
|
15
16
|
export * from "./intent-ceiling.js";
|
|
17
|
+
export * from "./merge-approval-head.js";
|
|
16
18
|
export * from "./min-greptile-confidence.js";
|
|
17
19
|
export * from "./no-deft-directive.js";
|
|
18
20
|
export * from "./org-force-on-migration.js";
|
package/dist/policy/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FIELD_HOST_SKILL_DISCOVERY, FIELD_HOST_SKILL_DISCOVERY_CLI_ALIAS, inspectHostSkillDiscovery, } from "../init-deposit/skill-discovery-hosts.js";
|
|
2
2
|
import { FIELD_OPENCLAW_PRODUCT_COMMANDS, FIELD_OPENCLAW_PRODUCT_COMMANDS_CLI_ALIAS, inspectOpenClawProductCommands, } from "../slash/openclaw-deposit.js";
|
|
3
|
+
import { FIELD_AC_PASS_BANKING, FIELD_AC_PASS_BANKING_CLI_ALIAS, inspectAcPassBanking, } from "./ac-pass-banking.js";
|
|
3
4
|
import { FIELD_CEREMONY_DIAL, FIELD_CEREMONY_DIAL_CLI_ALIAS, inspectCeremonyDial, } from "./ceremony-dial.js";
|
|
4
5
|
import { FIELD_CHECK_RESUME, FIELD_CHECK_RESUME_CLI_ALIAS, inspectCheckResume, } from "./check-resume.js";
|
|
5
6
|
import { FIELD_COVERAGE_DEBT, FIELD_COVERAGE_DEBT_CLI_ALIAS, inspectCoverageDebt, } from "./coverage-debt.js";
|
|
@@ -16,6 +17,7 @@ import { FIELD_RUNTIME_AUTHORITY, FIELD_RUNTIME_AUTHORITY_CLI_ALIAS, inspectRunt
|
|
|
16
17
|
import { FIELD_STALENESS_TICKLER, FIELD_STALENESS_TICKLER_CLI_ALIAS, inspectStalenessTickler, } from "./staleness-tickler.js";
|
|
17
18
|
import { FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, inspectValueFeedback, } from "./value-feedback.js";
|
|
18
19
|
import { DEFAULT_WIP_CAP } from "./wip.js";
|
|
20
|
+
export * from "./ac-pass-banking.js";
|
|
19
21
|
export * from "./agents-md-advisory.js";
|
|
20
22
|
export * from "./autonomy.js";
|
|
21
23
|
export * from "./capacity.js";
|
|
@@ -31,6 +33,7 @@ export * from "./host-hooks.js";
|
|
|
31
33
|
export * from "./host-slash-commands.js";
|
|
32
34
|
export * from "./hotfix-criteria.js";
|
|
33
35
|
export * from "./intent-ceiling.js";
|
|
36
|
+
export * from "./merge-approval-head.js";
|
|
34
37
|
export * from "./min-greptile-confidence.js";
|
|
35
38
|
export * from "./no-deft-directive.js";
|
|
36
39
|
export * from "./org-force-on-migration.js";
|
|
@@ -419,6 +422,15 @@ function inspectCeremonyDialField(data, projectRoot) {
|
|
|
419
422
|
source: field.source,
|
|
420
423
|
};
|
|
421
424
|
}
|
|
425
|
+
function inspectAcPassBankingField(data, projectRoot) {
|
|
426
|
+
const field = inspectAcPassBanking(data, projectRoot);
|
|
427
|
+
return {
|
|
428
|
+
name: field.name,
|
|
429
|
+
current: field.current,
|
|
430
|
+
default: field.default,
|
|
431
|
+
source: field.source,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
422
434
|
const REGISTERED_POLICIES = [
|
|
423
435
|
inspectAllowDirectCommits,
|
|
424
436
|
inspectWipCap,
|
|
@@ -447,6 +459,7 @@ const REGISTERED_POLICIES = [
|
|
|
447
459
|
inspectRequireHumanMergeField,
|
|
448
460
|
inspectHotfixCriteriaField,
|
|
449
461
|
inspectCeremonyDialField,
|
|
462
|
+
inspectAcPassBankingField,
|
|
450
463
|
];
|
|
451
464
|
/** Walk registered inspectors and return one row per field (#1148). */
|
|
452
465
|
export function inspectAllPolicies(projectRoot) {
|
|
@@ -485,7 +498,9 @@ export function inspectOnePolicy(name, projectRoot) {
|
|
|
485
498
|
? FIELD_MIN_GREPTILE_CONFIDENCE
|
|
486
499
|
: name === FIELD_CEREMONY_DIAL_CLI_ALIAS
|
|
487
500
|
? FIELD_CEREMONY_DIAL
|
|
488
|
-
: name
|
|
501
|
+
: name === FIELD_AC_PASS_BANKING_CLI_ALIAS
|
|
502
|
+
? FIELD_AC_PASS_BANKING
|
|
503
|
+
: name;
|
|
489
504
|
for (const field of inspectAllPolicies(projectRoot)) {
|
|
490
505
|
if (field.name === normalized)
|
|
491
506
|
return field;
|