@mstar-harness/engine 3.6.3 → 3.7.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.
@@ -0,0 +1,69 @@
1
+ import { type ValidationResult } from "./core.js";
2
+ /** Target paths from a write/edit event: `input.path` (string) plus `input.paths` (array). */
3
+ export declare function eventTargetPaths(input: unknown): string[];
4
+ /** Gated harness coordination documents in v3 (compass ruling 7 — hard
5
+ * cutover): the root `status.json` (v2), workflow snapshots
6
+ * (`workflows/<id>/snapshot.json`) and project registers
7
+ * (`projects/<id>/residuals.json`). Each kind maps to its engine
8
+ * validator; everything else is not a gated coordination write. */
9
+ export type HarnessDocKind = "status" | "snapshot" | "register";
10
+ /**
11
+ * Classify `targetPath` as a canonical `{HARNESS_DIR}` coordination
12
+ * document: basename is `status.json` at the harness root, `snapshot.json`
13
+ * under `{WORKFLOW_DIR}/<id>/`, or `residuals.json` under
14
+ * `{PROJECT_DIR}/<id>/` (harness-relative, one path component each), AND
15
+ * the harness root resolves — marker probe first (custom-layout-aware
16
+ * Phase-5 F1), `resolveHarnessDir` as the declared-root fallback. The
17
+ * snapshot/register rel is computed against the RESOLVED layout dirs
18
+ * (`.mstarc` `workflow_dir`/`project_dir` honored, defaults
19
+ * `workflows`/`projects`), so a custom layout classifies at the same
20
+ * location the runtime writes. Everything else is not a gated write.
21
+ * Returns the harness dir + doc kind when gated.
22
+ */
23
+ export declare function harnessDocKindOfTarget(targetPath: string): {
24
+ harnessDir: string;
25
+ kind: HarnessDocKind;
26
+ } | null;
27
+ export declare function violationLine(violation: ValidationResult): string;
28
+ /**
29
+ * Size guard: content strings beyond ~2MB are skipped without
30
+ * parsing — a pathologically large write must not approach a host's
31
+ * handler timeout (which fails CLOSED even in soft mode). The oversized
32
+ * write passes silently; documented in the host gate contract.
33
+ */
34
+ export declare const MAX_STATUS_CONTENT_LENGTH: number;
35
+ /**
36
+ * Options for {@link validateStatusWriteDoc}.
37
+ */
38
+ export interface ValidateStatusWriteDocOptions {
39
+ /**
40
+ * Behavior when the content (string form) or the on-disk gated document
41
+ * (edit form) exceeds `MAX_STATUS_CONTENT_LENGTH`. `"pass"` (default)
42
+ * keeps the documented silent-pass degradation; `"violate"` reports a
43
+ * `status.oversized` violation instead — for hosts whose block dialect
44
+ * makes the oversized write an enforceable refusal rather than a
45
+ * permission (the size check stays O(1), before any parse).
46
+ */
47
+ oversized?: "pass" | "violate";
48
+ }
49
+ /**
50
+ * Validate the document being written to a gated harness coordination
51
+ * document. `content` as a string is the new document: JSON.parse it
52
+ * and run the matching engine validator on the parsed doc — a parse failure
53
+ * is a violation (`status.invalid-json`, the same code/message shape the
54
+ * engine emits for an unparseable file). Parsed `null` / non-object / array
55
+ * content is a `status.invalid-json` violation too (the JSON
56
+ * literal `null` would otherwise slip through `validateStatus`'s
57
+ * destructuring into the outer catch's silent pass). Without a content
58
+ * string (edit-style events) the on-disk file is validated — unless it does
59
+ * not exist yet (fresh scaffold/init write): nothing to validate, silent
60
+ * pass. Never throws (the validators catch their own read errors).
61
+ */
62
+ export declare function validateStatusWriteDoc(content: unknown, filePath: string, kind: HarnessDocKind, options?: ValidateStatusWriteDocOptions): ValidationResult[];
63
+ /**
64
+ * Format the gate block reason: one `violationLine` per violation, each
65
+ * suffixed with the host's skill pointer (omp/ZCode parity: both hosts
66
+ * pass `skill: mstar-artifacts/references/status-and-residuals.md`),
67
+ * joined with newlines.
68
+ */
69
+ export declare function formatStatusWriteBlockReason(violations: ValidationResult[], skillPointer: string): string;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -20,15 +20,18 @@
20
20
  * constants (mstar-audit pr-review.md § Tally and derived score), `host`
21
21
  * detects the active
22
22
  * host from tool shapes, resolves skill roots and defines the type-only
23
- * `HostAdapter` contract, and `skill-authoring` lints frontmatter +
23
+ * `HostAdapter` contract, `gates` is the host-neutral coordination-write
24
+ * gate core (target classification + content/edit validation + reason
25
+ * formatting, shared by the omp and ZCode host gates), and `skill-authoring`
26
+ * lints frontmatter +
24
27
  * 5-question bodies and resolves skill-relative asset paths.
25
28
  */
26
29
  export type { GateResult, Severity, ValidationResult } from "./core.js";
27
30
  export { SEVERITY_ORDER, applyEnforcement, readHarnessVersion, readJson, resolveProjectRoot, writeJson } from "./core.js";
28
- export type { HarnessKind, ResolveHarnessDirOptions, ResolveSpecsDirOptions } from "./path.js";
31
+ export type { HarnessKind, ResolveHarnessDirOptions, ResolveSpecsDirOptions, } from "./path.js";
29
32
  export type { MstarcConfig } from "./mstarc.js";
30
33
  export { MSTARC_FILE, MSTARC_HARNESS_DIR_KEY, MSTARC_PROJECT_DIR_KEY, MSTARC_SECTION, MSTARC_WORKFLOW_DIR_KEY, findMstarc, parseMstarc, } from "./mstarc.js";
31
- export { assertPlanWritingPath, detectHarnessKind, emitGitignoreSnippet, resolveHarnessDir, resolveIterationDir, resolveKnowledgeDir, resolvePlanDir, resolveProjectDir, resolveScaffoldDirs, resolveSddDir, resolveSpecsDir, resolveWorkflowDir, scaffoldHarness, validateGitignore, } from "./path.js";
34
+ export { assertPlanWritingPath, canonicalizeNearestExisting, detectHarnessKind, emitGitignoreSnippet, resolveHarnessDir, resolveIterationDir, resolveKnowledgeDir, resolvePlanDir, resolveProjectDir, resolveScaffoldDirs, resolveSddDir, resolveSpecsDir, resolveWorkflowDir, scaffoldHarness, validateGitignore, } from "./path.js";
32
35
  export type { PlanRow, ResidualEntry, StatusDoc, StatusV2Doc, WorkflowEntry, } from "./status.js";
33
36
  export { normalizeSeverity, registerWorkflow, resolveCompassEnforcement, resolveMstarcEnforcement, resolveRepoEnforcement, unregisterWorkflow, validatePlanRow, validateResidual, validateStatus, validateStatusV2, validateWorkflowEntry, } from "./status.js";
34
37
  export type { ClaimLeaseFields, ExecutionLease, ExecutionLeaseLocations, IntegrationMergeLease, LeaseTransition, LeaseVerifyResult, } from "./lease.js";
@@ -38,13 +41,15 @@ export { WORKFLOW_LIFECYCLE_STATUSES, WORKFLOW_LIFECYCLE_TYPES, WORKFLOW_SNAPSHO
38
41
  export type { AssignmentBranchForms, AssignmentFields, ComposeDispatchGateOptions, ComposeDispatchGateResult, DefaultBranchOptions, EnforcementFlag, EnforcementSource, ExecutionModeToNOptions, ExecutionModeToNResult, ValidateAssignmentFieldsOptions, } from "./dispatch.js";
39
42
  export { antiRecursionPrecheck, assertDefaultBranchProtected, assertTriIdentity, assignmentHeaderRegion, composeDispatchGate, executionModeToN, isReadOnlyAssignmentRole, parseAssignmentBranchForms, parseAssignmentFields, parseBranchPolicyDirectOnBranch, parseEnforcementFlag, validateAssignmentFields, } from "./dispatch.js";
40
43
  export type { BranchProbeOptions, L1PreDispatchInput, L2PreDispatchInput, QcAlignmentAssignment, QcSnapshotAssignment, WorktreeTrack, } from "./worktree.js";
41
- export { assertBranchAlignment, assertControlVsFeaturePath, assertQcAlignment, l1PreDispatchCheck, l2PreDispatchCheck, singleReviewSnapshot, } from "./worktree.js";
42
- export type { ImplementerSessionLedger, ReviewPackageOptions, SddWorkspaceOptions, StickyRulesInput, StickyRulesResult, TaskBriefOptions, } from "./sdd.js";
43
- export { GIT_CAPTURE_MAX_BYTES, SddScriptError, assertBaseSha, implementerSessionStickyRules, readProgressLedger, reviewPackage, sddWorkspace, taskBrief, taskReportExists, } from "./sdd.js";
44
+ export { assertBranchAlignment, assertControlVsFeaturePath, assertQcAlignment, isDistinctCheckout, l1PreDispatchCheck, l2PreDispatchCheck, probeCheckoutRoot, singleReviewSnapshot, } from "./worktree.js";
45
+ export type { ImplementerSessionLedger, ReviewPackageOptions, SddAction, SddActionKind, SddExecutionContext, SddWorkspaceOptions, StickyRulesInput, StickyRulesResult, TaskBriefOptions, } from "./sdd.js";
46
+ export { GIT_CAPTURE_MAX_BYTES, SddScriptError, assertBaseSha, checkSddAction, implementerSessionStickyRules, readProgressLedger, resolveSddExecutionContext, reviewPackage, runInSddContext, sddWorkspace, taskBrief, taskReportExists, } from "./sdd.js";
44
47
  export type { CompassDoc, PhaseGateOptions, PhaseGateResult, PhaseTransition, } from "./iteration.js";
45
48
  export { assertIndexRowObligations, evaluatePhaseGate, parseCompassFrontmatter, parseCompassFrontmatterText, pushCadenceProbe, validateCompassFrontmatter, } from "./iteration.js";
46
49
  export type { AppendProjectRegisterEntriesOpts, CloseProjectRegisterEntryOpts, FindingsCleanupMode, ProjectRegisterDoc, ProjectRegisterEntry, RoadmapFrontmatter, RoadmapStatus, RoadmapValidation, TechDebtCheck, TechDebtRollup, TechDebtSummary, } from "./project.js";
47
50
  export { PROJECT_REFERENCES_DIR, PROJECT_REGISTER_FILE, PROJECT_ROADMAP_FILE, ROADMAP_STATUSES, _DEFAULT_PROJECT, appendProjectRegisterEntries, closeProjectRegisterEntry, findingsCleanupGate, listProjectReferenceFiles, techDebtRollup, validateProjectRegister, validateRoadmap, } from "./project.js";
51
+ export type { HarnessDocKind, ValidateStatusWriteDocOptions } from "./gates.js";
52
+ export { MAX_STATUS_CONTENT_LENGTH, eventTargetPaths, formatStatusWriteBlockReason, harnessDocKindOfTarget, validateStatusWriteDoc, violationLine, } from "./gates.js";
48
53
  export type { MigrateNotesFile, MigrateOptions, MigratePlan, MigrateRegister, MigrateResult, MigrateRoadmap, MigrateRootV2, MigrateSnapshot, MigrateStep, } from "./migrate.js";
49
54
  export { ARCHIVED_STATUS_V1_FILE, MIGRATE_STATUS_FILE, NOTES_LEDGER_FILE, applyMigratePlan, migrateHarnessTree, } from "./migrate.js";
50
55
  export type { CompletenessItem, CompletenessLevel, CompletenessPlaceholder, CompletenessResult, DesignFrontmatter, } from "./design-md.js";
@@ -59,8 +64,8 @@ export type { DevTrackParam, QcReviewerParam, RoleFamily, RoleMappingEntry, Role
59
64
  export { DEV_TRACK_PARAMS, QC_REVIEWER_PARAMS, ROLE_MAPPING, SHARED_FAMILIES, lintLoadOrder, validateRoleMapping, } from "./roles.js";
60
65
  export type { DetectResult, HostAdapter, HostId, SkillRootPaths, ToolSignal } from "./host.js";
61
66
  export { detectHost, resolveSkillRoot } from "./host.js";
62
- export type { FiveQuestionMode, FiveQuestionSection } from "./skill-authoring.js";
63
- export { FIVE_QUESTION_SECTIONS, RUNTIME_HEADING_ALIASES, lintFiveQuestion, lintFrontmatter, resolveAssetPath, stripFrontmatter, } from "./skill-authoring.js";
67
+ export type { FiveQuestionMode, FiveQuestionSection, SkillLintKind, SkillLintProfile } from "./skill-authoring.js";
68
+ export { classifySkillLint, FIVE_QUESTION_SECTIONS, RUNTIME_HEADING_ALIASES, lintFiveQuestion, lintFrontmatter, resolveAssetPath, stripFrontmatter, } from "./skill-authoring.js";
64
69
  export type { MergeClass, MstarReviewFinding, MstarReviewV1, PrReportTarget, PrReviewSeatPromptOptions, PrReviewSizing, PrReviewTier, PrTierKeyword, PrSizeBand, PrTallyInput, PrTallyResult, PrVerdict, ResolvePrReviewTierInput, ReviewChangesetMode, ReviewInlineComment, ReviewPostPlan, ValidateFindingDocOptions, } from "./prreview.js";
65
70
  export { MERGE_CLASSES, PR_REVIEW_TIER_BUDGETS, PR_VERDICTS, REVIEW_EMOJI, computePrTally, pickReviewBranchName, planReviewPost, preflightChangeset, prReviewReportPath, prReviewSeatPrompt, prReviewSizing, resolvePrReviewTier, synthesizeReview, validateFindingDoc, validateMstarReviewV1, validatePrReviewReport, } from "./prreview.js";
66
71
  export type { ArtifactDoc, ArtifactKind, ArtifactRef, ArtifactStore } from "./store.js";
@@ -3,9 +3,9 @@ import type { GateResult, ValidationResult } from "./core.js";
3
3
  * Loose shape of a parsed workflow snapshot (`workflows/<id>/snapshot.json`).
4
4
  * All fields are `unknown` because documents come from JSON at runtime;
5
5
  * validators narrow them. `plans[]` rows are the legacy PlanRow shape
6
- * verbatim (plan Task 2) — `findPlanRow` accepts `id` or `plan_id`.
6
+ * verbatim () — `findPlanRow` accepts `id` or `plan_id`.
7
7
  *
8
- * Deliberate decoupling (qc wave-1 S-f): this is a loose LOCAL re-declaration,
8
+ * Deliberate decoupling: this is a loose LOCAL re-declaration,
9
9
  * NOT an import of `WorkflowSnapshot` from workflow.ts. This module only
10
10
  * reads `plans[].status`; importing the full schema would add a module edge
11
11
  * to workflow.ts (which imports status.ts, which workflow.ts cycles back
@@ -54,7 +54,7 @@ export type PhaseGateOptions = {
54
54
  * required; missing items listed in `violations`).
55
55
  * - all plans Done and both checklists clean → `phase-4-pr-delivery`.
56
56
  *
57
- * Note (qc2 F-003): during the Phase-3 window `ok` is false because the
57
+ * Note : during the Phase-3 window `ok` is false because the
58
58
  * §3.4 close items (`status: completed` + `end_date`) are only written at
59
59
  * the END of close — the exit checklist gates Phase 4, not the Phase-3
60
60
  * entry, so callers (e.g. the CLI, which exits 1) must treat that as "close
package/dist/lint.d.ts CHANGED
@@ -9,27 +9,27 @@
9
9
  *
10
10
  * Spec sources (each function cites the source section):
11
11
  * - simplify:/temporary markers: `mstar-coding-behavior` SKILL.md § Simplicity
12
- * First → "Simplification markers": a deliberate shortcut with a known
13
- * ceiling is marked with a `simplify:` comment naming the ceiling and the
14
- * upgrade path; a workaround is labeled `simplify:` / `temporary`, explains
15
- * why, and records the removal path in the plan/status artifact before the
16
- * task is claimed complete.
12
+ * First → "Simplification markers": a deliberate shortcut with a known
13
+ * ceiling is marked with a `simplify:` comment naming the ceiling and the
14
+ * upgrade path; a workaround is labeled `simplify:` / `temporary`, explains
15
+ * why, and records the removal path in the plan/status artifact before the
16
+ * task is claimed complete.
17
17
  * - SDD TDD triple: `mstar-coding-behavior` SKILL.md § Integration Notes —
18
- * completion evidence must include the TDD triple (test file(s), command,
19
- * output) in `task-N-report.md`; `mstar-sdd/references/file-handoffs.md` —
20
- * fix subagents append covering test file(s), command run, output.
18
+ * completion evidence must include the TDD triple (test file(s), command,
19
+ * output) in `task-N-report.md`; `mstar-sdd/references/file-handoffs.md` —
20
+ * fix subagents append covering test file(s), command run, output.
21
21
  * - Plan quality bar: `mstar-artifacts/references/plan-quality-bar.md`
22
- * § Quality checklist + `templates/plan.main.md` self-review
23
- * ("Placeholder scan: no TBD").
22
+ * § Quality checklist + `templates/plan.main.md` self-review
23
+ * ("Placeholder scan: no TBD").
24
24
  * - Skill frontmatter contract: `mstar-skill-authoring` SKILL.md § Frontmatter
25
- * Contract — `name` stable lowercase-hyphen; `description` is the trigger
26
- * contract (not a workflow summary), third person.
25
+ * Contract — `name` stable lowercase-hyphen; `description` is the trigger
26
+ * contract (not a workflow summary), third person.
27
27
  * - STRATEGY.md structure: `mstar-strategy` SKILL.md § STRATEGY.md structure —
28
- * six required sections.
28
+ * six required sections.
29
29
  * - Ephemeral citations: knowledge `conventions/skill-content-porting-discipline.md`
30
- * §3 ("No ephemeral citations in durable skill text") + session evaluation
31
- * 2026-08-16 discrimination contract — concrete task-artifact references
32
- * and SDD deeplinks are ephemeral; placeholder forms are not.
30
+ * §3 ("No ephemeral citations in durable skill text") + session evaluation
31
+ * 2026-08-16 discrimination contract — concrete task-artifact references
32
+ * and SDD deeplinks are ephemeral; placeholder forms are not.
33
33
  *
34
34
  * Enforcement depth: roadmap §8.5 C4 — v1 lints are non-blocking
35
35
  * `ValidationResult`s; callers surface them as warnings.
@@ -112,8 +112,8 @@ export type EphemeralCitation = {
112
112
  /** The matched citation token (artifact name or deeplink prefix). */
113
113
  match: string;
114
114
  /** `task-artifact`: `task-<digits>-(brief|report|fix-report|diff)`;
115
- * `sdd-deeplink`: `.mstar/sdd/` / `.agents/sdd/` + a concrete first
116
- * segment. */
115
+ * `sdd-deeplink`: `.mstar/sdd/` / `.agents/sdd/` + a concrete first
116
+ * segment. */
117
117
  kind: "task-artifact" | "sdd-deeplink";
118
118
  };
119
119
  /**
@@ -123,12 +123,12 @@ export type EphemeralCitation = {
123
123
  *
124
124
  * Discrimination (HARD — zero false positives on the skills corpus):
125
125
  * - `task-<digits>-(brief|report|fix-report|diff)` with 1+ digits is a
126
- * concrete instance → reported (`task-2-report`, `task-1.diff`).
127
- * Placeholders (`task-N-brief`, `task-N-report`, `<plan-id>`,
128
- * `{SDD_DIR}/task-N-report.md`) never match.
126
+ * concrete instance → reported (`task-2-report`, `task-1.diff`).
127
+ * Placeholders (`task-N-brief`, `task-N-report`, `<plan-id>`,
128
+ * `{SDD_DIR}/task-N-report.md`) never match.
129
129
  * - `.mstar/sdd/<segment>` / `.agents/sdd/<segment>` with a concrete first
130
- * segment (`20260815-x`) → reported; `<plan-id>` / `{SDD_DIR}` segments
131
- * are template forms → never match.
130
+ * segment (`20260815-x`) → reported; `<plan-id>` / `{SDD_DIR}` segments
131
+ * are template forms → never match.
132
132
  *
133
133
  * Discovery only — a finder returning an array, same shape as
134
134
  * `findSimplifyMarkers`, NOT a GateResult; callers wrap findings into
@@ -151,17 +151,17 @@ export declare function findEphemeralCitations(skillText: string): EphemeralCita
151
151
  *
152
152
  * Heuristics (documented, conservative — tuned so prose alone never counts):
153
153
  * - tests: a `.test.<ext>` / `.spec.<ext>` path, or the phrase "test file(s)"
154
- * (the handoff template's exact header). "I added tests" without a file or
155
- * the phrase does not count.
154
+ * (the handoff template's exact header). "I added tests" without a file or
155
+ * the phrase does not count.
156
156
  * - command: a `$`-prefixed line, or a known runner invocation (bun/pnpm/
157
- * npm/yarn/npx/bunx test|run|exec, npx/bunx exec, tsc/vitest/jest/mocha/
158
- * pytest/go test/cargo test). Prose "run the tests" names no runner and
159
- * does not count (plan-quality-bar marks it a weak step anyway).
157
+ * npm/yarn/npx/bunx test|run|exec, npx/bunx exec, tsc/vitest/jest/mocha/
158
+ * pytest/go test/cargo test). Prose "run the tests" names no runner and
159
+ * does not count (plan-quality-bar marks it a weak step anyway).
160
160
  * - output: check marks, PASS/FAIL tokens, counts ("12 pass"), `N ok` /
161
- * TAP `ok N` / "all ok" verdicts, exit-code statements. Bare prose
162
- * `OK`/`ERROR` ("OK, moving on") does NOT count — output evidence must
163
- * look like output. Line-based and fence-insensitive: real output usually
164
- * lives in fenced blocks, so fence content is scanned too.
161
+ * TAP `ok N` / "all ok" verdicts, exit-code statements. Bare prose
162
+ * `OK`/`ERROR` ("OK, moving on") does NOT count — output evidence must
163
+ * look like output. Line-based and fence-insensitive: real output usually
164
+ * lives in fenced blocks, so fence content is scanned too.
165
165
  */
166
166
  export declare function assertSddTddTriple(reportText: string): GateResult;
167
167
  /**
@@ -188,16 +188,16 @@ export type PlanQualityResult = GateResult & {
188
188
  *
189
189
  * Heuristic (documented, conservative):
190
190
  * - tokens: `TBD`, `TODO`, `TBA` (case-insensitive, word-boundary, plural
191
- * forms included) and the prose ellipsis `...`. One finding per line per
192
- * token (a line with two TBDs yields one finding).
191
+ * forms included) and the prose ellipsis `...`. One finding per line per
192
+ * token (a line with two TBDs yields one finding).
193
193
  * - negation guard: a token preceded by a negation word (`no/not/without/
194
- * none`) in the same segment (split at `(`/`[`/`{`/`.`/`;`/`,`/line
195
- * start) is an absence assertion ("no TBD/placeholder/TODO" states the
196
- * rule), not a placeholder — not flagged.
194
+ * none`) in the same segment (split at `(`/`[`/`{`/`.`/`;`/`,`/line
195
+ * start) is an absence assertion ("no TBD/placeholder/TODO" states the
196
+ * rule), not a placeholder — not flagged.
197
197
  * - exemptions: fenced code blocks (```` ``` ```` / `~~~`) and inline code
198
- * spans are skipped — `...` in a file-list or example is not a placeholder.
198
+ * spans are skipped — `...` in a file-list or example is not a placeholder.
199
199
  * - out of scope (judgment stays prompt): "add tests" without code, and
200
- * `FIXME`/`XXX` code markers.
200
+ * `FIXME`/`XXX` code markers.
201
201
  */
202
202
  export declare function planQualityBar(planText: string): PlanQualityResult;
203
203
  /**
@@ -205,7 +205,7 @@ export declare function planQualityBar(planText: string): PlanQualityResult;
205
205
  * Frontmatter Contract:
206
206
  * - `name` — stable, lowercase-hyphen (`example-skill`);
207
207
  * - `description` — the trigger contract, third person, not a workflow
208
- * summary.
208
+ * summary.
209
209
  *
210
210
  * Accepts a full document (leading `---`-fenced block is parsed) or a bare
211
211
  * frontmatter body (`name:`/`description:` lines at the start). Violations:
@@ -214,21 +214,21 @@ export declare function planQualityBar(planText: string): PlanQualityResult;
214
214
  * - `lint.frontmatter.name.format` — `name` not lowercase-hyphen
215
215
  * - `lint.frontmatter.description.missing` — `description` absent/empty
216
216
  * - `lint.frontmatter.description.person` — first/second-person pronoun in
217
- * the description (third-person heuristic, low severity)
217
+ * the description (third-person heuristic, low severity)
218
218
  * - `lint.frontmatter.description.workflow` — description reads as a
219
- * workflow summary (verb-start or paragraph-length heuristic, low
220
- * severity)
219
+ * workflow summary (verb-start or paragraph-length heuristic, low
220
+ * severity)
221
221
  *
222
222
  * Heuristics (documented, conservative; corpus regression tests in
223
223
  * lint.test.ts cover the 20 real skill frontmatters):
224
224
  * - pronouns: `I`/`we`/`you`/`my`/`our`/`your`/`us`, word-boundary,
225
- * case-insensitive, after stripping quoted and backticked spans; `I/`
226
- * (I/O) and all-caps `US` exempt.
225
+ * case-insensitive, after stripping quoted and backticked spans; `I/`
226
+ * (I/O) and all-caps `US` exempt.
227
227
  * - workflow shape: description starts with a workflow verb ("Explains how
228
- * …", "Describes …") — the contract's own bad example — or exceeds 120
229
- * words (corpus max 114). Bold/quote prefixes are stripped before the
230
- * verb check. No content judgment (e.g. whether the trigger is narrow
231
- * enough) — that stays prompt.
228
+ * …", "Describes …") — the contract's own bad example — or exceeds 120
229
+ * words (corpus max 114). Bold/quote prefixes are stripped before the
230
+ * verb check. No content judgment (e.g. whether the trigger is narrow
231
+ * enough) — that stays prompt.
232
232
  */
233
233
  export declare function lintSkillFrontmatter(frontmatterText: string): GateResult;
234
234
  /**
package/dist/migrate.d.ts CHANGED
@@ -19,12 +19,12 @@ export type MigrateSnapshot = {
19
19
  type: WorkflowLifecycleType;
20
20
  status: WorkflowLifecycleStatus;
21
21
  /**
22
- * Canonical (default-layout) harness-relative snapshot path, e.g.
23
- * `workflows/<id>/snapshot.json`. The actual write target derives from
24
- * `MigratePlan.workflowDir` (Phase-5 F1 — a `.mstarc` custom
25
- * `workflow_dir` is honored by the executor); this field keeps the
26
- * default-layout rel name for display/provenance.
27
- */
22
+ * Canonical (default-layout) harness-relative snapshot path, e.g.
23
+ * `workflows/<id>/snapshot.json`. The actual write target derives from
24
+ * `MigratePlan.workflowDir` (Phase-5 F1 — a `.mstarc` custom
25
+ * `workflow_dir` is honored by the executor); this field keeps the
26
+ * default-layout rel name for display/provenance.
27
+ */
28
28
  file: string;
29
29
  /** Provenance label (compass file / status.json row). */
30
30
  source: string;
@@ -57,7 +57,7 @@ export type MigrateRootV2 = {
57
57
  file: string;
58
58
  data: StatusV2Doc;
59
59
  };
60
- /** Planner options (plan Task 6 — `--dry-run` returns steps, zero writes). */
60
+ /** Planner options ( — `--dry-run` returns steps, zero writes). */
61
61
  export type MigrateOptions = {
62
62
  dryRun?: boolean;
63
63
  /** Project id for the register/roadmap home (default `_default`). */
@@ -68,20 +68,20 @@ export type MigratePlan = {
68
68
  /** Resolved harness dir. */
69
69
  root: string;
70
70
  /**
71
- * Resolved `{WORKFLOW_DIR}` (Phase-5 F1): the `.mstarc` `[config]
72
- * workflow_dir` declaration wins, else `{HARNESS_DIR}/workflows`. The
73
- * snapshot/notes `file` fields below keep the canonical default-layout
74
- * rel names for display/provenance; the executor derives the actual
75
- * write targets from this dir so a custom layout lands where the v3
76
- * runtime reads.
77
- */
71
+ * Resolved `{WORKFLOW_DIR}` (Phase-5 F1): the `.mstarc` `[config]
72
+ * workflow_dir` declaration wins, else `{HARNESS_DIR}/workflows`. The
73
+ * snapshot/notes `file` fields below keep the canonical default-layout
74
+ * rel names for display/provenance; the executor derives the actual
75
+ * write targets from this dir so a custom layout lands where the v3
76
+ * runtime reads.
77
+ */
78
78
  workflowDir: string;
79
79
  /**
80
- * Resolved `{PROJECT_DIR}` (Phase-5 F1): the `.mstarc` `[config]
81
- * project_dir` declaration wins, else `{HARNESS_DIR}/projects`. Same
82
- * canonical-`file`-vs-actual-target split as `workflowDir` for the
83
- * register/roadmap writes.
84
- */
80
+ * Resolved `{PROJECT_DIR}` (Phase-5 F1): the `.mstarc` `[config]
81
+ * project_dir` declaration wins, else `{HARNESS_DIR}/projects`. Same
82
+ * canonical-`file`-vs-actual-target split as `workflowDir` for the
83
+ * register/roadmap writes.
84
+ */
85
85
  projectDir: string;
86
86
  dryRun: boolean;
87
87
  /** Root status.json already at `version: 2` -> nothing to plan/apply. */
@@ -108,7 +108,7 @@ export type MigrateResult = {
108
108
  message: string;
109
109
  };
110
110
  /**
111
- * Pure migration planner (plan Task 6): reads the v1 tree under `root` and
111
+ * Pure migration planner (): reads the v1 tree under `root` and
112
112
  * returns the full v2 migration plan — snapshots, notes ledgers, project
113
113
  * register, roadmap seeds, the archived v1 copy and the root v2
114
114
  * replacement — with an ordered step list (source -> destination). ZERO
@@ -120,7 +120,7 @@ export type MigrateResult = {
120
120
  */
121
121
  export declare function migrateHarnessTree(root: string, opts?: MigrateOptions): MigratePlan;
122
122
  /**
123
- * Execute a migration plan (plan Task 6). Additive-first ordering: the v1
123
+ * Execute a migration plan (). Additive-first ordering: the v1
124
124
  * root is archived, workflow snapshots/notes, the project register and the
125
125
  * roadmap are written BEFORE the root v2 replacement — the LAST step, the
126
126
  * commit point. A failure before it leaves the v1 tree intact (re-run
@@ -128,7 +128,7 @@ export declare function migrateHarnessTree(root: string, opts?: MigrateOptions):
128
128
  * `dryRun` plan, is a no-op. Every destination stays inside the harness
129
129
  * dir; every snapshot is validated fail-closed inside `writeWorkflowSnapshot`
130
130
  * — the writer is the authoritative validator, so the apply loop does not
131
- * pre-validate (qc wave-1 S-h: a gate here would run the same O(rows) pass
131
+ * pre-validate (a gate here would run the same O(rows) pass
132
132
  * twice per snapshot).
133
133
  */
134
134
  export declare function applyMigratePlan(plan: MigratePlan): Promise<MigrateResult>;
package/dist/path.d.ts CHANGED
@@ -4,25 +4,25 @@ import { type ValidationResult } from "./core.js";
4
4
  */
5
5
  export type ResolveHarnessDirOptions = {
6
6
  /**
7
- * Explicit harness root. Resolved against `startDir` when relative.
8
- * Takes precedence over `MSTAR_HARNESS_DIR` and over default probing.
9
- * Authoritative: the path is returned even when it does not exist yet
10
- * (the caller may scaffold it).
11
- */
7
+ * Explicit harness root. Resolved against `startDir` when relative.
8
+ * Takes precedence over `MSTAR_HARNESS_DIR` and over default probing.
9
+ * Authoritative: the path is returned even when it does not exist yet
10
+ * (the caller may scaffold it).
11
+ */
12
12
  harnessDir?: string;
13
13
  /**
14
- * Workspace-root stop boundary (roadmap §7c / plan
15
- * 20260810-harness-root-boundary). The upward probe keeps walking only
16
- * while `dir` is at or below this root — a harness dir above it is never
17
- * returned (the `~/.mstar` global-collision defect is the special case).
18
- * Resolved against `startDir` when relative. When omitted, the default
19
- * boundary is the git top-level of `startDir` (sync `git rev-parse
20
- * --show-cdup`; on failure / non-git start it falls back to
21
- * `startDir` itself — a non-git start probes only itself, never upward;
22
- * deliberate tightening). The boundary is an explicit caller value: the
23
- * engine git-probes only for this default resolution, never during the
24
- * walk.
25
- */
14
+ * Workspace-root stop boundary (roadmap §7c / plan
15
+ * 20260810-harness-root-boundary). The upward probe keeps walking only
16
+ * while `dir` is at or below this root — a harness dir above it is never
17
+ * returned (the `~/.mstar` global-collision defect is the special case).
18
+ * Resolved against `startDir` when relative. When omitted, the default
19
+ * boundary is the git top-level of `startDir` (sync `git rev-parse
20
+ * --show-cdup`; on failure / non-git start it falls back to
21
+ * `startDir` itself — a non-git start probes only itself, never upward;
22
+ * deliberate tightening). The boundary is an explicit caller value: the
23
+ * engine git-probes only for this default resolution, never during the
24
+ * walk.
25
+ */
26
26
  workspaceRoot?: string;
27
27
  };
28
28
  /**
@@ -48,10 +48,10 @@ export declare function resolveHarnessDir(startDir?: string, opts?: ResolveHarne
48
48
  */
49
49
  export type ResolveSpecsDirOptions = {
50
50
  /**
51
- * Default true: when every candidate is absent or empty, create
52
- * `{HARNESS_DIR}/specs/` (plan-conventions § 创建默认). Read-only callers
53
- * (e.g. `mstar path resolve`) pass `false` to skip the side effect.
54
- */
51
+ * Default true: when every candidate is absent or empty, create
52
+ * `{HARNESS_DIR}/specs/` (plan-conventions § 创建默认). Read-only callers
53
+ * (e.g. `mstar path resolve`) pass `false` to skip the side effect.
54
+ */
55
55
  create?: boolean;
56
56
  };
57
57
  /**
@@ -79,12 +79,23 @@ export declare function resolveSpecsDir(harnessDir: string, opts?: ResolveSpecsD
79
79
  export declare function resolvePlanDir(harnessDir: string): string;
80
80
  /**
81
81
  * Single safe path component for per-plan path composition
82
- * (qc2 F-001 — path traversal guard): rejects `""`, `.`, `..`, and any
82
+ * (path traversal guard): rejects `""`, `.`, `..`, and any
83
83
  * `/` or `\`; allows `[A-Za-z0-9._-]+` only. Throws with a clear message so
84
84
  * callers interpolating a plan id into a path (archive files, SDD dirs)
85
85
  * can never escape the intended parent directory.
86
86
  */
87
87
  export declare function assertSafePathComponent(value: string, what: string): void;
88
+ /**
89
+ * Canonicalize `path` for containment checks when the leaf may not exist
90
+ * (A3 nonexistent-leaf rule): canonicalize the nearest existing ancestor
91
+ * (realpath — resolves macOS `/var` → `/private/var` and any symlinked
92
+ * ancestors) and append the not-yet-existing remaining segments lexically.
93
+ * `..`/`.` segments are collapsed lexically by `resolve` before the walk,
94
+ * so the result is the path a later write would actually land at. Pure
95
+ * read-only (stat/realpath only — never creates anything). When nothing up
96
+ * to the filesystem root exists, the lexically resolved input is returned.
97
+ */
98
+ export declare function canonicalizeNearestExisting(path: string): string;
88
99
  /**
89
100
  * Compose `{SDD_DIR}` = `{HARNESS_DIR}/sdd/<plan-id>/` (plan-conventions
90
101
  * § 路径符号). A `.mstarc` `[config] sdd_dir` declaration replaces the
@@ -113,7 +124,7 @@ export declare function resolveKnowledgeDir(harnessDir: string): string;
113
124
  * the config file's directory). The dir need not exist — writers
114
125
  * (`writeWorkflowSnapshot` / register paths) create it on demand.
115
126
  *
116
- * Deferred-by-design (qc1 S-3): the startDir-first signature is asymmetric
127
+ * Deferred-by-design : the startDir-first signature is asymmetric
117
128
  * with the harnessDir-first sibling resolvers — brief-mandated for the CLI
118
129
  * consumer (it probes from the cwd). Revisit with a harness-dir-first
119
130
  * variant when a third v3 subdir resolver appears.
@@ -124,8 +135,7 @@ export declare function resolveWorkflowDir(startDir?: string, opts?: ResolveHarn
124
135
  * layer: roadmap.md + residuals register per project id). A `.mstarc`
125
136
  * `[config] project_dir` declaration wins (resolved against the config
126
137
  * file's directory). Same deferred-by-design signature asymmetry as
127
- * `resolveWorkflowDir` (qc1 S-3).
128
- */
138
+ * `resolveWorkflowDir`. */
129
139
  export declare function resolveProjectDir(startDir?: string, opts?: ResolveHarnessDirOptions): string;
130
140
  /**
131
141
  * Resolve the scaffold target dirs for `root` — the harness dir and the