@mstar-harness/engine 3.3.0 → 3.4.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/index.d.ts CHANGED
@@ -15,7 +15,10 @@
15
15
  * secrets and scaffolds audit-<date>/ plan dirs, and `compound` validates
16
16
  * knowledge-doc schema, reference existence, index rows and the
17
17
  * compound-refresh scope. `roles` validates the role reference mapping +
18
- * parameter tables and the load-order contract, `host` detects the active
18
+ * parameter tables and the load-order contract, `prreview` implements the
19
+ * PR-review tally/score/verdict arithmetic and the merge-class/verdict
20
+ * constants (mstar-audit pr-review.md § Tally and derived score), `host`
21
+ * detects the active
19
22
  * host from tool shapes, resolves skill roots and defines the type-only
20
23
  * `HostAdapter` contract, and `skill-authoring` lints frontmatter +
21
24
  * 5-question bodies and resolves skill-relative asset paths.
@@ -40,16 +43,16 @@ export type { ImplementerSessionLedger, ReviewPackageOptions, SddWorkspaceOption
40
43
  export { SddScriptError, assertBaseSha, implementerSessionStickyRules, readProgressLedger, reviewPackage, sddWorkspace, taskBrief, taskReportExists, } from "./sdd.js";
41
44
  export type { CompassDoc, PhaseGateOptions, PhaseGateResult, PhaseTransition, } from "./iteration.js";
42
45
  export { assertIndexRowObligations, evaluatePhaseGate, parseCompassFrontmatter, parseCompassFrontmatterText, pushCadenceProbe, validateCompassFrontmatter, } from "./iteration.js";
43
- export type { FindingsCleanupMode, ProjectRegisterDoc, ProjectRegisterEntry, RoadmapFrontmatter, RoadmapStatus, RoadmapValidation, TechDebtCheck, TechDebtRollup, TechDebtSummary, } from "./project.js";
44
- export { PROJECT_REFERENCES_DIR, PROJECT_REGISTER_FILE, PROJECT_ROADMAP_FILE, ROADMAP_STATUSES, _DEFAULT_PROJECT, findingsCleanupGate, listProjectReferenceFiles, techDebtRollup, validateProjectRegister, validateRoadmap, } from "./project.js";
46
+ export type { AppendProjectRegisterEntriesOpts, CloseProjectRegisterEntryOpts, FindingsCleanupMode, ProjectRegisterDoc, ProjectRegisterEntry, RoadmapFrontmatter, RoadmapStatus, RoadmapValidation, TechDebtCheck, TechDebtRollup, TechDebtSummary, } from "./project.js";
47
+ export { PROJECT_REFERENCES_DIR, PROJECT_REGISTER_FILE, PROJECT_ROADMAP_FILE, ROADMAP_STATUSES, _DEFAULT_PROJECT, appendProjectRegisterEntries, closeProjectRegisterEntry, findingsCleanupGate, listProjectReferenceFiles, techDebtRollup, validateProjectRegister, validateRoadmap, } from "./project.js";
45
48
  export type { MigrateNotesFile, MigrateOptions, MigratePlan, MigrateRegister, MigrateResult, MigrateRoadmap, MigrateRootV2, MigrateSnapshot, MigrateStep, } from "./migrate.js";
46
49
  export { ARCHIVED_STATUS_V1_FILE, MIGRATE_STATUS_FILE, NOTES_LEDGER_FILE, applyMigratePlan, migrateHarnessTree, } from "./migrate.js";
47
50
  export type { CompletenessItem, CompletenessLevel, CompletenessPlaceholder, CompletenessResult, DesignFrontmatter, } from "./design-md.js";
48
51
  export { assertLightDarkParity, completenessLevel, parseDesignFrontmatter, validateDesignTokenFrontmatter, } from "./design-md.js";
49
- export type { AuditCategory, AuditEffort, AuditFinding, AuditPriority, AuditRisk, PromoteAuditPlansOptions, RedactResult, ScaffoldAuditPlanOptions, ScaffoldAuditPlanResult, SecretFinding, } from "./audit.js";
50
- export { AUDIT_CATEGORIES, AUDIT_EFFORTS, AUDIT_PRIORITIES, AUDIT_RISKS, promoteAuditPlans, scaffoldAuditPlan, validateAuditStatusBlocks, } from "./audit.js";
51
- export type { ReferenceCheckResult } from "./compound.js";
52
+ export type { AuditCategory, AuditConfidence, AuditEffort, AuditFinding, AuditPriority, AuditRisk, PromoteAuditPlansOptions, RedactResult, ScaffoldAuditPlanOptions, ScaffoldAuditPlanResult, ScannedSecret, SecretFinding, SupplyChainFinding, SupplyChainFindingKind, SupplyChainResult, } from "./audit.js";
53
+ export { AUDIT_CATEGORIES, AUDIT_CONFIDENCES, AUDIT_EFFORTS, AUDIT_PRIORITIES, AUDIT_RISKS, promoteAuditPlans, scaffoldAuditPlan, scanSecrets, supplyChainChecks, validateAuditStatusBlocks, } from "./audit.js";
52
54
  export { KNOWLEDGE_BUG_PROBLEM_TYPES, KNOWLEDGE_CATEGORY_MAP, KNOWLEDGE_KNOWLEDGE_PROBLEM_TYPES, KNOWLEDGE_PROBLEM_TYPES, KNOWLEDGE_REQUIRED_FIELDS, KNOWLEDGE_RESOLUTION_TYPES, KNOWLEDGE_SEVERITIES, assertIndexRows, compoundRefreshScope, referenceExists, scopeGuard, validateSchemaYaml, } from "./compound.js";
55
+ export type { ReferenceCheckResult } from "./compound.js";
53
56
  export type { EphemeralCitation, PlanQualityFinding, PlanQualityResult, SimplifyMarker, TemporaryMarker, TemporaryMarkerResult, } from "./lint.js";
54
57
  export { assertSddTddTriple, findEphemeralCitations, findSimplifyMarkers, findTemporaryMarkers, lintSkillFrontmatter, lintStrategySections, planQualityBar, } from "./lint.js";
55
58
  export type { DevTrackParam, QcReviewerParam, RoleFamily, RoleMappingEntry, RoleMappingOptions, } from "./roles.js";
@@ -58,3 +61,5 @@ export type { DetectResult, HostAdapter, HostId, SkillRootPaths, ToolSignal } fr
58
61
  export { detectHost, resolveSkillRoot } from "./host.js";
59
62
  export type { FiveQuestionMode, FiveQuestionSection } from "./skill-authoring.js";
60
63
  export { FIVE_QUESTION_SECTIONS, RUNTIME_HEADING_ALIASES, lintFiveQuestion, lintFrontmatter, resolveAssetPath, stripFrontmatter, } from "./skill-authoring.js";
64
+ export type { MergeClass, PrReportTarget, PrReviewSeatPromptOptions, PrReviewSizing, PrReviewTier, PrTierKeyword, PrSizeBand, PrTallyInput, PrTallyResult, PrVerdict, ResolvePrReviewTierInput, ReviewChangesetMode, ReviewInlineComment, ReviewPostPlan, ValidateFindingDocOptions, } from "./prreview.js";
65
+ export { MERGE_CLASSES, PR_VERDICTS, REVIEW_EMOJI, computePrTally, pickReviewBranchName, planReviewPost, preflightChangeset, prReviewReportPath, prReviewSeatPrompt, prReviewSizing, resolvePrReviewTier, validateFindingDoc, validatePrReviewReport, } from "./prreview.js";
package/dist/project.d.ts CHANGED
@@ -100,6 +100,63 @@ export declare function validateRoadmap(filePath: string): RoadmapValidation;
100
100
  * `lifecycle_id`.
101
101
  */
102
102
  export declare function validateProjectRegister(doc: unknown): GateResult;
103
+ /** Options for `appendProjectRegisterEntries` (plan 20260826-backlog-register-cli Task 1 + B-9). */
104
+ export type AppendProjectRegisterEntriesOpts = {
105
+ /** Absolute path to the per-project directory (`<harness>/projects/<id>`; `_default` for project-less flows). */
106
+ projectDir: string;
107
+ /**
108
+ * Base entries key (`<plan-id>`), e.g. `pr-deep-review-2026-08-26`. The
109
+ * first free same-day key (`basePlanKey`, `basePlanKey-2`, `-3`, …) is
110
+ * selected INSIDE the status write lock — a caller-computed key would be a
111
+ * cross-lock TOCTOU (B-9 correction ①).
112
+ */
113
+ basePlanKey: string;
114
+ /** Residual entries to append — nine required fields + provenance. `source_plan` is overwritten with the used key; `registered_at` is required and must be set by the caller. */
115
+ entries: ResidualEntry[];
116
+ };
117
+ /** Options for `closeProjectRegisterEntry` (plan 20260826-backlog-register-cli Task 1). */
118
+ export type CloseProjectRegisterEntryOpts = {
119
+ /** Absolute path to the per-project directory (`<harness>/projects/<id>`; `_default` for project-less flows). */
120
+ projectDir: string;
121
+ /** Entries key (`<plan-id>`) holding the entry to close. */
122
+ planKey: string;
123
+ /** `id` of the entry to close (absent → throw). */
124
+ entryId: string;
125
+ /** Closure note written verbatim; `closed_at` is today's local date. */
126
+ closureNote: string;
127
+ };
128
+ /**
129
+ * Append residual entries to a project register (plan 20260826-backlog-register-cli
130
+ * Task 1 + B-9): resolve `<projectDir>/residuals.json` and run the WHOLE
131
+ * critical section inside `withStatusWriteLock(registerPath, ...)` (lease.ts —
132
+ * the `<register dir>/.status-write.lockdir/` lock is reused, never
133
+ * reimplemented). Read the register (absent → empty doc), select the first
134
+ * free same-day key (`basePlanKey`, `basePlanKey-2`, `-3`, … — port of the
135
+ * python next-free-key loop, pr-review.md) INSIDE the lock, validate every
136
+ * entry with `validateResidual`, enforce entry-id uniqueness within the
137
+ * selected key (B-9 correction ② — `validateProjectRegister` has no
138
+ * duplicate-id detection), set each entry's `source_plan` to the used key
139
+ * (provenance must match the entries key; the caller cannot know the bumped
140
+ * key beforehand), append preserving every other key, validate the whole
141
+ * register with `validateProjectRegister`, then `writeJson` (atomic
142
+ * temp+rename — never `open(w)`). Fail-loud: any validation failure throws
143
+ * and the register is left untouched. Returns the key actually used.
144
+ */
145
+ export declare function appendProjectRegisterEntries(opts: AppendProjectRegisterEntriesOpts): Promise<{
146
+ ok: true;
147
+ key: string;
148
+ }>;
149
+ /**
150
+ * Close one project-register entry in place (plan 20260826-backlog-register-cli
151
+ * Task 1): under `withStatusWriteLock(registerPath, ...)`, find `entryId` in
152
+ * `entries[planKey]` (absent → throw), set `lifecycle: resolved` +
153
+ * `closed_at: <today YYYY-MM-DD>` + `closure_note`, validate the whole
154
+ * register with `validateProjectRegister`, then `writeJson` (atomic
155
+ * temp+rename). Fail-loud: an invalid register throws and nothing is written.
156
+ */
157
+ export declare function closeProjectRegisterEntry(opts: CloseProjectRegisterEntryOpts): Promise<{
158
+ ok: true;
159
+ }>;
103
160
  /**
104
161
  * Findings cleanup gate (status-and-residuals.md § Findings cleanup modes;
105
162
  * QC wave-1 W-D relocation — the input is the project register
@@ -0,0 +1,335 @@
1
+ import type { GateResult } from "./core.js";
2
+ /** Merge classes for accepted PR-review findings (pr-review.md § Merge class). */
3
+ export declare const MERGE_CLASSES: readonly ["must-fix", "should-fix", "nit"];
4
+ export type MergeClass = (typeof MERGE_CLASSES)[number];
5
+ /** The three PR-review verdict tokens (pr-review.md § Verdict synthesis). */
6
+ export declare const PR_VERDICTS: readonly ["ship it", "needs fixes", "blocked"];
7
+ export type PrVerdict = (typeof PR_VERDICTS)[number];
8
+ /**
9
+ * Emoji per merge class (+ the unverified bucket) — pr-review.md § Section
10
+ * emoji map: 🔴 must-fix · 🟠 should-fix · 🔵 nit · ❓ unverified.
11
+ */
12
+ export declare const REVIEW_EMOJI: Record<MergeClass | "unverified", string>;
13
+ /**
14
+ * Input to {@link computePrTally}. `findings` are the post-vet accepted
15
+ * findings only; `unverifiedCount` is the count of residual items under
16
+ * `- unverified:` (0 when absent / `none`); `unmetAc` is the leftover
17
+ * unmet acceptance criteria (not met, not cut) — each increments the tally
18
+ * (§ Linked-issue hygiene), it is not a fourth class and not a second
19
+ * finding.
20
+ */
21
+ export type PrTallyInput = {
22
+ /** Post-vet accepted findings only. */
23
+ findings: readonly {
24
+ mergeClass: MergeClass;
25
+ }[];
26
+ /** Count of residual `- unverified:` items; 0 default. */
27
+ unverifiedCount?: number;
28
+ /** Leftover unmet ACs (not met, not cut). */
29
+ unmetAc?: readonly {
30
+ unsafeToShip: boolean;
31
+ }[];
32
+ };
33
+ /** Result of {@link computePrTally}. */
34
+ export type PrTallyResult = {
35
+ verdict: PrVerdict;
36
+ /** `max(0, 100 - 40*mustFix - 15*shouldFix - 3*nit - 10*unverified)`, integer, floor 0. */
37
+ scorePct: number;
38
+ tally: {
39
+ mustFix: number;
40
+ shouldFix: number;
41
+ nit: number;
42
+ unverified: number;
43
+ };
44
+ /** Two-line chat display header, verbatim per pr-review.md § Display contract. */
45
+ chatHeader: string;
46
+ };
47
+ /**
48
+ * Compute the PR-review tally, score and verdict from accepted findings,
49
+ * leftover unmet ACs and unverified residuals (pr-review.md § Tally and
50
+ * derived score — formula semantics verbatim, SSOT immutable).
51
+ *
52
+ * Leftover unmet ACs increment the tally (unsafe-to-ship → must_fix + 1,
53
+ * else should_fix + 1) BEFORE verdict derivation, so they cannot yield
54
+ * `ship it`. Verdict precedence: any must_fix ≥ 1 → `blocked`; else any
55
+ * should_fix ≥ 1 → `needs fixes`; else `ship it`. The score is computed but
56
+ * never overrides the verdict (override invariant).
57
+ */
58
+ export declare function computePrTally(input: PrTallyInput): PrTallyResult;
59
+ /**
60
+ * Which reviewed artifact the report (or evidence file) belongs to.
61
+ *
62
+ * - `pr` — reviewed PR number `n`.
63
+ * - `branch` — bare branch, `slug` is the pre-slugged `<branch-slug>`
64
+ * (caller slugs; the resolver only guards path safety).
65
+ * - `diff` — arbitrary changeset. When `headSha` is a non-empty string its
66
+ * short form (first 7 hex chars) lands in the filename; when absent or an
67
+ * empty string the bare `-diff` stem is used — a missing SHA is **never
68
+ * fabricated** (pr-review.md § Local report archive, Filename bullet).
69
+ */
70
+ export type PrReportTarget = {
71
+ kind: "pr";
72
+ n: number;
73
+ } | {
74
+ kind: "branch";
75
+ slug: string;
76
+ } | {
77
+ kind: "diff";
78
+ headSha?: string;
79
+ };
80
+ /**
81
+ * Resolve the local-report (or evidence-file) path for a reviewed target
82
+ * (pr-review.md § Local report archive — naming rules verbatim, pure read,
83
+ * never writes and never overwrites):
84
+ *
85
+ * - `<YYYY-MM-DD>-pr<N>.md` for PR targets; bare branch →
86
+ * `<YYYY-MM-DD>-<branch-slug>.md`; diff with head SHA →
87
+ * `<YYYY-MM-DD>-diff-<short-head-sha>.md`; diff without →
88
+ * `<YYYY-MM-DD>-diff.md` (never fabricate a SHA).
89
+ * - `stage: 1 | 2` requires `slug` (the seat Assignment's `<domain>-<seat>`
90
+ * slug) and produces the Stage 1/2 evidence-file stem
91
+ * `<stem>-stage<1|2>-<slug>.md`.
92
+ * - Same day, same target (same final stem): scans ALL existing files in
93
+ * `reportsDir` with that stem and appends `-r2`, `-r3`, ... on collision —
94
+ * a prior report is never overwritten. Report files and evidence files
95
+ * escalate independently (different stems).
96
+ * - `date` defaults to the local calendar date and must be `YYYY-MM-DD`.
97
+ */
98
+ export declare function prReviewReportPath(opts: {
99
+ reportsDir: string;
100
+ date?: string;
101
+ target: PrReportTarget;
102
+ stage?: 1 | 2;
103
+ slug?: string;
104
+ }): string;
105
+ /**
106
+ * Validate a saved local PR-review report against the machine-readable
107
+ * contract (pr-review.md § Local report archive Frontmatter + § Output
108
+ * shape tri-states, semantics verbatim):
109
+ *
110
+ * - `type: pr-review` required.
111
+ * - `verdict` exactly one of the three verdict tokens (§ Verdict synthesis)
112
+ * and CONSISTENT with the tally (any must_fix -> blocked; else any
113
+ * should_fix -> needs fixes; else ship it).
114
+ * - `score_pct` integer 0-100 and equal to the locked-formula recompute
115
+ * from the document's own tally via {@link computePrTally}
116
+ * (mismatch = hand-arithmetic drift — the exact defect class this gate
117
+ * exists to catch).
118
+ * - `tally` flow map with the four classes.
119
+ * - `comments` tri-state: `posted` (alias `yes`) | `n/a-no-pr` | `failed`.
120
+ * The states are distinct: a FAILED POST IS `FAILED`, never
121
+ * `n/a-no-pr`; `review_url` must pair accordingly (`http(s)://` for
122
+ * posted, `n/a` for n/a-no-pr, a `failed: <gh error summary>` for failed).
123
+ * - `generated_at` must be `YYYY-MM-DD` (DATE_RE).
124
+ * - `tier` optional: `quick | default | deep`; absent is valid (legacy
125
+ * reports without tier still pass — SP-A amendment).
126
+ */
127
+ export declare function validatePrReviewReport(text: string): GateResult;
128
+ /** One inline review comment: `path` + `line` in the three-dot diff, RIGHT
129
+ * side only (§ Comment posting step 2 — comments[] entry shape). */
130
+ export type ReviewInlineComment = {
131
+ path: string;
132
+ line: number;
133
+ side: "RIGHT";
134
+ body: string;
135
+ };
136
+ /**
137
+ * The POST payload for the Reviews API (step 2 built here, step 3
138
+ * executed by the CLI). `event` is the literal `"COMMENT"` — APPROVE /
139
+ * REQUEST_CHANGES are not representable in this type (SSOT:
140
+ * never approve-as-merge).
141
+ */
142
+ export type ReviewPostPlan = {
143
+ ownerRepo: string;
144
+ pr: number;
145
+ /** PR head SHA — the Reviews API `commit_id`. */
146
+ commitId: string;
147
+ event: "COMMENT";
148
+ body: string;
149
+ inlineComments: readonly ReviewInlineComment[];
150
+ };
151
+ /**
152
+ * Build the deterministic part of the GitHub Review POST (pr-review.md §
153
+ * Comment posting Procedure steps 1-2; step 3's POST + the at-most-once
154
+ * 422 fallback stay with the CLI, which owns the network):
155
+ *
156
+ * - Resolves the target from `gh pr view --json url,headRefOid` output:
157
+ * parse `owner/repo` from `url` ONLY — the BASE repo that owns the PR
158
+ * number. `headRepository` (fork head-repo data) is IGNORED: fork PRs
159
+ * are legal, and a fork's owner/name must never leak into the API path.
160
+ * It is never used as a fallback either.
161
+ * - Missing/invalid `headRefOid` throws — there is no commit_id without
162
+ * it.
163
+ * - `event` is always the literal `"COMMENT"`; no other value exists in
164
+ * this contract.
165
+ * - Inline comments validated per-entry (path / positive line / RIGHT).
166
+ */
167
+ export declare function planReviewPost(prView: {
168
+ url?: string;
169
+ headRepository?: unknown;
170
+ headRefOid?: string;
171
+ }, payload: {
172
+ body: string;
173
+ comments?: readonly ReviewInlineComment[];
174
+ }): ReviewPostPlan;
175
+ /**
176
+ * Pick a collision-free local review branch name BEFORE any fetch
177
+ * (pr-review.md § Worktree isolation): `pr-<n>` first; when occupied,
178
+ * loop `pr-<n>-<date>-<i>` with i = 1, 2, ... until an unoccupied name is
179
+ * found and return it. `existing` holds already-taken branch names; this
180
+ * function is pure — it never probes git itself.
181
+ */
182
+ export declare function pickReviewBranchName(existing: ReadonlySet<string>, pr: number, today: string): string;
183
+ /** Input-mode matrix for the review changeset (pr-review.md § Worktree
184
+ * isolation input modes). Modes with named refs gate on ref resolution;
185
+ * working-tree counts untracked-only as a changeset. */
186
+ export type ReviewChangesetMode = "pr" | "branch" | "diff" | "working-tree" | "commit";
187
+ /**
188
+ * Pre-flight gate over the probe results of a resolved review changeset
189
+ * (pr-review.md § Worktree isolation Pre-flight bullet, all modes):
190
+ *
191
+ * - Named refs must resolve in modes that HAVE refs (pr / branch / commit);
192
+ * establish them with explicit refspecs first.
193
+ * - The changeset must be NON-empty in ALL modes — an empty changeset
194
+ * reports "no changes to review" and stops before any lens fan-out.
195
+ * - For working-tree input, untracked-only changes ARE a non-empty
196
+ * changeset: the caller folds `git ls-files --others
197
+ * --exclude-standard` output into `changesetEmpty: false` when anything
198
+ * is listed.
199
+ */
200
+ export declare function preflightChangeset(mode: ReviewChangesetMode, probe: {
201
+ refsResolve: boolean;
202
+ changesetEmpty: boolean;
203
+ }): GateResult;
204
+ /** Sizing bands (~100 / ~300 / ~1000), reused across tiers — no second
205
+ * set of numbers (pr-review.md § Sizing & change shape; § Review depth). */
206
+ export type PrSizeBand = "small" | "large" | "too-large";
207
+ /** Sizing result: band + derived seat plan and advisories. */
208
+ export type PrReviewSizing = {
209
+ band: PrSizeBand;
210
+ /** True for too-large (>~1000) — advise a split, never auto-blocked. */
211
+ adviseSplit: boolean;
212
+ /** Stage 1 collect seats (§ Scale-driven fan-out table). */
213
+ collectSeats: 2 | 3;
214
+ /** File-size watch fired → advise extract/decompose ("decompose, then
215
+ * add"). Independent of the diff size. */
216
+ fileDecomposeAdvice: boolean;
217
+ };
218
+ /**
219
+ * Classify a changeset into the sizing bands and derive the fan-out plan
220
+ * (pr-review.md § Sizing & change shape + § Scale-driven fan-out):
221
+ *
222
+ * - ≤~300 reviewable/acceptable → band `small`; >~300 → `large`;
223
+ * >~1000 → `too-large` + split advice (a should-fix finding with split
224
+ * advice or a verdict note — never auto-`blocked`).
225
+ * - Stage 1 collect seats: small → 2 (code + security); large/too-large →
226
+ * 3 by domain.
227
+ * - `largestTouchedFileTotal` drives `fileDecomposeAdvice` INDEPENDENTLY
228
+ * of the diff size — a small diff materially growing a file past ~1000
229
+ * total lines gets "decompose, then add".
230
+ */
231
+ export declare function prReviewSizing(input: {
232
+ changedLines: number;
233
+ largestTouchedFileTotal?: number;
234
+ }): PrReviewSizing;
235
+ /** Seat prompt tier (SP-A amendment): quick omits the cross-domain /
236
+ * independent-security-seat block, the collect-wave wording AND shrinks
237
+ * the lens/prompt-ingredient set; default also omits both (SSOT pr-review.md
238
+ * § Review depth: default "folds collection in = seat reuse", no separate
239
+ * Stage-1 wave — collect-wave wording is deep-only); deep includes everything. */
240
+ export type PrReviewTier = "quick" | "default" | "deep";
241
+ /** Options for {@link prReviewSeatPrompt}. */
242
+ export type PrReviewSeatPromptOptions = {
243
+ stage: 1 | 2;
244
+ domain: string;
245
+ seat: string;
246
+ skillRoot: string;
247
+ worktreePath: string;
248
+ reconFacts: readonly string[];
249
+ decidedTradeoffs?: readonly string[];
250
+ securitySeat?: boolean;
251
+ tier?: PrReviewTier;
252
+ };
253
+ /**
254
+ * Generate the read-only audit-seat prompt for one Stage 1 collect or
255
+ * Stage 2 domain/security seat (pr-review.md § Review pipeline Seat
256
+ * prompts + § Fan-out discipline; full-audit mirror codebase-audit.md).
257
+ * Ingredients:
258
+ *
259
+ * - Absolute path to `references/pr-review.md` under `skillRoot` + the
260
+ * sections to read; absolute review `worktreePath`.
261
+ * - Recon facts + decided tradeoffs.
262
+ * - Hard Rules 4/5 VERBATIM.
263
+ * - Payload-return contract (write-blocked-safe; main agent writes files).
264
+ * - No-verdict / never-post clauses.
265
+ * - Slug mandate `<domain>-<seat>`.
266
+ * - Stage 2 adds finding-format.md (+ security-review.md for security
267
+ * seats) and the Merge-class instruction.
268
+ * - Tier cuts (SP-A amendment): quick drops the cross-domain /
269
+ * independent-security block, the collect-wave wording AND shrinks the
270
+ * lens/prompt-ingredient set; default drops the same blocks (SSOT
271
+ * pr-review.md § Review depth: default "folds collection in = seat
272
+ * reuse" — no separate Stage-1 wave, so collect-wave wording is
273
+ * deep-only); deep keeps everything.
274
+ * Tier omitted → `default` (pr-review.md § Review depth: the no-flag
275
+ * landing tier).
276
+ */
277
+ export declare function prReviewSeatPrompt(opts: PrReviewSeatPromptOptions): string;
278
+ /** Options for {@link validateFindingDoc}: `prVariant` gates the Merge
279
+ * class requirements (presence + enum + placement after Confidence). */
280
+ export type ValidateFindingDocOptions = {
281
+ prVariant?: boolean;
282
+ };
283
+ /**
284
+ * Machine-lint one or more findings in the finding-format template shape
285
+ * (skills/mstar-audit/references/finding-format.md § Template) plus the
286
+ * PR-only Merge class contract (pr-review.md § Merge class):
287
+ *
288
+ * - Every finding opens with `### [CATEGORY-NN] Title`; CATEGORY ∈
289
+ * `AUDIT_CATEGORIES` (case-insensitive read, canonical uppercase forms
290
+ * per category codes), NN numeric.
291
+ * - Required fields: Evidence / Impact / Effort / Risk / Confidence —
292
+ * Effort / Risk / Confidence each validated as their LEADING token
293
+ * (Effort via `AUDIT_EFFORTS`, Risk via `AUDIT_RISKS`, Confidence via
294
+ * HIGH | MED | LOW with `MEDIUM` tolerated as the MED alias); free-text
295
+ * gloss after a separator is allowed and ignored.
296
+ * - Each Evidence citation matches `path:line` (`\S+:\d+` — the path may
297
+ * but need not carry an extension).
298
+ * - `prVariant` (default false): every finding additionally carries
299
+ * **Merge class** ∈ {must-fix, should-fix, nit} placed IMMEDIATELY after
300
+ * Confidence.
301
+ */
302
+ export declare function validateFindingDoc(text: string, opts?: ValidateFindingDocOptions): GateResult;
303
+ /** Tier keywords the CLI may have matched from argv — the three explicit
304
+ * tokens (`--quick` / `--default` / `--deep`) alike. */
305
+ export type PrTierKeyword = "quick" | "default" | "deep";
306
+ /** Inference-ladder input for {@link resolvePrReviewTier}. `keywords`
307
+ * carries EVERY explicit tier token matched on argv (deduplicated);
308
+ * ANY TWO distinct keywords → hard-stop conflict error (§ Review depth
309
+ * Conflict rule: at most ONE tier keyword among quick / default / deep —
310
+ * never silently take a priority). Empty/omitted = no flag, full ladder
311
+ * runs. */
312
+ export type ResolvePrReviewTierInput = {
313
+ keywords?: readonly PrTierKeyword[];
314
+ band: PrSizeBand;
315
+ sensitiveSurface?: boolean;
316
+ tinyMechanical?: boolean;
317
+ };
318
+ /**
319
+ * The deterministic part of pr-review.md § Review depth Inference ladder
320
+ * (SP-A amendment; first hit wins):
321
+ *
322
+ * 1. Explicit keyword → that tier (user intent beats heuristics; a lone
323
+ * `default` returns `default` BEFORE the band/sensitive heuristics).
324
+ * Any two DISTINCT keywords (quick / default / deep) → hard-stop
325
+ * conflict error — never silently take a priority. (Empty/omitted =
326
+ * no flag.)
327
+ * 2. Too large (>~1000 / band too-large) → advise split; review anyway →
328
+ * deep.
329
+ * 3. Sensitive surface (auth / LLM / supply chain / data) → deep at any
330
+ * size.
331
+ * 4. Large (>~300 / band large) → deep.
332
+ * 5. Small: tiny-mechanical shape (docs-only / rename / formatting / pure
333
+ * deletion) → quick; anything else (real code change) → default.
334
+ */
335
+ export declare function resolvePrReviewTier(input: ResolvePrReviewTierInput): PrReviewTier;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstar-harness/engine",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "Morning Star Harness Workflow Engine — deterministic workflow enforcement library (path, status, lease, dispatch, sdd, iteration, lint gates).",
5
5
  "license": "MIT",
6
6
  "repository": {