@codyswann/lisa 2.279.2 → 2.281.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/cli/doctor-readiness-audit-allowlist.d.ts +7 -0
- package/dist/cli/doctor-readiness-audit-allowlist.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-audit-allowlist.js +177 -0
- package/dist/cli/doctor-readiness-audit-allowlist.js.map +1 -0
- package/dist/cli/doctor-readiness-capabilities.d.ts +33 -0
- package/dist/cli/doctor-readiness-capabilities.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-capabilities.js +26 -0
- package/dist/cli/doctor-readiness-capabilities.js.map +1 -0
- package/dist/cli/doctor-readiness-context-claims.d.ts +14 -0
- package/dist/cli/doctor-readiness-context-claims.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context-claims.js +117 -0
- package/dist/cli/doctor-readiness-context-claims.js.map +1 -0
- package/dist/cli/doctor-readiness-context-mechanisms.d.ts +46 -0
- package/dist/cli/doctor-readiness-context-mechanisms.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context-mechanisms.js +116 -0
- package/dist/cli/doctor-readiness-context-mechanisms.js.map +1 -0
- package/dist/cli/doctor-readiness-context.d.ts +16 -0
- package/dist/cli/doctor-readiness-context.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-context.js +244 -0
- package/dist/cli/doctor-readiness-context.js.map +1 -0
- package/dist/cli/doctor-readiness-delivery.d.ts.map +1 -1
- package/dist/cli/doctor-readiness-delivery.js +1 -10
- package/dist/cli/doctor-readiness-delivery.js.map +1 -1
- package/dist/cli/doctor-readiness-domain.d.ts +17 -0
- package/dist/cli/doctor-readiness-domain.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-domain.js +197 -0
- package/dist/cli/doctor-readiness-domain.js.map +1 -0
- package/dist/cli/doctor-readiness-guardrails.d.ts +15 -0
- package/dist/cli/doctor-readiness-guardrails.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-guardrails.js +219 -0
- package/dist/cli/doctor-readiness-guardrails.js.map +1 -0
- package/dist/cli/doctor-readiness-operations.d.ts +103 -0
- package/dist/cli/doctor-readiness-operations.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-operations.js +207 -0
- package/dist/cli/doctor-readiness-operations.js.map +1 -0
- package/dist/cli/doctor-readiness-shared.d.ts +47 -0
- package/dist/cli/doctor-readiness-shared.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-shared.js +88 -0
- package/dist/cli/doctor-readiness-shared.js.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.d.ts +67 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.js +316 -0
- package/dist/cli/doctor-readiness-supply-chain-scan.js.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain.d.ts +14 -0
- package/dist/cli/doctor-readiness-supply-chain.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-supply-chain.js +231 -0
- package/dist/cli/doctor-readiness-supply-chain.js.map +1 -0
- package/dist/cli/doctor-readiness-workflows.d.ts +20 -0
- package/dist/cli/doctor-readiness-workflows.d.ts.map +1 -1
- package/dist/cli/doctor-readiness-workflows.js +29 -7
- package/dist/cli/doctor-readiness-workflows.js.map +1 -1
- package/dist/cli/doctor-readiness-workspaces.d.ts +22 -0
- package/dist/cli/doctor-readiness-workspaces.d.ts.map +1 -0
- package/dist/cli/doctor-readiness-workspaces.js +98 -0
- package/dist/cli/doctor-readiness-workspaces.js.map +1 -0
- package/dist/cli/doctor-readiness.d.ts.map +1 -1
- package/dist/cli/doctor-readiness.js +23 -13
- package/dist/cli/doctor-readiness.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +23 -0
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The context-routing readiness producer — ship blocker B6 (PRD #1739, #1896).
|
|
3
|
+
*
|
|
4
|
+
* Dimension 1 of the `readiness-rubric` asks whether an agent can recover the
|
|
5
|
+
* real job from what is written down. Blocker B6 asks the sharper half of that:
|
|
6
|
+
* does the written word claim only what something actually enforces? An agent
|
|
7
|
+
* that reads "the pre-commit hook always runs the tests" stops verifying, so a
|
|
8
|
+
* documented guarantee with no mechanism behind it is worse than silence.
|
|
9
|
+
*
|
|
10
|
+
* Cross-checking prose against machinery is false-positive-prone, and a standing
|
|
11
|
+
* B6 is not a soft signal: the blocker engine reads a finding's `blocker` id and
|
|
12
|
+
* evidence and never reads its status, so a `WARN` finding naming B6 flips the
|
|
13
|
+
* whole repository to `NOT_READY` exactly as a `FAIL` one would. The `WARN`
|
|
14
|
+
* status communicates confidence to a human reader; it does NOT soften the
|
|
15
|
+
* verdict. **Precision is the only real defense**, which is why three
|
|
16
|
+
* disciplines are load-bearing here:
|
|
17
|
+
*
|
|
18
|
+
* 1. **Only a provable, high-confidence overstatement stands the blocker.** A
|
|
19
|
+
* claim is faulted only when the sentence names an in-repository mechanism
|
|
20
|
+
* that survives `classifyMechanism` and still does not exist. Package names,
|
|
21
|
+
* `org/repo` slugs, git refs, and generated artifacts are classified
|
|
22
|
+
* `unmappable` rather than missing.
|
|
23
|
+
* 2. **Anything short of that is an observation, never a blocker.** A claim with
|
|
24
|
+
* no resolvable mechanism, one inside a code fence, or a hedged sentence is
|
|
25
|
+
* surfaced as a non-blocking finding — never guessed into a violation, and
|
|
26
|
+
* never dropped into silence.
|
|
27
|
+
* 3. **A clean finding carries no `blocker` key.** A PASS finding that named B6
|
|
28
|
+
* would report a healthy repository as NOT_READY.
|
|
29
|
+
* @module cli/doctor-readiness-context
|
|
30
|
+
*/
|
|
31
|
+
import { collectClaims, } from "./doctor-readiness-context-claims.js";
|
|
32
|
+
import { classifyMechanism, loadIgnoreMatcher, } from "./doctor-readiness-context-mechanisms.js";
|
|
33
|
+
import { informationalFindings, readFileOrNull, } from "./doctor-readiness-shared.js";
|
|
34
|
+
/** The context-routing readiness dimension id (readiness-rubric, RRR-1). */
|
|
35
|
+
export const CONTEXT_ROUTING_DIMENSION_ID = "context-routing";
|
|
36
|
+
/** The ship blocker for documentation that overstates enforced guarantees. */
|
|
37
|
+
const CONTEXT_BLOCKER_ID = "B6";
|
|
38
|
+
/** Most claim lines carried into one finding, to keep the report readable. */
|
|
39
|
+
const MAX_EVIDENCE_LINES = 10;
|
|
40
|
+
/** Longest quoted claim carried into persisted evidence. */
|
|
41
|
+
const MAX_QUOTE_LENGTH = 160;
|
|
42
|
+
/**
|
|
43
|
+
* Shorten a quoted claim so persisted evidence stays readable.
|
|
44
|
+
* @param text - The raw claim line
|
|
45
|
+
* @returns The claim, truncated to {@link MAX_QUOTE_LENGTH}
|
|
46
|
+
*/
|
|
47
|
+
function quoteClaim(text) {
|
|
48
|
+
return text.length > MAX_QUOTE_LENGTH
|
|
49
|
+
? `${text.slice(0, MAX_QUOTE_LENGTH).trimEnd()}…`
|
|
50
|
+
: text;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Cross-check one claim against the mechanisms it names.
|
|
54
|
+
*
|
|
55
|
+
* The claim becomes a violation only when at least one named mechanism is
|
|
56
|
+
* classified `missing` — provably absent AND provably a path this repository
|
|
57
|
+
* would own. Every other outcome is an observation, because a blocker built on
|
|
58
|
+
* a token that might be a package name or a git ref would flip a healthy
|
|
59
|
+
* repository to NOT_READY.
|
|
60
|
+
* @param root - Repository root
|
|
61
|
+
* @param claim - The claim to check
|
|
62
|
+
* @param isIgnored - The repository's ignore matcher
|
|
63
|
+
* @returns Either a violation line, an unmappable line, or neither
|
|
64
|
+
*/
|
|
65
|
+
async function auditOneClaim(root, claim, isIgnored) {
|
|
66
|
+
const verdicts = await Promise.all(claim.mechanisms.map(async (mechanism) => ({
|
|
67
|
+
mechanism,
|
|
68
|
+
verdict: await classifyMechanism(root, mechanism, isIgnored),
|
|
69
|
+
})));
|
|
70
|
+
const missing = verdicts
|
|
71
|
+
.filter(entry => entry.verdict === "missing")
|
|
72
|
+
.map(entry => entry.mechanism);
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
const named = missing.map(entry => `\`${entry}\``).join(", ");
|
|
75
|
+
return {
|
|
76
|
+
violation: `\`${claim.file}\` line ${claim.line} claims enforcement by ` +
|
|
77
|
+
`${named}, which does not exist in this repository: ` +
|
|
78
|
+
`"${quoteClaim(claim.text)}"`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (verdicts.some(entry => entry.verdict === "present")) {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
unmappable: `\`${claim.file}\` line ${claim.line} states a guarantee but names ` +
|
|
86
|
+
`no mechanism this check can resolve to a repository path, so it was ` +
|
|
87
|
+
`not assessed: "${quoteClaim(claim.text)}"`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Cross-check every claim against the mechanism it names.
|
|
92
|
+
* @param root - Repository root
|
|
93
|
+
* @param claims - The claims read from the instruction surfaces
|
|
94
|
+
* @returns Evidence lines for overstatements, and unmappable-claim notes
|
|
95
|
+
*/
|
|
96
|
+
async function auditClaims(root, claims) {
|
|
97
|
+
const isIgnored = await loadIgnoreMatcher(root);
|
|
98
|
+
const audited = await Promise.all(claims.map(async (claim) => await auditOneClaim(root, claim, isIgnored)));
|
|
99
|
+
return {
|
|
100
|
+
violations: audited.flatMap(entry => entry.violation === undefined ? [] : [entry.violation]),
|
|
101
|
+
unmappable: audited.flatMap(entry => entry.unmappable === undefined ? [] : [entry.unmappable]),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Establish which of the four positive context-routing artifacts are present: a
|
|
106
|
+
* canonical `AGENTS.md`, a `CLAUDE.md` pointing at it, a parseable
|
|
107
|
+
* `.lisa.config.json`, and a wiki index.
|
|
108
|
+
* @param root - Repository root
|
|
109
|
+
* @returns The present and missing artifact descriptions
|
|
110
|
+
*/
|
|
111
|
+
async function inspectRoutingArtifacts(root) {
|
|
112
|
+
const agents = await readFileOrNull(root, "AGENTS.md");
|
|
113
|
+
const claude = await readFileOrNull(root, "CLAUDE.md");
|
|
114
|
+
const config = await readFileOrNull(root, ".lisa.config.json");
|
|
115
|
+
const wiki = await readFileOrNull(root, "wiki/index.md");
|
|
116
|
+
const checks = [
|
|
117
|
+
[agents !== null && agents.trim() !== "", "a canonical `AGENTS.md`"],
|
|
118
|
+
[
|
|
119
|
+
claude !== null && claude.includes("AGENTS.md"),
|
|
120
|
+
"a `CLAUDE.md` pointer to `AGENTS.md`",
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
config !== null && isParseableJson(config),
|
|
124
|
+
"a parseable `.lisa.config.json`",
|
|
125
|
+
],
|
|
126
|
+
[wiki !== null, "a `wiki/index.md` knowledge index"],
|
|
127
|
+
];
|
|
128
|
+
return {
|
|
129
|
+
present: checks.flatMap(([ok, label]) => (ok ? [label] : [])),
|
|
130
|
+
missing: checks.flatMap(([ok, label]) => (ok ? [] : [label])),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Whether a string parses as JSON.
|
|
135
|
+
* @param source - Candidate JSON text
|
|
136
|
+
* @returns True when it parses
|
|
137
|
+
*/
|
|
138
|
+
function isParseableJson(source) {
|
|
139
|
+
try {
|
|
140
|
+
JSON.parse(source);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build the rubric-shaped B6 finding from its evidence lines.
|
|
149
|
+
* @param violations - Evidence lines
|
|
150
|
+
* @returns The B6 finding
|
|
151
|
+
*/
|
|
152
|
+
function contextFinding(violations) {
|
|
153
|
+
const shown = violations.slice(0, MAX_EVIDENCE_LINES);
|
|
154
|
+
const overflow = violations.length - shown.length;
|
|
155
|
+
return {
|
|
156
|
+
blocker: CONTEXT_BLOCKER_ID,
|
|
157
|
+
invariant_violated: "the written word claims only what something actually enforces",
|
|
158
|
+
evidence: shown.join(" | ") +
|
|
159
|
+
(overflow > 0
|
|
160
|
+
? ` | (+${overflow} further overstatement(s) of the same kind)`
|
|
161
|
+
: ""),
|
|
162
|
+
why_proof_missed: "documentation is never executed, so no test, lint rule, or review step " +
|
|
163
|
+
"ever observes that the guarantee it promises has no mechanism behind it " +
|
|
164
|
+
"— and an agent that reads the promise stops checking for itself",
|
|
165
|
+
root_correction: "either build the mechanism the sentence names, or rewrite the sentence " +
|
|
166
|
+
"to describe what is actually enforced, so the written word and the " +
|
|
167
|
+
"machinery say the same thing",
|
|
168
|
+
machinery_to_remove: [
|
|
169
|
+
"documented guarantees with no mechanism behind them, which cost trust " +
|
|
170
|
+
"every time an agent relies on one",
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Build the stated-reason SKIP for a repository whose context routing cannot be
|
|
176
|
+
* established: nothing overstated, but not enough written down to call it clean.
|
|
177
|
+
* @param artifacts - Which routing artifacts are present and missing
|
|
178
|
+
* @param unmappable - Claims that named no resolvable mechanism
|
|
179
|
+
* @returns The SKIP dimension record
|
|
180
|
+
*/
|
|
181
|
+
function skipRecord(artifacts, unmappable) {
|
|
182
|
+
return {
|
|
183
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
184
|
+
status: "SKIP",
|
|
185
|
+
findings: [
|
|
186
|
+
{
|
|
187
|
+
reason: "no documented guarantee was found to overstate anything, but this " +
|
|
188
|
+
"repository is missing " +
|
|
189
|
+
`${artifacts.missing.join(", ")}, so whether an agent can recover the ` +
|
|
190
|
+
"real job from what is written down is not established either way",
|
|
191
|
+
skip: true,
|
|
192
|
+
},
|
|
193
|
+
...informationalFindings(unmappable),
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Assess the context-routing dimension: B6, "documentation overstates enforced
|
|
199
|
+
* guarantees". Offline by construction — it reads only the repository's own
|
|
200
|
+
* instruction surfaces and the paths they name — and high-precision by design:
|
|
201
|
+
* it stands B6 only on a named mechanism that survives {@link classifyMechanism}
|
|
202
|
+
* and still demonstrably does not exist. The record's status is `WARN` rather
|
|
203
|
+
* than `FAIL`, but that is a confidence signal to a human reader only: a
|
|
204
|
+
* standing B6 blocker flips the repository to `NOT_READY` either way.
|
|
205
|
+
* @param root - Project root to assess
|
|
206
|
+
* @returns The context-routing dimension record
|
|
207
|
+
*/
|
|
208
|
+
export async function assessContextRoutingDimension(root) {
|
|
209
|
+
const claims = await collectClaims(root);
|
|
210
|
+
const { violations, unmappable } = await auditClaims(root, claims);
|
|
211
|
+
const artifacts = await inspectRoutingArtifacts(root);
|
|
212
|
+
if (violations.length > 0) {
|
|
213
|
+
return {
|
|
214
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
215
|
+
// `WARN` reports how much confidence an offline prose cross-check can
|
|
216
|
+
// carry — it does NOT soften the verdict. The blocker engine never reads
|
|
217
|
+
// this status, so the finding below flips the repository to `NOT_READY`
|
|
218
|
+
// exactly as a `FAIL` would; precision is what keeps that honest.
|
|
219
|
+
status: "WARN",
|
|
220
|
+
findings: [
|
|
221
|
+
contextFinding(violations),
|
|
222
|
+
...informationalFindings(unmappable),
|
|
223
|
+
],
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
if (artifacts.missing.length > 0) {
|
|
227
|
+
return skipRecord(artifacts, unmappable);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
id: CONTEXT_ROUTING_DIMENSION_ID,
|
|
231
|
+
status: "PASS",
|
|
232
|
+
findings: [
|
|
233
|
+
{
|
|
234
|
+
evidence: `Cross-checked ${claims.length} documented guarantee(s) across this ` +
|
|
235
|
+
"repository's instruction surfaces: every one that names a mechanism " +
|
|
236
|
+
`names one that exists. Context routing is carried by ` +
|
|
237
|
+
`${artifacts.present.join(", ")}.`,
|
|
238
|
+
checked: [CONTEXT_BLOCKER_ID],
|
|
239
|
+
},
|
|
240
|
+
...informationalFindings(unmappable),
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=doctor-readiness-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-context.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-readiness-delivery.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor-readiness-delivery.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,iCAAiC,CAAC;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,+BAA+B,uBAAuB,CAAC;AAmOpE;;;;;;;;;GASG;AACH,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAiBnC"}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* @module cli/doctor-readiness-delivery
|
|
26
26
|
*/
|
|
27
27
|
import { detectCredentialFindings, } from "./doctor-readiness-credentials.js";
|
|
28
|
+
import { informationalFindings } from "./doctor-readiness-shared.js";
|
|
28
29
|
import { assessReleasePath, PROMOTION_ACTION, } from "./doctor-readiness-release-path.js";
|
|
29
30
|
import { parseRepositoryWorkflows, } from "./doctor-readiness-workflows.js";
|
|
30
31
|
/** The delivery/authority readiness dimension id (readiness-rubric, RRR-1). */
|
|
@@ -93,16 +94,6 @@ function credentialFinding(violations) {
|
|
|
93
94
|
],
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Wrap non-blocking observations as findings. They deliberately carry no
|
|
98
|
-
* `blocker` key: naming one would stand a blocker up on an observation that was
|
|
99
|
-
* never decidable offline.
|
|
100
|
-
* @param notes - Informational lines
|
|
101
|
-
* @returns Findings, one per note
|
|
102
|
-
*/
|
|
103
|
-
function informationalFindings(notes) {
|
|
104
|
-
return notes.map(note => ({ observation: note, blocking: false }));
|
|
105
|
-
}
|
|
106
97
|
/**
|
|
107
98
|
* Build the SKIP record for a repository whose release paths could not be
|
|
108
99
|
* settled from the workflow files alone.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-readiness-delivery.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAEL,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAEL,wBAAwB,GACzB,MAAM,iCAAiC,CAAC;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,+BAA+B,GAAG,oBAAoB,CAAC;AAEpE,gFAAgF;AAChF,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,+EAA+E;AAC/E,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAUnC;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,SAAoC;IAEpC,MAAM,QAAQ,GAAkC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAC3E,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC1B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,CAAC,CAAC,CACH,CAAC;IACF,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CACrC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CACvD;QACD,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CACrC,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CACtD;QACD,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,MAAM;QACvE,eAAe,EAAE,QAAQ,CAAC,MAAM;KACjC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,UAA6B;IAE7B,OAAO;QACL,OAAO,EAAE,kBAAkB;QAC3B,kBAAkB,EAChB,2EAA2E;QAC7E,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,gBAAgB,EACd,wEAAwE;YACxE,uEAAuE;YACvE,iDAAiD;QACnD,eAAe,EACb,yEAAyE;YACzE,6BAA6B,gBAAgB,6BAA6B;YAC1E,kCAAkC;QACpC,mBAAmB,EAAE;YACnB,yEAAyE;gBACvE,4CAA4C;SAC/C;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CACxB,UAA6B;IAE7B,OAAO;QACL,OAAO,EAAE,qBAAqB;QAC9B,kBAAkB,EAChB,wEAAwE;QAC1E,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAChC,gBAAgB,EACd,0EAA0E;YAC1E,2DAA2D;QAC7D,eAAe,EACb,2EAA2E;YAC3E,2EAA2E;YAC3E,wBAAwB;QAC1B,mBAAmB,EAAE;YACnB,yEAAyE;gBACvE,6BAA6B;SAChC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,
|
|
1
|
+
{"version":3,"file":"doctor-readiness-delivery.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-delivery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReadinessDimensionRecord } from "./doctor-readiness-types.js";
|
|
2
|
+
import { type ParsedWorkflow } from "./doctor-readiness-workflows.js";
|
|
3
|
+
/** The domain-ownership readiness dimension id (readiness-rubric, RRR-1). */
|
|
4
|
+
export declare const DOMAIN_OWNERSHIP_DIMENSION_ID = "domain-ownership";
|
|
5
|
+
/**
|
|
6
|
+
* Assess the domain-ownership dimension: B1, "a realistic path causes silent
|
|
7
|
+
* data loss". Offline by construction — it reads only the repository's declared
|
|
8
|
+
* workflows — and deliberately conservative: it stands B1 only when a workflow
|
|
9
|
+
* file alone proves an irreversible data-destroying command runs unattended,
|
|
10
|
+
* ungated, and with no way back, and renders a stated-reason SKIP in every other
|
|
11
|
+
* case, including the clean one.
|
|
12
|
+
* @param root - Project root to assess
|
|
13
|
+
* @param parsedWorkflows - Pre-parsed workflows (default: parse `root`)
|
|
14
|
+
* @returns The domain-ownership dimension record
|
|
15
|
+
*/
|
|
16
|
+
export declare function assessDomainOwnershipDimension(root: string, parsedWorkflows?: readonly ParsedWorkflow[]): Promise<ReadinessDimensionRecord>;
|
|
17
|
+
//# sourceMappingURL=doctor-readiness-domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-domain.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-domain.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,iCAAiC,CAAC;AAEzC,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAiKhE;;;;;;;;;;GAUG;AACH,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CAyBnC"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The domain-ownership readiness producer — ship blocker B1 (PRD #1739, #1896).
|
|
3
|
+
*
|
|
4
|
+
* Dimension 3 of the `readiness-rubric` asks whether the business rules,
|
|
5
|
+
* glossary, and danger zones are owned and written down. B1 asks the sharpest
|
|
6
|
+
* consequence of getting that wrong: does a realistic path destroy or corrupt
|
|
7
|
+
* data with no error surfaced and no way back?
|
|
8
|
+
*
|
|
9
|
+
* That question is the hardest one in the rubric to answer honestly offline, and
|
|
10
|
+
* getting it wrong is expensive in exactly one direction. A standing blocker
|
|
11
|
+
* flips the whole repository to `NOT_READY` regardless of this dimension's
|
|
12
|
+
* status — `WARN` is a confidence signal to a human reader, never a softener —
|
|
13
|
+
* so a false B1 on an ordinary brownfield repository would destroy the trust
|
|
14
|
+
* this entire feature exists to build. Three disciplines follow:
|
|
15
|
+
*
|
|
16
|
+
* 1. **Only an unambiguous, automated, ungated, unrecoverable destruction of
|
|
17
|
+
* data stands B1.** The command must irreversibly destroy *data* (not build
|
|
18
|
+
* output), inside a job an automated trigger reaches, with no `if:`, no
|
|
19
|
+
* `environment:`, no backup step beside it, and no checked-in runbook.
|
|
20
|
+
* 2. **Presence of a destructive surface is never a violation.** A `migrations/`
|
|
21
|
+
* directory, a reversible migration that drops a table, a guarded command, a
|
|
22
|
+
* manually dispatched workflow, or a command aimed at an ephemeral CI target
|
|
23
|
+
* are all reported as observations at most.
|
|
24
|
+
* 3. **The clean case is a stated SKIP, never PASS.** Whether the danger zones
|
|
25
|
+
* are genuinely owned and written down cannot be established by reading
|
|
26
|
+
* files; claiming PASS would be the same overstatement B6 exists to catch.
|
|
27
|
+
* @module cli/doctor-readiness-domain
|
|
28
|
+
*/
|
|
29
|
+
import { describeCommands, hasCheckedInRunbook, looksEphemeral, scanCommands, } from "./doctor-readiness-operations.js";
|
|
30
|
+
import { informationalFindings } from "./doctor-readiness-shared.js";
|
|
31
|
+
import { parseRepositoryWorkflows, } from "./doctor-readiness-workflows.js";
|
|
32
|
+
/** The domain-ownership readiness dimension id (readiness-rubric, RRR-1). */
|
|
33
|
+
export const DOMAIN_OWNERSHIP_DIMENSION_ID = "domain-ownership";
|
|
34
|
+
/** The ship blocker for a realistic path that causes silent data loss. */
|
|
35
|
+
const DOMAIN_BLOCKER_ID = "B1";
|
|
36
|
+
/** Most destructive commands quoted in one finding before summarizing. */
|
|
37
|
+
const MAX_EVIDENCE_COMMANDS = 10;
|
|
38
|
+
/**
|
|
39
|
+
* Commands that irreversibly destroy stored data. Every entry is a whole
|
|
40
|
+
* operation, not a keyword: `rm -rf` is deliberately absent because build
|
|
41
|
+
* outputs and caches dominate its real-world use, and a blocker built on it
|
|
42
|
+
* would fire on nearly every repository that cleans a `dist/` directory.
|
|
43
|
+
*/
|
|
44
|
+
const IRREVERSIBLE_DATA_OPS = [
|
|
45
|
+
/\bdrop\s+database\b/,
|
|
46
|
+
/\bdrop\s+schema\b/,
|
|
47
|
+
/\btruncate\s+table\b/,
|
|
48
|
+
/\baws\s+s3\s+rm\b[^\n]*--recursive\b/,
|
|
49
|
+
/\baws\s+s3\s+rb\b[^\n]*--force\b/,
|
|
50
|
+
/\baws\s+dynamodb\s+delete-table\b/,
|
|
51
|
+
/\baws\s+rds\s+delete-db-(instance|cluster)\b[^\n]*--skip-final-snapshot\b/,
|
|
52
|
+
];
|
|
53
|
+
/** Commands that create the way back: a copy taken before the destruction. */
|
|
54
|
+
const RECOVERY_COMMANDS = [
|
|
55
|
+
/\bpg_dump\b/,
|
|
56
|
+
/\bmysqldump\b/,
|
|
57
|
+
/\bbackup\b/,
|
|
58
|
+
/\bsnapshot\b/,
|
|
59
|
+
/\baws\s+s3\s+sync\b/,
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* Whether a command irreversibly destroys data that is not obviously throwaway.
|
|
63
|
+
*
|
|
64
|
+
* The ephemeral screen reads the job's `env:` block alongside the command,
|
|
65
|
+
* because the evidence is routinely outside the command text: `psql
|
|
66
|
+
* "$DATABASE_URL" -c "DROP SCHEMA public CASCADE"` says nothing on its own,
|
|
67
|
+
* while the `DATABASE_URL` it expands to may point at `127.0.0.1` and settle the
|
|
68
|
+
* question outright.
|
|
69
|
+
* @param command - The lower-cased `run` command
|
|
70
|
+
* @param job - The job the command runs in
|
|
71
|
+
* @returns True when the command is an unambiguous data-destroying operation
|
|
72
|
+
*/
|
|
73
|
+
function destroysData(command, job) {
|
|
74
|
+
return (IRREVERSIBLE_DATA_OPS.some(pattern => pattern.test(command)) &&
|
|
75
|
+
!looksEphemeral(`${command}\n${job.env}`));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* State why a job that boots its own `services:` containers cannot be settled.
|
|
79
|
+
* A job that starts its own database is operating on state it created moments
|
|
80
|
+
* earlier, so destroying it is not data loss — but proving *which* store the
|
|
81
|
+
* command targets is beyond an offline read, so this is deferred, not cleared.
|
|
82
|
+
* @param job - The job to consider
|
|
83
|
+
* @returns A stated reason, or null when the job starts no services
|
|
84
|
+
*/
|
|
85
|
+
function servicesDeferral(job) {
|
|
86
|
+
if (job.services.length === 0) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return (`Job \`${job.id}\` runs a destructive data operation while starting its own ` +
|
|
90
|
+
`\`services:\` container(s) (${job.services.join(", ")}), which are created ` +
|
|
91
|
+
"and thrown away inside the run, so whether the command targets durable " +
|
|
92
|
+
"data is not established either way");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether a job takes its own copy before destroying anything — the way back,
|
|
96
|
+
* sitting right beside the danger.
|
|
97
|
+
* @param job - The parsed job
|
|
98
|
+
* @returns True when any step in the job looks like a backup
|
|
99
|
+
*/
|
|
100
|
+
function jobTakesBackup(job) {
|
|
101
|
+
return job.steps.some(step => RECOVERY_COMMANDS.some(pattern => pattern.test(step.run.toLowerCase())));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Build the rubric-shaped B1 finding from the destructive commands it cites.
|
|
105
|
+
* @param scan - The destructive-operation scan
|
|
106
|
+
* @returns The B1 finding
|
|
107
|
+
*/
|
|
108
|
+
function domainFinding(scan) {
|
|
109
|
+
return {
|
|
110
|
+
blocker: DOMAIN_BLOCKER_ID,
|
|
111
|
+
invariant_violated: "no realistic path destroys or corrupts data without surfacing an error " +
|
|
112
|
+
"and leaving a way back",
|
|
113
|
+
evidence: describeCommands(scan.ungated, MAX_EVIDENCE_COMMANDS),
|
|
114
|
+
why_proof_missed: "the destructive command is exercised only against real data, so no test " +
|
|
115
|
+
"run and no review step ever observes what it removes — the pipeline " +
|
|
116
|
+
"reports green whether the data survived or not",
|
|
117
|
+
root_correction: "put the operation behind an explicit gate (a job `environment:` or a " +
|
|
118
|
+
"confirmation input) and give it a way back — a snapshot taken in the " +
|
|
119
|
+
"same job, or a checked-in runbook naming the restore procedure",
|
|
120
|
+
machinery_to_remove: [
|
|
121
|
+
"any unattended destructive step that exists only because no retention " +
|
|
122
|
+
"or lifecycle policy was configured on the store itself",
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* State why the dimension was not settled, naming what WAS looked at so an
|
|
128
|
+
* operator can tell "nothing to report" from "never looked".
|
|
129
|
+
* @param inspected - How many workflow files were read
|
|
130
|
+
* @returns The SKIP reason
|
|
131
|
+
*/
|
|
132
|
+
function skipReason(inspected) {
|
|
133
|
+
return (`Read ${inspected} workflow file(s) for irreversible data-destroying ` +
|
|
134
|
+
"operations and found none running unattended and ungated. Whether this " +
|
|
135
|
+
"repository's business rules, glossary, and danger zones are genuinely " +
|
|
136
|
+
"owned and written down cannot be established by reading files offline — " +
|
|
137
|
+
"that needs the agent-ready domain phase — so domain ownership is not " +
|
|
138
|
+
"established either way.");
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build the SKIP record, carrying every guarded destructive operation as an
|
|
142
|
+
* observation. Those observations name no `blocker`: they are the operator's
|
|
143
|
+
* map of where the danger lives, not a verdict about it.
|
|
144
|
+
* @param guarded - The destructive commands something already guards
|
|
145
|
+
* @param scan - The destructive-operation scan
|
|
146
|
+
* @param inspected - How many workflow files were read
|
|
147
|
+
* @returns The SKIP dimension record
|
|
148
|
+
*/
|
|
149
|
+
function skipRecord(guarded, scan, inspected) {
|
|
150
|
+
return {
|
|
151
|
+
id: DOMAIN_OWNERSHIP_DIMENSION_ID,
|
|
152
|
+
status: "SKIP",
|
|
153
|
+
findings: [
|
|
154
|
+
{ reason: skipReason(inspected), skip: true },
|
|
155
|
+
...informationalFindings([
|
|
156
|
+
...guarded.map(entry => `\`${entry.workflow}\` job \`${entry.jobId}\` runs a destructive ` +
|
|
157
|
+
`operation (\`${entry.command}\`) behind a gate, beside its own ` +
|
|
158
|
+
"backup, or in a repository that checks in a recovery runbook, so " +
|
|
159
|
+
"it was not treated as a silent-data-loss path"),
|
|
160
|
+
...scan.unresolved,
|
|
161
|
+
]),
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Assess the domain-ownership dimension: B1, "a realistic path causes silent
|
|
167
|
+
* data loss". Offline by construction — it reads only the repository's declared
|
|
168
|
+
* workflows — and deliberately conservative: it stands B1 only when a workflow
|
|
169
|
+
* file alone proves an irreversible data-destroying command runs unattended,
|
|
170
|
+
* ungated, and with no way back, and renders a stated-reason SKIP in every other
|
|
171
|
+
* case, including the clean one.
|
|
172
|
+
* @param root - Project root to assess
|
|
173
|
+
* @param parsedWorkflows - Pre-parsed workflows (default: parse `root`)
|
|
174
|
+
* @returns The domain-ownership dimension record
|
|
175
|
+
*/
|
|
176
|
+
export async function assessDomainOwnershipDimension(root, parsedWorkflows) {
|
|
177
|
+
const workflows = parsedWorkflows ?? (await parseRepositoryWorkflows(root));
|
|
178
|
+
const scan = scanCommands(workflows, destroysData, {
|
|
179
|
+
exemptJob: jobTakesBackup,
|
|
180
|
+
unresolvedJob: servicesDeferral,
|
|
181
|
+
});
|
|
182
|
+
// A checked-in runbook is a way back, so it clears the "no recovery" half of
|
|
183
|
+
// B1 for the whole repository — the blocker asks for BOTH halves at once.
|
|
184
|
+
const recoverable = await hasCheckedInRunbook(root);
|
|
185
|
+
if (scan.ungated.length === 0 || recoverable) {
|
|
186
|
+
return skipRecord(recoverable ? [...scan.gated, ...scan.ungated] : scan.gated, scan, workflows.length);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
id: DOMAIN_OWNERSHIP_DIMENSION_ID,
|
|
190
|
+
// `WARN` reports how much confidence an offline read can carry; it does NOT
|
|
191
|
+
// soften the verdict. The blocker engine never reads this status, so the
|
|
192
|
+
// finding below flips the repository to `NOT_READY` exactly as `FAIL` would.
|
|
193
|
+
status: "WARN",
|
|
194
|
+
findings: [domainFinding(scan), ...informationalFindings(scan.unresolved)],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=doctor-readiness-domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-domain.js","sourceRoot":"","sources":["../../src/cli/doctor-readiness-domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReadinessDimensionRecord } from "./doctor-readiness-types.js";
|
|
2
|
+
import { type ParsedWorkflow } from "./doctor-readiness-workflows.js";
|
|
3
|
+
/** The feedback/guardrails readiness dimension id (readiness-rubric, RRR-1). */
|
|
4
|
+
export declare const FEEDBACK_GUARDRAILS_DIMENSION_ID = "feedback-guardrails";
|
|
5
|
+
/**
|
|
6
|
+
* Assess the feedback/guardrails dimension: B4, "a consequential operation has
|
|
7
|
+
* no gate and no recovery". Offline by construction, and honest about it — the
|
|
8
|
+
* environment-protection-rule half is reasoned-SKIPped in every record, so this
|
|
9
|
+
* dimension never reports `PASS`. B4 stands only on the file-provable subset.
|
|
10
|
+
* @param root - Project root to assess
|
|
11
|
+
* @param parsedWorkflows - Pre-parsed workflows (default: parse `root`)
|
|
12
|
+
* @returns The feedback/guardrails dimension record
|
|
13
|
+
*/
|
|
14
|
+
export declare function assessFeedbackGuardrailsDimension(root: string, parsedWorkflows?: readonly ParsedWorkflow[]): Promise<ReadinessDimensionRecord>;
|
|
15
|
+
//# sourceMappingURL=doctor-readiness-guardrails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-readiness-guardrails.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-readiness-guardrails.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,iCAAiC,CAAC;AAEzC,gFAAgF;AAChF,eAAO,MAAM,gCAAgC,wBAAwB,CAAC;AA0LtE;;;;;;;;GAQG;AACH,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,GAC1C,OAAO,CAAC,wBAAwB,CAAC,CA6BnC"}
|