@mstar-harness/engine 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit.d.ts +110 -1
- package/dist/audit.js +345 -15
- package/dist/dispatch.d.ts +37 -18
- package/dist/engine.js +1141 -78
- package/dist/index.d.ts +11 -6
- package/dist/project.d.ts +57 -0
- package/dist/prreview.d.ts +335 -0
- package/package.json +1 -1
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, `
|
|
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
|
+
"version": "3.4.1",
|
|
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": {
|