@unbrained/pm-cli 2026.9.19 → 2026.9.21
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +954 -924
- package/dist/cli/main.d.ts +10 -76
- package/dist/cli/main.js +1 -2
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli/runtime/activation.d.ts +51 -0
- package/dist/cli/runtime/activation.js +2 -0
- package/dist/cli/runtime/invocation-options.d.ts +41 -0
- package/dist/cli/runtime/invocation-options.js +2 -0
- package/dist/cli/runtime/selection.d.ts +29 -0
- package/dist/cli/runtime/selection.js +2 -0
- package/dist/cli/runtime/telemetry-outcome.d.ts +20 -0
- package/dist/cli/runtime/telemetry-outcome.js +2 -0
- package/dist/cli-bundle/bundle-manifest.json +150 -150
- package/dist/cli-bundle/chunks/{chunk-QA4GUEKJ.js → chunk-2QLXN6HZ.js} +46 -46
- package/dist/cli-bundle/chunks/chunk-2UNYUB4A.js +2 -0
- package/dist/cli-bundle/chunks/chunk-4SI67A2F.js +8 -0
- package/dist/cli-bundle/chunks/chunk-7YUYLYJQ.js +6 -0
- package/dist/cli-bundle/chunks/{chunk-7CN53F4S.js → chunk-FBWAECBI.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-GRHSNUQO.js +20 -0
- package/dist/cli-bundle/chunks/chunk-HAFSMFJK.js +3 -0
- package/dist/cli-bundle/chunks/chunk-JBJUOOJI.js +238 -0
- package/dist/cli-bundle/chunks/chunk-K7RWRJLT.js +29 -0
- package/dist/cli-bundle/chunks/chunk-NHRB3L5T.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-CCLWCESZ.js → chunk-QZTS23BV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-K4VAU4HU.js → chunk-SDLBF4PY.js} +1252 -1252
- package/dist/cli-bundle/chunks/{register-list-query-RMZNHSII.js → register-list-query-5V43MYPN.js} +6 -6
- package/dist/cli-bundle/chunks/{register-mutation-HJGSGX3H.js → register-mutation-DXES37MA.js} +4 -4
- package/dist/cli-bundle/chunks/register-operations-LJU5H2CU.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-HJUNGYBB.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3XPBKIV6.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-7Y7PAC56.js → chunk-5BLRMUMK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5SZ4JSPZ.js → chunk-6MNKQKT6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IKPR4VVN.js → chunk-DPBTIFW7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-J3GN4SQT.js → chunk-DRNXMOSV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-P4BA7OX7.js → chunk-FXAZPSU6.js} +7 -7
- package/dist/cli-bundle/focused-chunks/{chunk-ARK4FIO4.js → chunk-HYPK5OPA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-I4WDON3K.js → chunk-IA5CCSBB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CJ4QA4RW.js → chunk-ISEOBALS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ZI2YBJFH.js → chunk-K5ZCBC6Y.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-V3YMNAO7.js → chunk-L6L4XCLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TDHVROGL.js → chunk-N6KI3LWF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-PC6ZZVNP.js +20 -0
- package/dist/cli-bundle/focused-chunks/chunk-RQL5WLNZ.js +30 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZDBKYZFE.js → chunk-U2SB2BMM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YDFEWXXZ.js → chunk-UIS5FVHH.js} +53 -53
- package/dist/cli-bundle/main.js +26 -27
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +39 -39
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +42 -42
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +8 -8
- package/dist/core/diagnostics/remediation.js +1 -1
- package/dist/core/extensions/extension-types.d.ts +2 -2
- package/dist/core/extensions/loader.d.ts +9 -15
- package/dist/core/extensions/loader.js +1 -1
- package/dist/core/extensions/manifest-parser.d.ts +5 -0
- package/dist/core/extensions/manifest-parser.js +2 -0
- package/dist/core/extensions/registration-contracts.d.ts +34 -0
- package/dist/core/extensions/registration-contracts.js +2 -0
- package/dist/core/governance/issue-codes.d.ts +10 -1
- package/dist/core/governance/issue-codes.js +1 -1
- package/dist/core/validate/fix-planning.d.ts +3 -3
- package/dist/core/validate/fix-planning.js +1 -1
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/completion/bash.d.ts +3 -0
- package/dist/sdk/completion/bash.js +2 -0
- package/dist/sdk/completion/fish.d.ts +3 -0
- package/dist/sdk/completion/fish.js +1054 -0
- package/dist/sdk/completion/shared.d.ts +103 -0
- package/dist/sdk/completion/shared.js +2 -0
- package/dist/sdk/completion/zsh.d.ts +3 -0
- package/dist/sdk/completion/zsh.js +1109 -0
- package/dist/sdk/completion.d.ts +5 -30
- package/dist/sdk/completion.js +1 -2160
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/closure-timestamps.d.ts +32 -0
- package/dist/sdk/governance/closure-timestamps.js +2 -0
- package/dist/sdk/governance/validate-normalization.d.ts +2 -0
- package/dist/sdk/governance/validate-normalization.js +1 -1
- package/dist/sdk/governance/validate.js +1 -1
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/search/corpus.d.ts +27 -0
- package/dist/sdk/query/search/corpus.js +2 -0
- package/dist/sdk/query/search/filters.d.ts +27 -0
- package/dist/sdk/query/search/filters.js +2 -0
- package/dist/sdk/query/search/input.d.ts +28 -0
- package/dist/sdk/query/search/input.js +2 -0
- package/dist/sdk/query/search/lexical.d.ts +34 -0
- package/dist/sdk/query/search/lexical.js +2 -0
- package/dist/sdk/query/search/response.d.ts +34 -0
- package/dist/sdk/query/search/response.js +2 -0
- package/dist/sdk/query/search/semantic.d.ts +229 -0
- package/dist/sdk/query/search/semantic.js +3 -0
- package/dist/sdk/query/search/types.d.ts +123 -0
- package/dist/sdk/query/search/types.js +2 -0
- package/dist/sdk/query/search.d.ts +13 -364
- package/dist/sdk/query/search.js +1 -2
- package/dist/sdk/runtime/actions.d.ts +4 -0
- package/dist/sdk/runtime/actions.js +2 -0
- package/dist/sdk/runtime/context.d.ts +38 -0
- package/dist/sdk/runtime/context.js +2 -0
- package/dist/sdk/runtime/schema.d.ts +4 -0
- package/dist/sdk/runtime/schema.js +2 -0
- package/dist/sdk/runtime.d.ts +90 -95
- package/dist/sdk/runtime.js +1 -1
- package/docs/ARCHITECTURE.md +68 -0
- package/docs/HISTORY_GOVERNANCE_REPAIR.md +66 -0
- package/docs/README.md +2 -0
- package/docs/VALIDATION_PORTABILITY.md +82 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
- package/marketplace.json +2 -2
- package/package.json +6 -6
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +23 -17
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-AACGU5IA.js +0 -3
- package/dist/cli-bundle/chunks/chunk-J7NP7QLW.js +0 -6
- package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +0 -238
- package/dist/cli-bundle/chunks/chunk-KYG2QKNY.js +0 -29
- package/dist/cli-bundle/chunks/chunk-OQS2Y6VN.js +0 -2
- package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +0 -20
- package/dist/cli-bundle/chunks/chunk-RVMDPIGD.js +0 -2
- package/dist/cli-bundle/chunks/chunk-WASMH647.js +0 -8
- package/dist/cli-bundle/chunks/register-operations-LBEMFUMM.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-MU557JAA.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-I32L3FWW.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-OOZHQFBF.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-QL4MO5M2.js +0 -30
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="16aa1db1-b6f2-504b-aa4e-0e384ad1d7a5")}catch(e2){}})();import{assertInitializedTracker}from"../environment/tracker-preflight.js";import{readWorkflowCompletenessCheck}from"./workflow-completeness.js";import fs from"node:fs/promises";import{realpathSync}from"node:fs";import{execFile}from"node:child_process";import path from"node:path";import{promisify}from"node:util";import{buildRemediationCommands}from"../../core/diagnostics/remediation.js";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{collectRegisteredItemFieldNames}from"../../core/extensions/item-fields.js";import{isFileMissingError}from"../../core/fs/fs-utils.js";import{normalizeStatusInput}from"../../core/item/status.js";import{resolveItemTypeRegistry}from"../../core/item/type-registry.js";import{resolveRuntimeStatusRegistry}from"../../core/schema/runtime-schema.js";import{DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS,DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS,EXIT_CODE,PM_DIRNAME,SETTINGS_DEFAULTS}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{toNonEmptyStringOrUndefined}from"../../core/shared/primitives.js";import{nowIso}from"../../core/shared/time.js";import{CURRENT_ITEM_FORMAT_VERSION,effectiveItemFormatVersion,scanItemFormatVersions}from"../../core/item/item-format-version.js";import{resolvePmRoot}from"../../core/store/paths.js";import{readSettings}from"../../core/store/settings.js";import{partitionFixesByGrant,planCloseReasonBackfillFixes,planEstimateBackfillFixes,planResolutionBackfillFixes,planStaleLinkPruneFixes,planTerminalParentFixes,resolveGrantedFixScopes,toFixOutputRow}from"../../core/validate/fix-planning.js";import{findDuplicateIssueCodes}from"../../core/governance/issue-codes.js";import{buildMissingByTypeCounts}from"../../core/validate/missing-by-type.js";import{classifyStaleLinkedPaths,summarizeStaleLinkedPathClassifications}from"../../core/validate/stale-file-classification.js";import{isRemoteLinkedArtifactReference}from"../../core/validate/linked-artifact-reference.js";import{assertProjectionModeChoice}from"../output-projection.js";import{collectDanglingDependencyReferences}from"../graph/assembly.js";import{auditMergeAttributeFence,auditMergeDriverConfiguration,findGitWorkspaceRoot,resolveProjectMergeTypeFolders}from"../merge/install.js";import{inspectMergeReceiptEvidence,partitionMergeReceipts}from"../merge/receipts.js";import{buildLinkedFileRepairReport}from"./linked-file-report.js";import{scanStorageIntegrity}from"./storage-integrity.js";import{scanTrackedRuntimeCache}from"./tracked-runtime-cache.js";import{scanHistoryAuthorAttribution}from"../author-attribution.js";import{createRelationshipKindRegistry}from"../relationships.js";import{runDocs}from"../docs.js";import{runFiles}from"../files.js";import{extractReferencedPmItemIdsFromCommand}from"../test/linked-command-detection.js";import{resolveLinkedTestSourceRef,resolveLinkedTestSourceWorkspaceRoot,resolveLinkedTestTrustBatch}from"../test/trust.js";import{readValidateItems}from"./validate-item-reader.js";import{buildValidateHistoryDriftCheck}from"./validate-history-drift.js";import{buildLifecycleParentGraph,detectLifecycleParentCycles,resolveLifecycleDependencyCycleSamplePath}from"./hierarchy-validation.js";import{buildStatusRoleWarnings,inspectStatusRoleAssignments}from"./status-role-diagnostics.js";import{normalizeRelativeDirectoryPath,normalizeRelativePath,toMeaningfulString}from"./validate-normalization.js";const FILE_SCAN_DIRECTORIES=["src","tests","docs"];const FILE_SCAN_ROOT_FILES=["README.md","PRD.md","CHANGELOG.md","AGENTS.md","CONTRIBUTING.md","SECURITY.md","CODE_OF_CONDUCT.md","LICENSE"];const DIRECTORY_IGNORE_SET=new Set(["node_modules",".git",".cursor",".agents","dist","coverage"]);const RESOLUTION_FIELD_KEYS=["resolution","expected_result","actual_result"];const VALIDATE_FILE_SCAN_MODES=["default","tracked-all","tracked-all-strict"];const VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"];const VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES=["off","warn","error"];const CORE_METADATA_REQUIRED_FIELDS=["author","acceptance_criteria","estimated_minutes","close_reason"];const STRICT_METADATA_REQUIRED_FIELDS=[...CORE_METADATA_REQUIRED_FIELDS,"reviewer","risk","confidence","sprint","release"];const SUPPORTED_METADATA_REQUIRED_FIELDS=Array.from(new Set(STRICT_METADATA_REQUIRED_FIELDS));const METADATA_REQUIRED_FIELD_ALIASES={author:"author",acceptance_criteria:"acceptance_criteria","acceptance-criteria":"acceptance_criteria",estimated_minutes:"estimated_minutes","estimated-minutes":"estimated_minutes",estimate:"estimated_minutes",close_reason:"close_reason","close-reason":"close_reason",reviewer:"reviewer",risk:"risk",confidence:"confidence",sprint:"sprint",release:"release"};const METADATA_WARNING_TOKEN_BY_FIELD={author:"validate_metadata_missing_author",acceptance_criteria:"validate_metadata_missing_acceptance_criteria",estimated_minutes:"validate_metadata_missing_estimate",close_reason:"validate_metadata_missing_close_reason",reviewer:"validate_metadata_missing_reviewer",risk:"validate_metadata_missing_risk",confidence:"validate_metadata_missing_confidence",sprint:"validate_metadata_missing_sprint",release:"validate_metadata_missing_release"};const METADATA_COUNT_KEY_BY_FIELD={author:"missing_author",acceptance_criteria:"missing_acceptance_criteria",estimated_minutes:"missing_estimated_minutes",close_reason:"closed_missing_close_reason",reviewer:"missing_reviewer",risk:"missing_risk",confidence:"missing_confidence",sprint:"missing_sprint",release:"missing_release"};const METADATA_ITEM_IDS_KEY_BY_FIELD={author:"missing_author_item_ids",acceptance_criteria:"missing_acceptance_criteria_item_ids",estimated_minutes:"missing_estimated_minutes_item_ids",close_reason:"closed_missing_close_reason_item_ids",reviewer:"missing_reviewer_item_ids",risk:"missing_risk_item_ids",confidence:"missing_confidence_item_ids",sprint:"missing_sprint_item_ids",release:"missing_release_item_ids"};const METADATA_TRUNCATED_KEY_BY_FIELD={author:"missing_author_truncated",acceptance_criteria:"missing_acceptance_criteria_truncated",estimated_minutes:"missing_estimated_minutes_truncated",close_reason:"closed_missing_close_reason_truncated",reviewer:"missing_reviewer_truncated",risk:"missing_risk_truncated",confidence:"missing_confidence_truncated",sprint:"missing_sprint_truncated",release:"missing_release_truncated"};const GIT_LS_FILES_MAX_BUFFER=32*1024*1024;const GIT_LS_FILES_TIMEOUT_MS=1e4;const FILE_LIST_SUMMARY_LIMIT=40;const DIAGNOSTIC_LIST_SUMMARY_LIMIT=5;const LINKED_ARTIFACT_MAX_PATH_LENGTH=4096;const LINKED_ARTIFACT_MAX_SEGMENT_LENGTH=255;const execFileAsync=promisify(execFile);function projectValidateCountsRecord(record){const projected={};for(const[key,value]of Object.entries(record)){if(Array.isArray(value)||value===false&&key.endsWith("_truncated")){continue}projected[key]=typeof value==="object"&&value!==null?projectValidateCountsRecord(value):value}return projected}function projectValidateCounts(result){return{...result,checks:result.checks.map(check=>({...check,details:projectValidateCountsRecord(check.details)})),...result.fixes?{fixes:{mode:result.fixes.mode,auto_fix:result.fixes.auto_fix,prune_missing:result.fixes.prune_missing,planned_count:result.fixes.planned_count,applied_count:result.fixes.applied_count,gated_count:result.fixes.gated_count,failed_count:result.fixes.failed_count}}:{}}}function normalizeStatusForRegistry(status,statusRegistry){return normalizeStatusInput(status,statusRegistry)??status}function isTerminalStatus(status,statusRegistry){return statusRegistry.terminal_statuses.has(normalizeStatusForRegistry(status,statusRegistry))}function normalizeLifecyclePatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function areSortedStringListsEqual(left,right){if(left.length!==right.length){return false}return left.every((value,index)=>value===right[index])}function resolveLifecyclePatternPolicy(settings){const defaultStalePatterns=normalizeLifecyclePatternList(DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS);const defaultClosureLikePatterns={blocked_reason:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.blocked_reason),resolution:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.resolution),actual_result:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.actual_result)};const staleBlockerReasonPatterns=normalizeLifecyclePatternList(settings.validation.lifecycle_stale_blocker_reason_patterns);const closureLikePatterns={blocked_reason:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_blocked_reason_patterns),resolution:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_resolution_patterns),actual_result:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_actual_result_patterns)};return{stale_blocker_reason_patterns:staleBlockerReasonPatterns,stale_blocker_reason_pattern_source:areSortedStringListsEqual(staleBlockerReasonPatterns,defaultStalePatterns)?"default":"settings",closure_like_metadata_field_patterns:closureLikePatterns,closure_like_metadata_field_pattern_sources:{blocked_reason:areSortedStringListsEqual(closureLikePatterns.blocked_reason,defaultClosureLikePatterns.blocked_reason)?"default":"settings",resolution:areSortedStringListsEqual(closureLikePatterns.resolution,defaultClosureLikePatterns.resolution)?"default":"settings",actual_result:areSortedStringListsEqual(closureLikePatterns.actual_result,defaultClosureLikePatterns.actual_result)?"default":"settings"}}}function resolveValidateMetadataProfile(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"core"}if(VALIDATE_METADATA_PROFILE_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --metadata-profile value "${value}". Supported values: ${VALIDATE_METADATA_PROFILE_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveDependencyCycleSeverity(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"warn"}if(VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --dependency-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveParentCycleSeverity(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"warn"}if(VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --parent-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function normalizeMetadataRequiredFieldsFromSettings(values){const normalized=[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))];return normalized.map(value=>METADATA_REQUIRED_FIELD_ALIASES[value]).filter(value=>value!==void 0).sort((left,right)=>left.localeCompare(right))}function resolveValidateMetadataPolicy(profile,profileSource,configuredCustomFields){const normalizedCustomFields=normalizeMetadataRequiredFieldsFromSettings(configuredCustomFields);if(profile==="core"){return{profile,profile_source:profileSource,required_fields:[...CORE_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}if(profile==="strict"){return{profile,profile_source:profileSource,required_fields:[...STRICT_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}if(normalizedCustomFields.length>0){return{profile,profile_source:profileSource,required_fields:normalizedCustomFields,configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}return{profile,profile_source:profileSource,required_fields:[...CORE_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:true,warnings:["validate_metadata_custom_profile_missing_required_fields:0"]}}const TERMINAL_EXEMPT_PLANNING_FIELDS=new Set(["acceptance_criteria","estimated_minutes"]);function isMetadataFieldMissing(item,field,statusRegistry,enforcePlanningFieldsOnTerminal){if(!enforcePlanningFieldsOnTerminal&&TERMINAL_EXEMPT_PLANNING_FIELDS.has(field)&&isTerminalStatus(item.status,statusRegistry)){return false}if(field==="author"){return!toNonEmptyStringOrUndefined(item.author)}if(field==="acceptance_criteria"){return!toNonEmptyStringOrUndefined(item.acceptance_criteria)}if(field==="estimated_minutes"){return!Number.isFinite(item.estimated_minutes)}if(field==="close_reason"){return normalizeStatusForRegistry(item.status,statusRegistry)===statusRegistry.close_status&&!toNonEmptyStringOrUndefined(item.close_reason)}if(field==="reviewer"){return!toNonEmptyStringOrUndefined(item.reviewer)}if(field==="risk"){return!toNonEmptyStringOrUndefined(item.risk)}if(field==="confidence"){if(typeof item.confidence==="number"){return!Number.isFinite(item.confidence)}return!toNonEmptyStringOrUndefined(item.confidence)}if(field==="sprint"){return!toNonEmptyStringOrUndefined(item.sprint)}return!toNonEmptyStringOrUndefined(item.release)}function resolveFileScanMode(scanMode){if(scanMode===void 0){return"default"}const normalized=scanMode.trim().toLowerCase();if(normalized.length===0){return"default"}if(normalized==="default"){return"default"}if(normalized==="tracked-all"||normalized==="tracked_all"){return"tracked-all"}if(normalized==="tracked-all-strict"||normalized==="tracked_all_strict"){return"tracked-all-strict"}throw new PmCliError(`Unknown --scan-mode value "${scanMode}". Supported values: ${VALIDATE_FILE_SCAN_MODES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveWorkspaceRoot(pmRoot){const sourceWorkspaceRoot=process.env.PM_SOURCE_WORKSPACE_ROOT?.trim();if(sourceWorkspaceRoot){return path.resolve(sourceWorkspaceRoot)}const resolvedPmRoot=path.resolve(pmRoot);const normalizedPmRoot=resolvedPmRoot.replaceAll("\\","/");if(normalizedPmRoot.endsWith("/.agents/pm")){return path.dirname(path.dirname(resolvedPmRoot))}const resolvedCwd=path.resolve(process.cwd());const canonicalPmRoot=realpathForWorkspaceRoot(resolvedPmRoot);const canonicalCwd=realpathForWorkspaceRoot(resolvedCwd);const relativeFromPmRoot=path.relative(canonicalPmRoot,canonicalCwd);const cwdInsidePmRoot=relativeFromPmRoot.length===0||!relativeFromPmRoot.startsWith("..")&&!path.isAbsolute(relativeFromPmRoot);if(cwdInsidePmRoot){return resolvedPmRoot}return resolvedCwd}function realpathForWorkspaceRoot(inputPath){try{return realpathSync.native(inputPath)}catch{return path.resolve(inputPath)}}function hasFilesystemErrorCode(error,acceptedCodes){return typeof error==="object"&&error!==null&&"code"in error&&typeof error.code==="string"&&acceptedCodes.includes(error.code)}async function listFilesRecursive(basePath,relativePath,output){const targetDirectory=relativePath.length>0?path.join(basePath,relativePath):basePath;let entries;try{entries=await fs.readdir(targetDirectory,{withFileTypes:true})}catch(error){if(isFileMissingError(error)){return}throw error}for(const entry of entries){if(entry.name.startsWith(".")){continue}const childRelative=relativePath.length>0?path.join(relativePath,entry.name):entry.name;if(entry.isDirectory()){if(DIRECTORY_IGNORE_SET.has(entry.name)){continue}await listFilesRecursive(basePath,childRelative,output);continue}if(!entry.isFile()){continue}output.push(normalizeRelativePath(childRelative))}}async function collectDefaultProjectFileCandidates(workspaceRoot){const discovered=[];for(const directory of FILE_SCAN_DIRECTORIES){await listFilesRecursive(workspaceRoot,directory,discovered)}for(const candidate of FILE_SCAN_ROOT_FILES){const absolute=path.join(workspaceRoot,candidate);try{const stats=await fs.stat(absolute);if(stats.isFile()){discovered.push(normalizeRelativePath(candidate))}}catch{}}return[...new Set(discovered)].sort((left,right)=>left.localeCompare(right))}async function collectTrackedGitFileCandidates(workspaceRoot){try{const{stdout}=await execFileAsync("git",["ls-files","-z"],{cwd:workspaceRoot,encoding:"utf8",maxBuffer:GIT_LS_FILES_MAX_BUFFER,windowsHide:true,timeout:GIT_LS_FILES_TIMEOUT_MS});const discovered=stdout.split("\0").map(value=>normalizeRelativePath(value)).filter(value=>value.length>0);return[...new Set(discovered)].sort((left,right)=>left.localeCompare(right))}catch{return null}}function resolvePmInternalCandidatePrefixes(pmRoot,workspaceRoot){const prefixes=new Set;const configuredDefault=normalizeRelativeDirectoryPath(PM_DIRNAME);if(configuredDefault.length>0){prefixes.add(configuredDefault)}const relativePmRoot=normalizeRelativeDirectoryPath(path.relative(workspaceRoot,pmRoot));if(relativePmRoot.length>0&&!relativePmRoot.startsWith("..")){prefixes.add(relativePmRoot)}return[...prefixes].sort((left,right)=>left.localeCompare(right))}function hasPathPrefix(candidate,prefixes){for(const prefix of prefixes){if(candidate===prefix||candidate.startsWith(`${prefix}/`)){return true}}return false}async function collectProjectFileCandidates(workspaceRoot,scanMode){if(scanMode==="tracked-all"||scanMode==="tracked-all-strict"){const trackedCandidates=await collectTrackedGitFileCandidates(workspaceRoot);if(trackedCandidates){return{requestedMode:scanMode,appliedMode:scanMode,source:"tracked-git",candidateFiles:trackedCandidates,candidateTotal:trackedCandidates.length,candidateScanned:trackedCandidates.length}}const fallbackCandidates=await collectDefaultProjectFileCandidates(workspaceRoot);return{requestedMode:scanMode,appliedMode:"default",source:"tracked-all-fallback-default",candidateFiles:fallbackCandidates,candidateTotal:fallbackCandidates.length,candidateScanned:fallbackCandidates.length}}const defaultCandidates=await collectDefaultProjectFileCandidates(workspaceRoot);return{requestedMode:scanMode,appliedMode:"default",source:"default-curated",candidateFiles:defaultCandidates,candidateTotal:defaultCandidates.length,candidateScanned:defaultCandidates.length}}function summarizeList(values,limit=DIAGNOSTIC_LIST_SUMMARY_LIMIT){if(values.length<=limit){return{values,truncated:false}}return{values:values.slice(0,limit),truncated:true}}function summarizeFileList(values,verboseFileLists){if(verboseFileLists){return{values,truncated:false,total:values.length}}const summary=summarizeList(values,FILE_LIST_SUMMARY_LIMIT);return{values:summary.values,truncated:summary.truncated,total:values.length}}const RESOLUTION_REMEDIATION_FLAG_BY_FIELD={resolution:"--resolution",expected_result:"--expected-result",actual_result:"--actual-result"};const RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD={resolution:"Describe how this item was resolved",expected_result:"Describe the expected result",actual_result:"Describe the actual result"};function buildResolutionRemediationCommand(row){const fieldArguments=row.missing_fields.map(field=>`${RESOLUTION_REMEDIATION_FLAG_BY_FIELD[field]} "${RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD[field]}"`).join(" ");return`pm update ${row.id} ${fieldArguments} --message "Backfill resolution metadata"`}function attachValidateFixHints(check,checkWarnings){const existingResolutionHints=check.details?.missing_resolution_remediation_hints;const aliasedResolution=Array.isArray(existingResolutionHints)&&existingResolutionHints.length>0;const fixHints=aliasedResolution?existingResolutionHints.filter(hint=>typeof hint==="string"):buildRemediationCommands(checkWarnings);if(fixHints.length===0){return}const truncated=aliasedResolution&&check.details?.missing_resolution_remediation_hints_truncated===true;check.details={...check.details,fix_hints:fixHints,...truncated?{fix_hints_truncated:true}:{}}}function resolveRequestedChecks(options){const requested=new Set;if(options.checkCompleteness)requested.add("completeness");if(options.checkMetadata){requested.add("metadata")}if(options.checkResolution){requested.add("resolution")}if(options.checkLifecycle||options.checkStaleBlockers){requested.add("lifecycle")}if(options.checkFiles){requested.add("files")}if(options.checkHistoryDrift){requested.add("history_drift")}if(options.checkCommandReferences){requested.add("command_references")}if(options.checkStorageIntegrity){requested.add("storage_integrity")}if(requested.size===0){if(options.autoFix){requested.add("metadata");requested.add("resolution");requested.add("lifecycle")}if(options.pruneMissing){requested.add("files")}if(requested.size===0){requested.add("metadata");requested.add("resolution");requested.add("lifecycle");requested.add("files");requested.add("command_references");requested.add("history_drift");requested.add("format_version");requested.add("completeness");requested.add("storage_integrity")}return requested}if(options.pruneMissing){requested.add("files")}return requested}const DUPLICATE_ISSUE_CODE_WARNING_TOKEN="validate_metadata_duplicate_issue_codes";function summarizeDuplicateIssueCodes(duplicates,verboseDiagnostics){if(duplicates.length===0){return{rows:[],truncated:false,warnings:[]}}const limit=verboseDiagnostics?duplicates.length:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const shown=duplicates.slice(0,limit);const rows=shown.map(duplicate=>({code:duplicate.code,count:duplicate.count,ids:duplicate.ids,titles:duplicate.titles,remediation_hint:`Items ${duplicate.ids.join(", ")} share issue code "${duplicate.code}"; rename or merge so each logical code maps to one item.`}));return{rows,truncated:shown.length<duplicates.length,warnings:[`${DUPLICATE_ISSUE_CODE_WARNING_TOKEN}:${duplicates.length}`]}}function collectMissingMetadataByField(items,statusRegistry,enforcePlanningFieldsOnTerminal){const missingByField=Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map(field=>[field,[]]));for(const item of items){for(const field of SUPPORTED_METADATA_REQUIRED_FIELDS){if(isMetadataFieldMissing(item,field,statusRegistry,enforcePlanningFieldsOnTerminal)){missingByField[field].push(item.id)}}}return missingByField}function buildMetadataWarningTokens(metadataPolicy,missingByField,duplicateWarnings){const warningTokens=[...metadataPolicy.warnings];for(const field of metadataPolicy.required_fields){const missingItems=missingByField[field];if(missingItems.length>0){warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`)}}warningTokens.push(...duplicateWarnings);return warningTokens}function buildMetadataCounts(metadataPolicy,missingByField){const counts={};for(const field of metadataPolicy.required_fields){const missing=missingByField[field];const value=missing?missing.length:0;const countKey=METADATA_COUNT_KEY_BY_FIELD[field];counts[countKey]=value}return counts}function buildMissingFieldOccurrences(metadataPolicy,missingByField,itemsById){const occurrences=[];for(const field of metadataPolicy.required_fields){const missing=missingByField[field];if(!missing){continue}for(const itemId of missing){const itemType=itemsById.get(itemId)?.type;const normalizedItemType=typeof itemType==="string"&&itemType.length>0?itemType:"Unknown";occurrences.push({item_type:normalizedItemType,field})}}return occurrences}function attachMissingMetadataItemIds(details,metadataPolicy,missingByField,verboseDiagnostics){for(const field of metadataPolicy.required_fields){const missing=missingByField[field];if(!missing||missing.length===0){continue}const idsKey=METADATA_ITEM_IDS_KEY_BY_FIELD[field];const truncatedKey=METADATA_TRUNCATED_KEY_BY_FIELD[field];if(!idsKey||!truncatedKey){continue}const summarized=summarizeList(missing,verboseDiagnostics?missing.length:DIAGNOSTIC_LIST_SUMMARY_LIMIT);details[idsKey]=summarized.values;details[truncatedKey]=summarized.truncated}}function buildCloseReasonBackfillRows(metadataPolicy,missingByField,itemsById){if(!metadataPolicy.required_fields.includes("close_reason")){return[]}const missing=missingByField.close_reason;if(!missing){return[]}return missing.map(itemId=>({id:itemId,resolution:toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution)}))}function buildEstimateBackfillRows(metadataPolicy,missingByField,itemsById){if(!metadataPolicy.required_fields.includes("estimated_minutes")){return[]}const missing=missingByField.estimated_minutes;if(!missing){return[]}return missing.map(itemId=>({id:itemId,type:toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type)}))}function buildMetadataCheck(items,metadataPolicy,statusRegistry,verboseDiagnostics,configuredIssueCodePrefixes){const itemsById=new Map(items.map(item=>[item.id,item]));const enforcePlanningFieldsOnTerminal=metadataPolicy.profile==="strict";const missingByField=collectMissingMetadataByField(items,statusRegistry,enforcePlanningFieldsOnTerminal);const duplicateIssueCodes=findDuplicateIssueCodes(items,{configuredPrefixes:configuredIssueCodePrefixes});const duplicateIssueCodeSummary=summarizeDuplicateIssueCodes(duplicateIssueCodes,verboseDiagnostics);const warningTokens=buildMetadataWarningTokens(metadataPolicy,missingByField,duplicateIssueCodeSummary.warnings);const counts=buildMetadataCounts(metadataPolicy,missingByField);const missingFieldOccurrences=buildMissingFieldOccurrences(metadataPolicy,missingByField,itemsById);const missingByType=buildMissingByTypeCounts(missingFieldOccurrences);const details={checked_items:items.length,metadata_profile:metadataPolicy.profile,metadata_profile_source:metadataPolicy.profile_source,metadata_profile_fallback_to_core:metadataPolicy.fallback_to_core,required_fields:[...metadataPolicy.required_fields],supported_required_fields:[...SUPPORTED_METADATA_REQUIRED_FIELDS],counts,missing_by_type:missingByType,duplicate_issue_codes_count:duplicateIssueCodes.length,duplicate_issue_codes:duplicateIssueCodeSummary.rows,duplicate_issue_codes_truncated:duplicateIssueCodeSummary.truncated};if(metadataPolicy.configured_custom_fields.length>0){details.configured_custom_required_fields=[...metadataPolicy.configured_custom_fields]}attachMissingMetadataItemIds(details,metadataPolicy,missingByField,verboseDiagnostics);const closeReasonBackfillRows=buildCloseReasonBackfillRows(metadataPolicy,missingByField,itemsById);const estimateBackfillRows=buildEstimateBackfillRows(metadataPolicy,missingByField,itemsById);return{check:{name:"metadata",status:warningTokens.length===0?"ok":"warn",ok:warningTokens.length===0,details},warnings:warningTokens,closeReasonBackfillRows,estimateBackfillRows}}function buildResolutionCheck(items,statusRegistry,verboseDiagnostics){const terminalDoneStatuses=new Set(statusRegistry.terminal_done_statuses);terminalDoneStatuses.add(statusRegistry.close_status);const closedItems=items.filter(item=>terminalDoneStatuses.has(normalizeStatusForRegistry(item.status,statusRegistry)));const missingResolutionRows=[];const resolutionBackfillRows=[];for(const item of closedItems){const missingFields=RESOLUTION_FIELD_KEYS.filter(field=>!toNonEmptyStringOrUndefined(item[field]));if(missingFields.length===0){continue}missingResolutionRows.push({id:item.id,missing_fields:missingFields});resolutionBackfillRows.push({id:item.id,missing_fields:missingFields,close_reason:toNonEmptyStringOrUndefined(item.close_reason)})}const warnings=missingResolutionRows.length>0?[`validate_resolution_missing_fields:${missingResolutionRows.length}`]:[];const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(missingResolutionRows.map(row=>`${row.id}:${row.missing_fields.join(",")}`),diagnosticLimit);const remediationHints=missingResolutionRows.map(row=>buildResolutionRemediationCommand(row));const summarizedHints=summarizeList(remediationHints,diagnosticLimit);return{check:{name:"resolution",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{checked_closed_items:closedItems.length,missing_resolution_items:missingResolutionRows.length,missing_resolution_rows:summarizedRows.values,missing_resolution_rows_truncated:summarizedRows.truncated,missing_resolution_remediation_hints:summarizedHints.values,missing_resolution_remediation_hints_truncated:summarizedHints.truncated}},warnings,resolutionBackfillRows}}function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildLifecycleDependencyGraph(activeItems,idPrefix="pm",relationshipRegistry=createRelationshipKindRegistry()){const activeItemIds=new Set(activeItems.map(item=>item.id));const sortedItems=[...activeItems].sort((left,right)=>left.id.localeCompare(right.id));return new Map(sortedItems.map(item=>{const edges=new Set;const blockedBy=toMeaningfulString(item.blocked_by);if(blockedBy&&activeItemIds.has(blockedBy)){edges.add(blockedBy)}(item.dependencies??[]).filter(dependency=>{const dependencyKind=toMeaningfulString(dependency.kind);return dependencyKind!==void 0&&relationshipRegistry.resolve(dependencyKind)?.ordering===true}).map(dependency=>toMeaningfulString(dependency.id)).filter(dependencyId=>dependencyId!==void 0&&activeItemIds.has(dependencyId)).forEach(dependencyId=>edges.add(dependencyId));const definitionOfReady=toMeaningfulString(item.definition_of_ready);extractItemIds(definitionOfReady??"",idPrefix).filter(referencedId=>activeItemIds.has(referencedId)).forEach(referencedId=>edges.add(referencedId));return[item.id,[...edges].sort((left,right)=>left.localeCompare(right))]}))}function buildDependencyReferencesCheck(items,verboseDiagnostics,statusRegistry){const classified=collectDanglingDependencyReferences(items,statusRegistry?status=>isTerminalStatus(status,statusRegistry):void 0);const activeRows=classified.active.map(row=>`${row.holder_id}:${row.target_id}:${row.kind}`);const legacyRows=classified.legacy_terminal.map(row=>`${row.holder_id}:${row.target_id}:${row.kind}:${row.holder_status}`);const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(activeRows,diagnosticLimit);const summarizedLegacyRows=summarizeList(legacyRows,diagnosticLimit);const hints=summarizeList(classified.active.map(row=>{if(row.source==="parent"){return`pm update ${row.holder_id} --unset parent`}return row.source==="blocked_by"?`pm update ${row.holder_id} --unset blocked_by`:`pm update ${row.holder_id} --replace-deps '<correct dependency edges>'`}),diagnosticLimit);return{check:{name:"dependency_references",status:activeRows.length===0?"ok":"warn",ok:activeRows.length===0,details:{checked_items:items.length,dangling_reference_count:activeRows.length+legacyRows.length,active_dangling_reference_count:activeRows.length,dangling_reference_rows:summarizedRows.values,dangling_reference_rows_truncated:summarizedRows.truncated,legacy_terminal_dangling_reference_count:legacyRows.length,legacy_closed_dangling_reference_count:classified.legacy_terminal.filter(row=>row.holder_status==="closed").length,legacy_terminal_dangling_reference_rows:summarizedLegacyRows.values,legacy_terminal_dangling_reference_rows_truncated:summarizedLegacyRows.truncated,no_active_blocker_sentinel_count:classified.no_active_blocker_sentinels.length,remediation_hints:hints.values,remediation_hints_truncated:hints.truncated}},warnings:activeRows.length>0?[`validate_dangling_dependency_references:${activeRows.length}`]:[]}}function extractItemIds(value,idPrefix="pm"){const normalizedPrefix=(idPrefix.trim().toLowerCase()||"pm").replace(/-+$/g,"");const pattern=new RegExp(`(?:^|[^a-z0-9-])(${escapeRegExp(normalizedPrefix)}-[a-z0-9][a-z0-9-]*)`,"gi");return[...new Set([...value.matchAll(pattern)].map(match=>match[1].toLowerCase()))].sort((left,right)=>left.localeCompare(right))}function findLifecycleDependencyCycleComponents(graph){let nextIndex=0;const indexById=new Map;const lowLinkById=new Map;const stack=[];const inStack=new Set;const components=[];const visit=id=>{indexById.set(id,nextIndex);lowLinkById.set(id,nextIndex);nextIndex+=1;stack.push(id);inStack.add(id);for(const dependencyId of graph.get(id)??[]){if(!indexById.has(dependencyId)){visit(dependencyId);lowLinkById.set(id,Math.min(lowLinkById.get(id),lowLinkById.get(dependencyId)))}else if(inStack.has(dependencyId)){lowLinkById.set(id,Math.min(lowLinkById.get(id),indexById.get(dependencyId)))}}if(lowLinkById.get(id)!==indexById.get(id)){return}const component=[];while(stack.length>0){const member=stack.pop();inStack.delete(member);component.push(member);if(member===id){break}}component.sort((left,right)=>left.localeCompare(right));components.push(component)};const sortedNodeIds=[...graph.keys()].sort((left,right)=>left.localeCompare(right));for(const id of sortedNodeIds){if(!indexById.has(id)){visit(id)}}const cycleComponents=components.filter(component=>{if(component.length>1){return true}const selfId=component[0];return(graph.get(selfId)??[]).includes(selfId)});return cycleComponents.sort((left,right)=>left[0].localeCompare(right[0])||left.length-right.length||left.join(",").localeCompare(right.join(",")))}function detectLifecycleDependencyCycles(activeItems,idPrefix="pm"){const graph=buildLifecycleDependencyGraph(activeItems,idPrefix);const cycleComponents=findLifecycleDependencyCycleComponents(graph);const cycleItemIds=[...new Set(cycleComponents.flat())].sort((left,right)=>left.localeCompare(right));const cycleSamplePaths=cycleComponents.map(component=>resolveLifecycleDependencyCycleSamplePath(component,graph).join("->"));return{cycle_count:cycleComponents.length,cycle_item_ids:cycleItemIds,cycle_sample_paths:cycleSamplePaths}}function classifyOrphanedPath(pathValue){if(pathValue.startsWith("docs/")){return"docs_unowned"}if(pathValue.startsWith("tests/")){return"tests_unowned"}if(pathValue.startsWith("src/")){return"source_unowned"}if(pathValue.endsWith(".md")){return"docs_unowned"}return"unlinked_existing"}function directoryOf(relativePath){const slash=relativePath.lastIndexOf("/");return slash===-1?"":relativePath.slice(0,slash)}function sharedDirectoryPrefixLength(left,right){const leftParts=directoryOf(left).split("/").filter(Boolean);const rightParts=directoryOf(right).split("/").filter(Boolean);let count=0;while(count<leftParts.length&&count<rightParts.length&&leftParts[count]===rightParts[count]){count+=1}return count}function scoreOrphanOwnerCandidate(pathValue,linkedPath){const linkedDir=directoryOf(linkedPath);const orphanDir=directoryOf(pathValue);const directoryPrefix=linkedPath.endsWith("/")?linkedPath:`${linkedPath}/`;const isDirectoryPrefix=pathValue.startsWith(directoryPrefix);const sameDirectory=linkedDir.length>0&&linkedDir===orphanDir;const sharedPrefixLength=sharedDirectoryPrefixLength(pathValue,linkedPath);if(!isDirectoryPrefix&&!sameDirectory&&sharedPrefixLength===0){return null}if(isDirectoryPrefix){return{score:linkedPath.length+1e3,confidence:"path_prefix"}}return sameDirectory?{score:sharedPrefixLength+500,confidence:"same_directory"}:{score:sharedPrefixLength,confidence:"shared_directory"}}function shouldReplaceOrphanOwnerCandidate(best,item,score){return best===void 0||score>best.score||score===best.score&&item.id.localeCompare(best.item.id)<0}function findOrphanOwnerCandidate(pathValue,classification,items){const linkKind=classification==="docs_unowned"?"docs":"files";let best;items.flatMap(item=>(linkKind==="docs"?item.docs??[]:item.files??[]).map(link=>({item,link}))).forEach(({item,link})=>{if(link.scope!=="project"){return}const linkedPath=normalizeRelativePath(link.path);if(linkedPath.length===0||linkedPath===pathValue){return}const scored=scoreOrphanOwnerCandidate(pathValue,linkedPath);if(scored===null){return}if(shouldReplaceOrphanOwnerCandidate(best,item,scored.score)){best={item,score:scored.score,confidence:scored.confidence}}});if(!best){return null}return{id:best.item.id,type:best.item.type,title:best.item.title,status:best.item.status,confidence:best.confidence}}function buildOrphanedPathRows(orphanedFiles,items){return orphanedFiles.map(pathValue=>{const classification=classifyOrphanedPath(pathValue);const linkCommand=classification==="docs_unowned"?"docs":"files";const ownerCandidate=findOrphanOwnerCandidate(pathValue,classification,items);const target=ownerCandidate?.id??"<id>";return{path:pathValue,classification,owner_candidate:ownerCandidate,remediation_hint:`pm ${linkCommand} ${target} --add path=${pathValue},scope=project,note="<why this artifact belongs to the item>"`}})}function summarizeOrphanedPathRows(rows){return rows.map(row=>`${row.path}:${row.classification} owner_candidate=${row.owner_candidate?.id??"unowned"} hint=${JSON.stringify(row.remediation_hint)}`)}function closureLikeFieldsForItem(item,lifecyclePatternPolicy){return Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns).filter(([field,patterns])=>{const value=toMeaningfulString(item[field]);return value?patterns.some(pattern=>value.toLowerCase().includes(pattern)):false}).map(([field])=>field).sort((left,right)=>left.localeCompare(right))}function buildTerminalParentFixRow(item,parent,itemsById,canonicalIdByLowercase,statusRegistry){const grandparentId=toMeaningfulString(parent.parent);const grandparent=grandparentId?itemsById.get(canonicalIdByLowercase.get(grandparentId.toLowerCase())??grandparentId):void 0;return{id:item.id,parent_id:parent.id,grandparent_id:grandparent?.id,grandparent_active:grandparent!==void 0&&!isTerminalStatus(grandparent.status,statusRegistry)}}function staleBlockerReasonsForItem(item,blockedStatuses,statusRegistry,lifecyclePatternPolicy){const blockedBy=toMeaningfulString(item.blocked_by);const blockedReason=toMeaningfulString(item.blocked_reason);const blockedReasonNormalized=blockedReason?.toLowerCase();const normalizedStatus=normalizeStatusForRegistry(item.status,statusRegistry);const reasons=[];if(!blockedStatuses.has(normalizedStatus)){if(blockedBy){reasons.push("non_blocked_status_has_blocked_by")}if(blockedReason){reasons.push("non_blocked_status_has_blocked_reason")}return reasons}if(!blockedBy&&!blockedReason){reasons.push("blocked_status_missing_blocker_context")}if(blockedReasonNormalized?.includes("no active blocker")){reasons.push("blocked_status_reason_reports_no_active_blocker")}if(blockedReasonNormalized&&lifecyclePatternPolicy.stale_blocker_reason_patterns.some(pattern=>blockedReasonNormalized.includes(pattern))){reasons.push("blocked_status_reason_matches_stale_pattern")}return reasons}function collectLifecycleScanRows(items,includeStaleBlockers,statusRegistry,lifecyclePatternPolicy){const itemsById=new Map(items.map(item=>[item.id,item]));const canonicalIdByLowercase=new Map(items.map(item=>[item.id.toLowerCase(),item.id]));const blockedStatuses=statusRegistry.blocked_statuses.size>0?statusRegistry.blocked_statuses:new Set(["blocked"]);const rows={activeItems:items.filter(item=>!isTerminalStatus(item.status,statusRegistry)),closureLikeRows:[],terminalParentRows:[],terminalParentFixRows:[],staleBlockerRows:[]};for(const item of rows.activeItems){const closureLikeFields=closureLikeFieldsForItem(item,lifecyclePatternPolicy);if(closureLikeFields.length>0){rows.closureLikeRows.push({id:item.id,fields:closureLikeFields})}const parentId=toMeaningfulString(item.parent);const parent=parentId?itemsById.get(canonicalIdByLowercase.get(parentId.toLowerCase())??parentId):void 0;if(parent&&isTerminalStatus(parent.status,statusRegistry)){rows.terminalParentRows.push({id:item.id,parent_id:parent.id,parent_status:parent.status});rows.terminalParentFixRows.push(buildTerminalParentFixRow(item,parent,itemsById,canonicalIdByLowercase,statusRegistry))}if(includeStaleBlockers){const reasons=staleBlockerReasonsForItem(item,blockedStatuses,statusRegistry,lifecyclePatternPolicy);if(reasons.length>0){rows.staleBlockerRows.push({id:item.id,status:item.status,reasons:[...new Set(reasons)].sort((left,right)=>left.localeCompare(right))})}}}return rows}function sortLifecycleScanRows(rows){rows.closureLikeRows.sort((left,right)=>left.id.localeCompare(right.id));rows.terminalParentRows.sort((left,right)=>left.id.localeCompare(right.id)||left.parent_id.localeCompare(right.parent_id));rows.terminalParentFixRows.sort((left,right)=>left.id.localeCompare(right.id)||left.parent_id.localeCompare(right.parent_id));rows.staleBlockerRows.sort((left,right)=>left.id.localeCompare(right.id))}function lifecycleCycleWarningToken(prefix,severity,count){if(count<=0||severity==="off"){return null}return`${severity==="error"?`${prefix}_error`:prefix}:${count}`}function lifecycleAdvisoryWarningToken(prefix,severity,count){return count>0&&severity!=="off"?`${prefix}:${count}`:null}function buildLifecycleWarnings(rows,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,counts){const warnings=[];if(rows.closureLikeRows.length>0){warnings.push(`validate_lifecycle_active_closure_like_metadata:${rows.closureLikeRows.length}`)}if(rows.terminalParentRows.length>0){warnings.push(`validate_lifecycle_active_terminal_parent:${rows.terminalParentRows.length}`)}if(includeStaleBlockers&&rows.staleBlockerRows.length>0){warnings.push(`validate_lifecycle_stale_blockers:${rows.staleBlockerRows.length}`)}const dependencyWarning=lifecycleCycleWarningToken("validate_lifecycle_dependency_cycles",dependencyCycleSeverity,counts.dependencyCycles);const parentWarning=lifecycleCycleWarningToken("validate_hierarchy_parent_cycle",parentCycleSeverity,counts.activeHierarchyCycles);const cardinalityWarning=lifecycleCycleWarningToken("validate_hierarchy_cardinality_violation",parentCycleSeverity,counts.activeHierarchyCardinality);const divergenceWarning=lifecycleCycleWarningToken("validate_hierarchy_parent_divergence",parentCycleSeverity,counts.activeHierarchyDivergence);const legacyCycleWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_parent_cycle",parentCycleSeverity,counts.legacyHierarchyCycles);const legacyCardinalityWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_cardinality_violation",parentCycleSeverity,counts.legacyHierarchyCardinality);const legacyDivergenceWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_parent_divergence",parentCycleSeverity,counts.legacyHierarchyDivergence);return[...warnings,...dependencyWarning?[dependencyWarning]:[],...parentWarning?[parentWarning]:[],...cardinalityWarning?[cardinalityWarning]:[],...divergenceWarning?[divergenceWarning]:[],...legacyCycleWarning?[legacyCycleWarning]:[],...legacyCardinalityWarning?[legacyCardinalityWarning]:[],...legacyDivergenceWarning?[legacyDivergenceWarning]:[]]}function linkedArtifactPathExceedsFilesystemLimits(artifactPath){const normalized=normalizeRelativePath(artifactPath);return normalized.length>LINKED_ARTIFACT_MAX_PATH_LENGTH||normalized.split(/[\\/]/).some(segment=>segment.length>LINKED_ARTIFACT_MAX_SEGMENT_LENGTH)}async function linkedArtifactIsMissing(workspaceRoot,artifactPath){const absolutePath=path.isAbsolute(artifactPath)?artifactPath:path.resolve(workspaceRoot,artifactPath);if(linkedArtifactPathExceedsFilesystemLimits(absolutePath)){return false}try{const stats=await fs.stat(absolutePath);return!stats.isFile()&&!stats.isDirectory()}catch(error){return hasFilesystemErrorCode(error,["ENOENT","ENOTDIR"])}}async function collectLinkedPathScanState(items,workspaceRoot){const state={linkedProjectPaths:new Set,remoteLinkedPaths:new Set,missingLinkedPaths:[],staleLinkRows:[]};const linkedArtifacts=items.flatMap(item=>[...(item.files??[]).map(artifact=>({item,artifact,link_kind:"files"})),...(item.docs??[]).map(artifact=>({item,artifact,link_kind:"docs"}))]);for(const{item,artifact,link_kind}of linkedArtifacts){if(artifact.scope!=="project"){continue}if(isRemoteLinkedArtifactReference(artifact.path)){state.remoteLinkedPaths.add(artifact.path.trim());continue}const normalizedPath=normalizeRelativePath(artifact.path);if(normalizedPath.length===0){continue}state.linkedProjectPaths.add(normalizedPath);if(await linkedArtifactIsMissing(workspaceRoot,artifact.path)){state.missingLinkedPaths.push(normalizedPath);state.staleLinkRows.push({item_id:item.id,path:normalizedPath,link_kind})}}return state}function partitionFileCandidates(fileCandidates,pmRoot,workspaceRoot,fileScanMode,includePmInternals,verboseFileLists){const strictTrackedAllMode=fileScanMode==="tracked-all-strict";const strictModeForcesPmInternals=strictTrackedAllMode&&!includePmInternals;const includePmInternalsEffective=includePmInternals||strictTrackedAllMode;const pmInternalCandidatePrefixes=includePmInternalsEffective?[]:resolvePmInternalCandidatePrefixes(pmRoot,workspaceRoot);const excludedPmInternalPaths=pmInternalCandidatePrefixes.length===0?[]:fileCandidates.candidateFiles.filter(candidate=>hasPathPrefix(candidate,pmInternalCandidatePrefixes));const candidateFiles=pmInternalCandidatePrefixes.length===0?fileCandidates.candidateFiles:fileCandidates.candidateFiles.filter(candidate=>!hasPathPrefix(candidate,pmInternalCandidatePrefixes));const excludedByReason={};if(excludedPmInternalPaths.length>0){const summarizedPmInternalPaths=summarizeFileList(excludedPmInternalPaths,verboseFileLists);excludedByReason.pm_internals={count:excludedPmInternalPaths.length,paths:summarizedPmInternalPaths.values,paths_truncated:summarizedPmInternalPaths.truncated,paths_total:summarizedPmInternalPaths.total}}return{strictTrackedAllMode,strictModeForcesPmInternals,includePmInternalsEffective,pmInternalCandidatePrefixes,excludedPmInternalPaths,candidateFiles,excludedByReason}}function buildLifecycleCheck(items,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,statusRegistry,lifecyclePatternPolicy,verboseDiagnostics,idPrefix="pm"){const rows=collectLifecycleScanRows(items,includeStaleBlockers,statusRegistry,lifecyclePatternPolicy);sortLifecycleScanRows(rows);const dependencyCycleDiagnostics=detectLifecycleDependencyCycles(rows.activeItems,idPrefix);const parentCycleDiagnostics=detectLifecycleParentCycles(items,statusRegistry);const statusRoleDiagnostics=inspectStatusRoleAssignments(statusRegistry,items,verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT);const warnings=[...buildLifecycleWarnings(rows,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,{dependencyCycles:dependencyCycleDiagnostics.cycle_count,activeHierarchyCycles:parentCycleDiagnostics.active_cycle_count,activeHierarchyCardinality:parentCycleDiagnostics.active_cardinality_violation_count,activeHierarchyDivergence:parentCycleDiagnostics.active_parent_divergence_count,legacyHierarchyCycles:parentCycleDiagnostics.legacy_cycle_count,legacyHierarchyCardinality:parentCycleDiagnostics.legacy_cardinality_violation_count,legacyHierarchyDivergence:parentCycleDiagnostics.legacy_parent_divergence_count}),...buildStatusRoleWarnings(statusRoleDiagnostics)];const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedClosureLikeRows=summarizeList(rows.closureLikeRows.map(row=>`${row.id}:${row.fields.join(",")}`),diagnosticLimit);const summarizedTerminalParentRows=summarizeList(rows.terminalParentRows.map(row=>`${row.id}:${row.parent_id}:${row.parent_status}`),diagnosticLimit);const summarizedStaleBlockerRows=summarizeList(rows.staleBlockerRows.map(row=>`${row.id}:${row.status}:${row.reasons.join(",")}`),diagnosticLimit);const summarizedDependencyCycleItemIds=summarizeList(dependencyCycleDiagnostics.cycle_item_ids,diagnosticLimit);const summarizedDependencyCycleSamplePaths=summarizeList(dependencyCycleDiagnostics.cycle_sample_paths,diagnosticLimit);const summarizedParentCycleItemIds=summarizeList(parentCycleDiagnostics.cycle_item_ids,diagnosticLimit);const summarizedParentCycleSamplePaths=summarizeList(parentCycleDiagnostics.cycle_sample_paths,diagnosticLimit);const summarizedHierarchyCardinalityRows=summarizeList(parentCycleDiagnostics.cardinality_violation_rows,diagnosticLimit);const summarizedHierarchyDivergenceRows=summarizeList(parentCycleDiagnostics.parent_divergence_rows,diagnosticLimit);const hasErrorSeverityCycle=dependencyCycleDiagnostics.cycle_count>0&&dependencyCycleSeverity==="error"||(parentCycleDiagnostics.active_cycle_count>0||parentCycleDiagnostics.active_cardinality_violation_count>0||parentCycleDiagnostics.active_parent_divergence_count>0)&&parentCycleSeverity==="error";return{check:{name:"lifecycle",status:hasErrorSeverityCycle?"error":warnings.length===0?"ok":"warn",ok:!hasErrorSeverityCycle&&warnings.length===0,details:{checked_active_items:rows.activeItems.length,lifecycle_status_roles:statusRoleDiagnostics,active_closure_like_metadata_items:rows.closureLikeRows.length,active_closure_like_metadata_rows:summarizedClosureLikeRows.values,active_closure_like_metadata_rows_truncated:summarizedClosureLikeRows.truncated,active_terminal_parent_items:rows.terminalParentRows.length,active_terminal_parent_rows:summarizedTerminalParentRows.values,active_terminal_parent_rows_truncated:summarizedTerminalParentRows.truncated,stale_blocker_checks_enabled:includeStaleBlockers,stale_blocker_items:rows.staleBlockerRows.length,stale_blocker_rows:summarizedStaleBlockerRows.values,stale_blocker_rows_truncated:summarizedStaleBlockerRows.truncated,dependency_cycle_severity_policy:dependencyCycleSeverity,dependency_cycle_count:dependencyCycleDiagnostics.cycle_count,dependency_cycle_item_count:dependencyCycleDiagnostics.cycle_item_ids.length,dependency_cycle_item_ids:summarizedDependencyCycleItemIds.values,dependency_cycle_item_ids_truncated:summarizedDependencyCycleItemIds.truncated,dependency_cycle_sample_paths:summarizedDependencyCycleSamplePaths.values,dependency_cycle_sample_paths_truncated:summarizedDependencyCycleSamplePaths.truncated,parent_cycle_severity_policy:parentCycleSeverity,parent_cycle_count:parentCycleDiagnostics.cycle_count,active_parent_cycle_count:parentCycleDiagnostics.active_cycle_count,legacy_parent_cycle_count:parentCycleDiagnostics.legacy_cycle_count,parent_cycle_item_count:parentCycleDiagnostics.cycle_item_ids.length,parent_cycle_item_ids:summarizedParentCycleItemIds.values,parent_cycle_item_ids_truncated:summarizedParentCycleItemIds.truncated,parent_cycle_sample_paths:summarizedParentCycleSamplePaths.values,parent_cycle_sample_paths_truncated:summarizedParentCycleSamplePaths.truncated,hierarchy_cardinality_violation_count:parentCycleDiagnostics.cardinality_violation_count,active_hierarchy_cardinality_violation_count:parentCycleDiagnostics.active_cardinality_violation_count,legacy_hierarchy_cardinality_violation_count:parentCycleDiagnostics.legacy_cardinality_violation_count,hierarchy_cardinality_violation_rows:summarizedHierarchyCardinalityRows.values,hierarchy_cardinality_violation_rows_truncated:summarizedHierarchyCardinalityRows.truncated,hierarchy_parent_divergence_count:parentCycleDiagnostics.parent_divergence_count,active_hierarchy_parent_divergence_count:parentCycleDiagnostics.active_parent_divergence_count,legacy_hierarchy_parent_divergence_count:parentCycleDiagnostics.legacy_parent_divergence_count,hierarchy_parent_divergence_rows:summarizedHierarchyDivergenceRows.values,hierarchy_parent_divergence_rows_truncated:summarizedHierarchyDivergenceRows.truncated,stale_blocker_reason_patterns:[...lifecyclePatternPolicy.stale_blocker_reason_patterns],stale_blocker_reason_pattern_source:lifecyclePatternPolicy.stale_blocker_reason_pattern_source,closure_like_blocked_reason_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.blocked_reason],closure_like_blocked_reason_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.blocked_reason,closure_like_resolution_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.resolution],closure_like_resolution_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.resolution,closure_like_actual_result_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.actual_result],closure_like_actual_result_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.actual_result}},warnings,terminalParentFixRows:rows.terminalParentFixRows}}async function buildFilesCheck(items,workspaceRoot,pmRoot,fileScanMode,includePmInternals,verboseFileLists,statusRegistry=resolveRuntimeStatusRegistry(SETTINGS_DEFAULTS.schema)){const linkedPathState=await collectLinkedPathScanState(items,workspaceRoot);const itemsById=new Map(items.map(item=>[item.id,item]));const uniqueMissingLinkedPaths=[...new Set(linkedPathState.missingLinkedPaths)].sort((left,right)=>left.localeCompare(right));const fileCandidates=await collectProjectFileCandidates(workspaceRoot,fileScanMode);const partition=partitionFileCandidates(fileCandidates,pmRoot,workspaceRoot,fileScanMode,includePmInternals,verboseFileLists);const orphanedFiles=partition.candidateFiles.filter(candidate=>!linkedPathState.linkedProjectPaths.has(candidate));const orphanedPathRows=buildOrphanedPathRows(orphanedFiles,items);const classifiedStalePaths=classifyStaleLinkedPaths(uniqueMissingLinkedPaths,partition.candidateFiles);const classificationByPath=new Map(classifiedStalePaths.map(entry=>[entry.path,entry.classification]));const movedStalePathCount=classifiedStalePaths.filter(entry=>entry.classification==="moved").length;const staleLinkPruneRows=linkedPathState.staleLinkRows.map(row=>({...row,classification:classificationByPath.get(row.path)??"deleted"})).sort((left,right)=>left.item_id.localeCompare(right.item_id)||left.path.localeCompare(right.path)||left.link_kind.localeCompare(right.link_kind));const warnings=[];if(partition.strictModeForcesPmInternals){warnings.push("validate_files_tracked_all_strict_forces_pm_internals")}if(orphanedFiles.length>0){warnings.push(`validate_files_orphaned_paths:${orphanedFiles.length}`)}const uniqueRemoteLinkedPaths=[...linkedPathState.remoteLinkedPaths].sort((left,right)=>left.localeCompare(right));const summarizedRemote=summarizeFileList(uniqueRemoteLinkedPaths,verboseFileLists);const summarizedMissing=summarizeFileList(uniqueMissingLinkedPaths,verboseFileLists);const summarizedOrphaned=summarizeFileList(orphanedFiles,verboseFileLists);const summarizedOrphanedClassifications=summarizeFileList(orphanedPathRows.map(row=>`${row.path}:${row.classification}:owner_candidate=${row.owner_candidate?.id??"unowned"}`),verboseFileLists);const orphanedPathRowDetail=verboseFileLists?orphanedPathRows:summarizeFileList(summarizeOrphanedPathRows(orphanedPathRows),false).values;const summarizedClassifications=summarizeFileList(summarizeStaleLinkedPathClassifications(classifiedStalePaths),verboseFileLists);const missingLinkedPathRows=staleLinkPruneRows;const repairReport=buildLinkedFileRepairReport(missingLinkedPathRows,classifiedStalePaths,id=>itemsById.get(id),statusRegistry,verboseFileLists?Infinity:FILE_LIST_SUMMARY_LIMIT);if(repairReport.active_missing_linked_paths_count>0){warnings.push(`validate_files_missing_linked_paths:${repairReport.active_missing_linked_paths_count}`)}return{check:{name:"files",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{workspace_root:workspaceRoot,scan_mode_requested:fileCandidates.requestedMode,scan_mode_applied:fileCandidates.appliedMode,strict_tracked_all_mode:partition.strictTrackedAllMode,strict_mode_forces_pm_internals:partition.strictModeForcesPmInternals,strict_mode_forces_pm_internals_notice:partition.strictModeForcesPmInternals?"tracked-all-strict force-enables PM internals; pass --include-pm-internals to make inclusion explicit.":null,file_list_detail_mode:verboseFileLists?"full":"summary",file_list_summary_limit:FILE_LIST_SUMMARY_LIMIT,candidate_scan_source:fileCandidates.source,include_pm_internals:partition.includePmInternalsEffective,include_pm_internals_requested:includePmInternals,pm_internal_candidate_prefixes:partition.pmInternalCandidatePrefixes,pm_internal_excluded_count:partition.excludedPmInternalPaths.length,excluded_total:partition.excludedPmInternalPaths.length,excluded_by_reason:partition.excludedByReason,linked_project_paths:linkedPathState.linkedProjectPaths.size,remote_linked_paths_count:uniqueRemoteLinkedPaths.length,remote_linked_paths_total:summarizedRemote.total,remote_linked_paths:summarizedRemote.values,remote_linked_paths_truncated:summarizedRemote.truncated,candidate_total_raw:fileCandidates.candidateTotal,candidate_scanned_raw:fileCandidates.candidateScanned,candidate_total:partition.candidateFiles.length,candidate_scanned:partition.candidateFiles.length,scanned_candidate_files:partition.candidateFiles.length,missing_linked_paths_count:uniqueMissingLinkedPaths.length,missing_linked_paths_total:summarizedMissing.total,missing_linked_paths:summarizedMissing.values,missing_linked_paths_truncated:summarizedMissing.truncated,missing_linked_paths_moved_count:movedStalePathCount,missing_linked_paths_deleted_count:classifiedStalePaths.filter(entry=>entry.classification==="deleted").length,missing_linked_paths_malformed_count:classifiedStalePaths.filter(entry=>entry.classification==="malformed").length,missing_linked_path_classifications:summarizedClassifications.values,missing_linked_path_classifications_truncated:summarizedClassifications.truncated,...repairReport,orphaned_paths_count:orphanedFiles.length,orphaned_paths_total:summarizedOrphaned.total,orphaned_paths:summarizedOrphaned.values,orphaned_paths_truncated:summarizedOrphaned.truncated,orphaned_path_classifications:summarizedOrphanedClassifications.values,orphaned_path_classifications_truncated:summarizedOrphanedClassifications.truncated,orphaned_path_rows_count:orphanedPathRows.length,orphaned_path_rows:orphanedPathRowDetail}},warnings,staleLinkPruneRows}}function summarizeCommandPreview(command){const normalizedCommand=command.trim().replaceAll(/\s+/g," ");return normalizedCommand.length>120?`${normalizedCommand.slice(0,117)}...`:normalizedCommand}function summarizeCommandReferenceRow(ownerId,referencedId,command){return`${ownerId}:${referencedId}:${summarizeCommandPreview(command)}`}function buildUntrustedLinkedTestRows(linkedTests,trustDecisions){const rows=[];linkedTests.forEach(({item,linkedTest},index)=>{const trust=trustDecisions[index];if(trust.trusted)return;const command=summarizeCommandPreview(linkedTest.command??"");rows.push(`${item.id}:${trust.source_ref??"unknown"}->${trust.current_source_ref??"unknown"}:${command}`)});return rows}async function buildCommandReferencesCheck(items,idPrefix,verboseDiagnostics,pmRoot){const knownIds=new Set(items.map(item=>item.id.toLowerCase()));let linkedCommandsScanned=0;let referencedPmIdCount=0;const referencedPmIds=new Set;const staleReferenceRows=[];const linkedTests=items.flatMap(item=>(item.tests??[]).map(linkedTest=>({item,linkedTest})));const currentSourceRef=await resolveLinkedTestSourceRef(resolveLinkedTestSourceWorkspaceRoot());const trustDecisions=await resolveLinkedTestTrustBatch(pmRoot,linkedTests.map(({linkedTest})=>linkedTest),currentSourceRef);const untrustedRows=buildUntrustedLinkedTestRows(linkedTests,trustDecisions);for(const{item,linkedTest}of linkedTests){if(typeof linkedTest.command!=="string"||linkedTest.command.trim().length===0){continue}linkedCommandsScanned+=1;const referencedIds=extractReferencedPmItemIdsFromCommand(linkedTest.command,idPrefix);if(referencedIds.length===0){continue}referencedPmIdCount+=referencedIds.length;for(const referencedId of referencedIds){referencedPmIds.add(referencedId);if(!knownIds.has(referencedId.toLowerCase())){staleReferenceRows.push(summarizeCommandReferenceRow(item.id,referencedId,linkedTest.command))}}}const uniqueStaleReferenceRows=[...new Set(staleReferenceRows)].sort((left,right)=>left.localeCompare(right));const stalePmIds=[...new Set(uniqueStaleReferenceRows.map(row=>row.split(":")[1]??""))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right));const warnings=[];if(uniqueStaleReferenceRows.length>0){warnings.push(`validate_command_references_stale_pm_ids:${uniqueStaleReferenceRows.length}`)}if(untrustedRows.length>0){warnings.push(`validate_linked_test_trust_unacknowledged:${untrustedRows.length}`)}const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(uniqueStaleReferenceRows,diagnosticLimit);const summarizedStalePmIds=summarizeList(stalePmIds,diagnosticLimit);const summarizedReferencedPmIds=summarizeList([...referencedPmIds].sort((left,right)=>left.localeCompare(right)),diagnosticLimit);const summarizedUntrustedRows=summarizeList(untrustedRows,diagnosticLimit);return{check:{name:"command_references",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{checked_items:items.length,linked_commands_scanned:linkedCommandsScanned,referenced_pm_ids_count:referencedPmIdCount,unique_referenced_pm_ids_count:referencedPmIds.size,unique_referenced_pm_ids:summarizedReferencedPmIds.values,unique_referenced_pm_ids_truncated:summarizedReferencedPmIds.truncated,linked_test_trust_current_source_ref:currentSourceRef??null,untrusted_linked_tests_count:untrustedRows.length,untrusted_linked_tests:summarizedUntrustedRows.values,untrusted_linked_tests_truncated:summarizedUntrustedRows.truncated,stale_pm_id_references_count:uniqueStaleReferenceRows.length,stale_pm_ids_count:stalePmIds.length,stale_pm_ids:summarizedStalePmIds.values,stale_pm_ids_truncated:summarizedStalePmIds.truncated,stale_pm_id_reference_rows:summarizedRows.values,stale_pm_id_reference_rows_truncated:summarizedRows.truncated}},warnings}}function buildFormatVersionCheck(items,verboseDiagnostics){const scan=scanItemFormatVersions(items.map(item=>({ref:item.id,version:effectiveItemFormatVersion(item)})));const warnings=[];if(scan.outdated.length>0){warnings.push(`validate_format_version_outdated_items:${scan.outdated.length}`)}if(scan.ahead.length>0){warnings.push(`validate_format_version_ahead_items:${scan.ahead.length}`)}const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedOutdated=summarizeList(scan.outdated,diagnosticLimit);const summarizedAhead=summarizeList(scan.ahead,diagnosticLimit);const status=scan.ahead.length>0?"error":scan.outdated.length>0?"warn":"ok";return{check:{name:"format_version",status,ok:status==="ok",details:{checked_items:items.length,current_format_version:CURRENT_ITEM_FORMAT_VERSION,outdated_items_count:scan.outdated.length,outdated_items:summarizedOutdated.values,outdated_items_truncated:summarizedOutdated.truncated,ahead_items_count:scan.ahead.length,ahead_items:summarizedAhead.values,ahead_items_truncated:summarizedAhead.truncated}},warnings}}const VALIDATE_AUTO_FIX_MESSAGE="pm validate auto-fix";async function applyValidateFix(fix,global2,services){switch(fix.kind){case"set_resolution":case"set_close_reason":case"set_estimate":case"reparent":case"unset_parent":{const updateOptions={message:VALIDATE_AUTO_FIX_MESSAGE};if(fix.kind==="set_resolution"){updateOptions.resolution=fix.value}else if(fix.kind==="set_close_reason"){updateOptions.closeReason=fix.value}else if(fix.kind==="set_estimate"){updateOptions.estimatedMinutes=fix.value}else if(fix.kind==="reparent"){updateOptions.parent=fix.parent_id}else{updateOptions.unset=["parent"]}if(!services.runUpdate){throw new PmCliError("Applying validate metadata/lifecycle fixes requires a runUpdate mutation service.",EXIT_CODE.USAGE)}await services.runUpdate(fix.item_id,updateOptions,global2);return}case"prune_file_link":{throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`)}case"prune_doc_link":{throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`)}}}function pruneBatchKey(fix){if(fix.kind!=="prune_file_link"&&fix.kind!=="prune_doc_link"){return null}return`${fix.kind}:${fix.item_id}`}async function applyValidateFixes(applicable,global2,services){const applied=[];const failed=[];const pruneBatches=new Map;for(const fix of applicable.filter(candidate=>pruneBatchKey(candidate)===null)){try{await applyValidateFix(fix,global2,services);applied.push(fix)}catch(error){failed.push({fix,error})}}for(const fix of applicable.filter(candidate=>pruneBatchKey(candidate)!==null)){const batchKey=pruneBatchKey(fix);const existing=pruneBatches.get(batchKey);if(existing){existing.push(fix)}else{pruneBatches.set(batchKey,[fix])}}for(const batch of pruneBatches.values()){const first=batch[0];if(!first){continue}const remove=batch.map(fix=>fix.path).filter(value=>typeof value==="string"&&value.length>0);try{if(first.kind==="prune_file_link"){await runFiles(first.item_id,{remove,message:VALIDATE_AUTO_FIX_MESSAGE},global2)}else{await runDocs(first.item_id,{remove,message:VALIDATE_AUTO_FIX_MESSAGE},global2)}applied.push(...batch)}catch(error){failed.push(...batch.map(fix=>({fix,error})))}}return{applied,failed}}const _testOnlyValidateCommand={applyValidateFix,applyValidateFixes,attachValidateFixHints,buildCommandReferencesCheck,buildDependencyReferencesCheck,buildCloseReasonBackfillRows,buildFilesCheck,buildLifecycleCheck,buildLifecycleDependencyGraph,buildLifecycleParentGraph,buildEstimateBackfillRows,buildMetadataCounts,buildMissingFieldOccurrences,buildOrphanedPathRows,classifyOrphanedPath,collectDefaultProjectFileCandidates,collectTrackedGitFileCandidates,detectLifecycleDependencyCycles,detectLifecycleParentCycles,escapeRegExp,extractItemIds,findLifecycleDependencyCycleComponents,isMetadataFieldMissing,linkedArtifactPathExceedsFilesystemLimits,listFilesRecursive,resolveDependencyCycleSeverity,resolveParentCycleSeverity,resolveFileScanMode,resolveLifecycleDependencyCycleSamplePath,resolveRequestedChecks,resolveValidateMetadataProfile,resolveWorkspaceRoot,sharedDirectoryPrefixLength,summarizeOrphanedPathRows,summarizeDuplicateIssueCodes,toMeaningfulString};function appendInvalidMergeReceiptEvidenceWarning(warnings,invalidEvidenceCount){if(invalidEvidenceCount>0){warnings.push(`merge_receipt_evidence_invalid:${invalidEvidenceCount}`)}}async function buildStorageIntegrityCheck(pmRoot,items,typeToFolder,settings){const scan=await scanStorageIntegrity(pmRoot,new Set(items.map(item=>item.id)),typeToFolder,{schema:settings.schema,extensionFieldNames:collectRegisteredItemFieldNames(getActiveExtensionRegistrations())});const warnings=[];if(scan.unreadable_item_files.length>0){warnings.push(`validate_storage_unreadable_items:${scan.unreadable_item_files.length}`)}if(scan.duplicate_item_ids.length>0){warnings.push(`validate_storage_duplicate_item_ids:${scan.duplicate_item_ids.length}`)}if(scan.history_conflict_marker_streams.length>0){warnings.push(`validate_storage_history_conflict_markers:${scan.history_conflict_marker_streams.length}`)}if(scan.history_unparseable_streams.length>0){warnings.push(`validate_storage_unparseable_history:${scan.history_unparseable_streams.length}`)}if(scan.resurrected_items.length>0){warnings.push(`validate_storage_resurrected_items:${scan.resurrected_items.length}`)}if(scan.unparseable_config_files.length>0){warnings.push(`validate_storage_unparseable_config:${scan.unparseable_config_files.length}`)}const errorCount=warnings.length;const trackedRuntimeCache=await scanTrackedRuntimeCache(pmRoot);if(trackedRuntimeCache.tracked_path_count>0){warnings.push(`validate_storage_tracked_runtime_cache_files:${trackedRuntimeCache.tracked_path_count}`)}const fenceAudit=await auditMergeAttributeFence(pmRoot,resolveProjectMergeTypeFolders(settings));if(fenceAudit.status==="drift"){warnings.push(`validate_merge_fence_drift:${fenceAudit.missing_patterns.length+fenceAudit.stale_patterns.length}`)}const gitWorkspaceRoot=await findGitWorkspaceRoot(pmRoot);const mergeDriverAudit=gitWorkspaceRoot===null?null:await auditMergeDriverConfiguration(gitWorkspaceRoot);if(mergeDriverAudit!==null&&mergeDriverAudit.status!=="ok"){warnings.push(`validate_merge_driver_configuration:${mergeDriverAudit.missing_keys.length+mergeDriverAudit.drifted_keys.length}`)}const mergeReceiptEvidence=await inspectMergeReceiptEvidence(gitWorkspaceRoot??pmRoot,{includeLossless:true,pmRoot});const pendingMergeReceipts=mergeReceiptEvidence.receipts;const{pendingDecisions:pendingMergeDecisions,lossless:losslessMergeReceipts}=partitionMergeReceipts(pendingMergeReceipts);if(pendingMergeDecisions.length>0){warnings.push(`validate_merge_decisions_unreviewed:${pendingMergeDecisions.length}`)}appendInvalidMergeReceiptEvidenceWarning(warnings,mergeReceiptEvidence.invalid_evidence_count);const status=errorCount>0?"error":warnings.length>0?"warn":"ok";return{check:{name:"storage_integrity",status,ok:status==="ok",details:{...scan,merge_fence:fenceAudit,merge_driver_configuration:mergeDriverAudit,pending_merge_decision_count:pendingMergeDecisions.length,pending_merge_decision_items:[...new Set(pendingMergeDecisions.map(receipt=>receipt.item_id))].sort((left,right)=>left.localeCompare(right)),lossless_merge_receipt_count:losslessMergeReceipts.length,invalid_merge_receipt_evidence_count:mergeReceiptEvidence.invalid_evidence_count,invalid_merge_receipt_evidence_details:mergeReceiptEvidence.invalid_evidence,invalid_merge_receipt_evidence_details_truncated:mergeReceiptEvidence.invalid_evidence_truncated,lossless_merge_receipt_items:[...new Set(losslessMergeReceipts.map(receipt=>receipt.item_id))].sort((left,right)=>left.localeCompare(right)),tracked_runtime_cache:{tracker_relative_root:trackedRuntimeCache.tracker_relative_root,tracked_paths:trackedRuntimeCache.tracked_paths,tracked_path_count:trackedRuntimeCache.tracked_path_count,remediation_command:trackedRuntimeCache.remediation_command}}},warnings}}function recordValidateCheck(state,built,fixHintsEnabled){if(fixHintsEnabled){attachValidateFixHints(built.check,built.warnings)}state.checks.push(built.check);state.warnings.push(...built.warnings)}async function executeRequestedValidateChecks(params){const state={checks:[],warnings:[...params.initialWarnings],closeReasonBackfillRows:[],estimateBackfillRows:[],resolutionBackfillRows:[],terminalParentFixRows:[],staleLinkPruneRows:[]};const fixHintsEnabled=params.options.fixHints===true;const fullDiagnostics=params.options.verboseDiagnostics===true||params.options.allAffectedIds===true||params.global.json===true;if(params.requestedChecks.has("completeness")){const built=await readWorkflowCompletenessCheck(params.pmRoot,params.items,fullDiagnostics?Infinity:DIAGNOSTIC_LIST_SUMMARY_LIMIT,params.sourceIncomplete);recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("metadata")){const built=buildMetadataCheck(params.items,params.metadataPolicy,params.statusRegistry,fullDiagnostics,[params.settings.id_prefix]);state.closeReasonBackfillRows=built.closeReasonBackfillRows;state.estimateBackfillRows=built.estimateBackfillRows;recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("resolution")){const built=buildResolutionCheck(params.items,params.statusRegistry,fullDiagnostics);state.resolutionBackfillRows=built.resolutionBackfillRows;recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("lifecycle")){const built=buildLifecycleCheck(params.items,Boolean(params.options.checkStaleBlockers),params.dependencyCycleSeverity,params.parentCycleSeverity,params.statusRegistry,params.lifecyclePatternPolicy,fullDiagnostics,params.settings.id_prefix);state.terminalParentFixRows=built.terminalParentFixRows;recordValidateCheck(state,built,fixHintsEnabled);recordValidateCheck(state,buildDependencyReferencesCheck(params.items,fullDiagnostics,params.statusRegistry),fixHintsEnabled)}if(params.requestedChecks.has("files")){const built=await buildFilesCheck(params.items,params.workspaceRoot,params.pmRoot,params.fileScanMode,Boolean(params.options.includePmInternals),Boolean(params.options.verboseFileLists),params.statusRegistry);state.staleLinkPruneRows=built.staleLinkPruneRows;recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("command_references")){recordValidateCheck(state,await buildCommandReferencesCheck(params.items,params.settings.id_prefix,fullDiagnostics,params.pmRoot),fixHintsEnabled)}if(params.requestedChecks.has("history_drift")){recordValidateCheck(state,await buildValidateHistoryDriftCheck(params.pmRoot,params.items,fullDiagnostics),fixHintsEnabled)}if(params.requestedChecks.has("format_version")){recordValidateCheck(state,buildFormatVersionCheck(params.items,fullDiagnostics),fixHintsEnabled)}if(params.requestedChecks.has("storage_integrity")){recordValidateCheck(state,await buildStorageIntegrityCheck(params.pmRoot,params.items,resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,params.settings),fixHintsEnabled)}return state}function planValidateFixes(options,state,settings){const planned=[];if(options.autoFix===true){planned.push(...planCloseReasonBackfillFixes(state.closeReasonBackfillRows));planned.push(...planResolutionBackfillFixes(state.resolutionBackfillRows));planned.push(...planEstimateBackfillFixes(state.estimateBackfillRows,settings.validation.estimate_defaults_by_type));planned.push(...planTerminalParentFixes(state.terminalParentFixRows))}if(options.pruneMissing===true){planned.push(...planStaleLinkPruneFixes(state.staleLinkPruneRows))}return planned}async function buildValidateFixesSummary(options,state,settings,grantedFixScopes,global2,services){if(options.autoFix!==true&&options.pruneMissing!==true){return void 0}const planned=planValidateFixes(options,state,settings);const{applicable,gated}=partitionFixesByGrant(planned,grantedFixScopes);const dryRun=options.dryRun===true;const appliedFixRows=[];const failedFixRows=[];if(!dryRun){const applied=await applyValidateFixes(applicable,global2,services);appliedFixRows.push(...applied.applied.map(toFixOutputRow));failedFixRows.push(...applied.failed.map(({fix,error})=>({...toFixOutputRow(fix),error:error instanceof Error?error.message:String(error)})))}return{mode:dryRun?"dry_run":"apply",auto_fix:options.autoFix===true,prune_missing:options.pruneMissing===true,granted_fix_scopes:[...grantedFixScopes].sort((left,right)=>left.localeCompare(right)),planned_count:planned.length,applied_count:appliedFixRows.length,gated_count:gated.length,failed_count:failedFixRows.length,planned_fixes:planned.map(toFixOutputRow),applied_fixes:appliedFixRows,gated_fixes:gated.map(fix=>({...toFixOutputRow(fix),gate_hint:`Withheld: re-run with --fix-scope ${fix.gate} to apply.`})),failed_fixes:failedFixRows}}async function runValidate(options,global2,services={}){assertProjectionModeChoice(options.counts===true,options.full===true,"--counts");const fixesRequested=options.autoFix===true||options.pruneMissing===true;if(options.dryRun===true&&!fixesRequested){throw new PmCliError("--dry-run requires --auto-fix or --prune-missing (there is nothing to preview otherwise).",EXIT_CODE.USAGE)}if(options.fixScope!==void 0&&options.fixScope.length>0&&options.autoFix!==true){throw new PmCliError("--fix-scope requires --auto-fix.",EXIT_CODE.USAGE)}const grantedFixScopes=resolveGrantedFixScopes(options.fixScope);const pmRoot=resolvePmRoot(process.cwd(),global2.path);await assertInitializedTracker(pmRoot);const settings=await readSettings(pmRoot);const statusRegistry=resolveRuntimeStatusRegistry(settings.schema);const typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());const requestedChecks=resolveRequestedChecks(options);const itemReadWarnings=[];const items=await readValidateItems({includeBody:["history_drift","metadata","completeness"].some(check=>requestedChecks.has(check)),pmRoot,settings,typeToFolder:typeRegistry.type_to_folder,warnings:itemReadWarnings});const sourceIncomplete=itemReadWarnings.length>0;if(requestedChecks.has("history_drift")){const authorAttribution=await scanHistoryAuthorAttribution(pmRoot);if(authorAttribution.actionable_unknown_event_count>0){itemReadWarnings.push(`validate_history_unknown_author_events:${authorAttribution.actionable_unknown_event_count}`)}}const metadataProfileSource=typeof options.metadataProfile==="string"?"option":"settings";const metadataProfile=resolveValidateMetadataProfile(typeof options.metadataProfile==="string"?options.metadataProfile:settings.validation.metadata_profile);const metadataPolicy=resolveValidateMetadataPolicy(metadataProfile,metadataProfileSource,settings.validation.metadata_required_fields);const lifecyclePatternPolicy=resolveLifecyclePatternPolicy(settings);const dependencyCycleSeverity=resolveDependencyCycleSeverity(options.dependencyCycleSeverity);const parentCycleSeverity=resolveParentCycleSeverity(options.parentCycleSeverity);const fileScanMode=resolveFileScanMode(options.scanMode);const workspaceRoot=resolveWorkspaceRoot(pmRoot);const state=await executeRequestedValidateChecks({requestedChecks,options,global:global2,pmRoot,workspaceRoot,settings,items,statusRegistry,metadataPolicy,lifecyclePatternPolicy,dependencyCycleSeverity,parentCycleSeverity,fileScanMode,initialWarnings:[...new Set(itemReadWarnings)],sourceIncomplete});const fixes=fixesRequested?await buildValidateFixesSummary(options,state,settings,grantedFixScopes,global2,services):void 0;const normalizedWarnings=[...new Set(state.warnings)].sort((left,right)=>left.localeCompare(right));const hasErrors=state.checks.some(check=>check.status==="error");const result={ok:!hasErrors,has_warnings:normalizedWarnings.length>0,checks:state.checks,warnings:normalizedWarnings,...fixes!==void 0?{fixes}:{},generated_at:nowIso(),projection:{mode:"full",declared_field_groups:[{name:"diagnostic_rows",restore_with:"--full"}],included_field_groups:["diagnostic_rows"]}};if(options.counts!==true)return result;return{...projectValidateCounts(result),projection:{mode:"counts",declared_field_groups:[{name:"diagnostic_rows",restore_with:"--full"}],included_field_groups:[]}}}export{_testOnlyValidateCommand,projectValidateCounts,runValidate};
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1ffaaceb-cc25-5d2f-a840-763ba8c7e81f")}catch(e2){}})();import{assertInitializedTracker}from"../environment/tracker-preflight.js";import{applyClosureTimestampFix,scanClosureTimestamps}from"./closure-timestamps.js";import{readWorkflowCompletenessCheck}from"./workflow-completeness.js";import fs from"node:fs/promises";import{realpathSync}from"node:fs";import{execFile}from"node:child_process";import path from"node:path";import{promisify}from"node:util";import{buildRemediationCommands}from"../../core/diagnostics/remediation.js";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{collectRegisteredItemFieldNames}from"../../core/extensions/item-fields.js";import{isFileMissingError}from"../../core/fs/fs-utils.js";import{normalizeStatusInput}from"../../core/item/status.js";import{resolveItemTypeRegistry}from"../../core/item/type-registry.js";import{resolveRuntimeStatusRegistry}from"../../core/schema/runtime-schema.js";import{DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS,DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS,EXIT_CODE,PM_DIRNAME,SETTINGS_DEFAULTS}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{toNonEmptyStringOrUndefined}from"../../core/shared/primitives.js";import{nowIso}from"../../core/shared/time.js";import{CURRENT_ITEM_FORMAT_VERSION,effectiveItemFormatVersion,scanItemFormatVersions}from"../../core/item/item-format-version.js";import{resolvePmRoot}from"../../core/store/paths.js";import{readSettings}from"../../core/store/settings.js";import{partitionFixesByGrant,planCloseReasonBackfillFixes,planEstimateBackfillFixes,planResolutionBackfillFixes,planStaleLinkPruneFixes,planTerminalParentFixes,resolveGrantedFixScopes,toFixOutputRow}from"../../core/validate/fix-planning.js";import{findDuplicateIssueCodes}from"../../core/governance/issue-codes.js";import{buildMissingByTypeCounts}from"../../core/validate/missing-by-type.js";import{classifyStaleLinkedPaths,summarizeStaleLinkedPathClassifications}from"../../core/validate/stale-file-classification.js";import{isRemoteLinkedArtifactReference}from"../../core/validate/linked-artifact-reference.js";import{assertProjectionModeChoice}from"../output-projection.js";import{collectDanglingDependencyReferences}from"../graph/assembly.js";import{auditMergeAttributeFence,auditMergeDriverConfiguration,findGitWorkspaceRoot,resolveProjectMergeTypeFolders}from"../merge/install.js";import{inspectMergeReceiptEvidence,partitionMergeReceipts}from"../merge/receipts.js";import{buildLinkedFileRepairReport}from"./linked-file-report.js";import{scanStorageIntegrity}from"./storage-integrity.js";import{scanTrackedRuntimeCache}from"./tracked-runtime-cache.js";import{scanHistoryAuthorAttribution}from"../author-attribution.js";import{createRelationshipKindRegistry}from"../relationships.js";import{runDocs}from"../docs.js";import{runFiles}from"../files.js";import{extractReferencedPmItemIdsFromCommand}from"../test/linked-command-detection.js";import{resolveLinkedTestSourceRef,resolveLinkedTestSourceWorkspaceRoot,resolveLinkedTestTrustBatch}from"../test/trust.js";import{readValidateItems}from"./validate-item-reader.js";import{buildValidateHistoryDriftCheck}from"./validate-history-drift.js";import{buildLifecycleParentGraph,detectLifecycleParentCycles,resolveLifecycleDependencyCycleSamplePath}from"./hierarchy-validation.js";import{buildStatusRoleWarnings,inspectStatusRoleAssignments}from"./status-role-diagnostics.js";import{summarizeCommandPreview,normalizeRelativeDirectoryPath,normalizeRelativePath,toMeaningfulString}from"./validate-normalization.js";const FILE_SCAN_DIRECTORIES=["src","tests","docs"];const FILE_SCAN_ROOT_FILES=["README.md","PRD.md","CHANGELOG.md","AGENTS.md","CONTRIBUTING.md","SECURITY.md","CODE_OF_CONDUCT.md","LICENSE"];const DIRECTORY_IGNORE_SET=new Set(["node_modules",".git",".cursor",".agents","dist","coverage"]);const RESOLUTION_FIELD_KEYS=["resolution","expected_result","actual_result"];const VALIDATE_FILE_SCAN_MODES=["default","tracked-all","tracked-all-strict"];const VALIDATE_METADATA_PROFILE_VALUES=["core","strict","custom"];const VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES=["off","warn","error"];const CORE_METADATA_REQUIRED_FIELDS=["author","acceptance_criteria","estimated_minutes","close_reason"];const STRICT_METADATA_REQUIRED_FIELDS=[...CORE_METADATA_REQUIRED_FIELDS,"reviewer","risk","confidence","sprint","release"];const SUPPORTED_METADATA_REQUIRED_FIELDS=Array.from(new Set(STRICT_METADATA_REQUIRED_FIELDS));const METADATA_REQUIRED_FIELD_ALIASES={author:"author",acceptance_criteria:"acceptance_criteria","acceptance-criteria":"acceptance_criteria",estimated_minutes:"estimated_minutes","estimated-minutes":"estimated_minutes",estimate:"estimated_minutes",close_reason:"close_reason","close-reason":"close_reason",reviewer:"reviewer",risk:"risk",confidence:"confidence",sprint:"sprint",release:"release"};const METADATA_WARNING_TOKEN_BY_FIELD={author:"validate_metadata_missing_author",acceptance_criteria:"validate_metadata_missing_acceptance_criteria",estimated_minutes:"validate_metadata_missing_estimate",close_reason:"validate_metadata_missing_close_reason",reviewer:"validate_metadata_missing_reviewer",risk:"validate_metadata_missing_risk",confidence:"validate_metadata_missing_confidence",sprint:"validate_metadata_missing_sprint",release:"validate_metadata_missing_release"};const METADATA_COUNT_KEY_BY_FIELD={author:"missing_author",acceptance_criteria:"missing_acceptance_criteria",estimated_minutes:"missing_estimated_minutes",close_reason:"closed_missing_close_reason",reviewer:"missing_reviewer",risk:"missing_risk",confidence:"missing_confidence",sprint:"missing_sprint",release:"missing_release"};const METADATA_ITEM_IDS_KEY_BY_FIELD={author:"missing_author_item_ids",acceptance_criteria:"missing_acceptance_criteria_item_ids",estimated_minutes:"missing_estimated_minutes_item_ids",close_reason:"closed_missing_close_reason_item_ids",reviewer:"missing_reviewer_item_ids",risk:"missing_risk_item_ids",confidence:"missing_confidence_item_ids",sprint:"missing_sprint_item_ids",release:"missing_release_item_ids"};const METADATA_TRUNCATED_KEY_BY_FIELD={author:"missing_author_truncated",acceptance_criteria:"missing_acceptance_criteria_truncated",estimated_minutes:"missing_estimated_minutes_truncated",close_reason:"closed_missing_close_reason_truncated",reviewer:"missing_reviewer_truncated",risk:"missing_risk_truncated",confidence:"missing_confidence_truncated",sprint:"missing_sprint_truncated",release:"missing_release_truncated"};const GIT_LS_FILES_MAX_BUFFER=32*1024*1024;const GIT_LS_FILES_TIMEOUT_MS=1e4;const FILE_LIST_SUMMARY_LIMIT=40;const DIAGNOSTIC_LIST_SUMMARY_LIMIT=5;const LINKED_ARTIFACT_MAX_PATH_LENGTH=4096;const LINKED_ARTIFACT_MAX_SEGMENT_LENGTH=255;const execFileAsync=promisify(execFile);function projectValidateCountsRecord(record){const projected={};for(const[key,value]of Object.entries(record)){if(Array.isArray(value)||value===false&&key.endsWith("_truncated")){continue}projected[key]=typeof value==="object"&&value!==null?projectValidateCountsRecord(value):value}return projected}function projectValidateCounts(result){return{...result,checks:result.checks.map(check=>({...check,details:projectValidateCountsRecord(check.details)})),...result.fixes?{fixes:{mode:result.fixes.mode,auto_fix:result.fixes.auto_fix,prune_missing:result.fixes.prune_missing,planned_count:result.fixes.planned_count,applied_count:result.fixes.applied_count,gated_count:result.fixes.gated_count,failed_count:result.fixes.failed_count}}:{}}}function normalizeStatusForRegistry(status,statusRegistry){return normalizeStatusInput(status,statusRegistry)??status}function isTerminalStatus(status,statusRegistry){return statusRegistry.terminal_statuses.has(normalizeStatusForRegistry(status,statusRegistry))}function normalizeLifecyclePatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function areSortedStringListsEqual(left,right){if(left.length!==right.length){return false}return left.every((value,index)=>value===right[index])}function resolveLifecyclePatternPolicy(settings){const defaultStalePatterns=normalizeLifecyclePatternList(DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS);const defaultClosureLikePatterns={blocked_reason:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.blocked_reason),resolution:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.resolution),actual_result:normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.actual_result)};const staleBlockerReasonPatterns=normalizeLifecyclePatternList(settings.validation.lifecycle_stale_blocker_reason_patterns);const closureLikePatterns={blocked_reason:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_blocked_reason_patterns),resolution:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_resolution_patterns),actual_result:normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_actual_result_patterns)};return{stale_blocker_reason_patterns:staleBlockerReasonPatterns,stale_blocker_reason_pattern_source:areSortedStringListsEqual(staleBlockerReasonPatterns,defaultStalePatterns)?"default":"settings",closure_like_metadata_field_patterns:closureLikePatterns,closure_like_metadata_field_pattern_sources:{blocked_reason:areSortedStringListsEqual(closureLikePatterns.blocked_reason,defaultClosureLikePatterns.blocked_reason)?"default":"settings",resolution:areSortedStringListsEqual(closureLikePatterns.resolution,defaultClosureLikePatterns.resolution)?"default":"settings",actual_result:areSortedStringListsEqual(closureLikePatterns.actual_result,defaultClosureLikePatterns.actual_result)?"default":"settings"}}}function resolveValidateMetadataProfile(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"core"}if(VALIDATE_METADATA_PROFILE_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --metadata-profile value "${value}". Supported values: ${VALIDATE_METADATA_PROFILE_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveDependencyCycleSeverity(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"warn"}if(VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --dependency-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveParentCycleSeverity(value){const normalized=value?.trim().toLowerCase();if(!normalized||normalized.length===0){return"warn"}if(VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown --parent-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function normalizeMetadataRequiredFieldsFromSettings(values){const normalized=[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))];return normalized.map(value=>METADATA_REQUIRED_FIELD_ALIASES[value]).filter(value=>value!==void 0).sort((left,right)=>left.localeCompare(right))}function resolveValidateMetadataPolicy(profile,profileSource,configuredCustomFields){const normalizedCustomFields=normalizeMetadataRequiredFieldsFromSettings(configuredCustomFields);if(profile==="core"){return{profile,profile_source:profileSource,required_fields:[...CORE_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}if(profile==="strict"){return{profile,profile_source:profileSource,required_fields:[...STRICT_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}if(normalizedCustomFields.length>0){return{profile,profile_source:profileSource,required_fields:normalizedCustomFields,configured_custom_fields:normalizedCustomFields,fallback_to_core:false,warnings:[]}}return{profile,profile_source:profileSource,required_fields:[...CORE_METADATA_REQUIRED_FIELDS],configured_custom_fields:normalizedCustomFields,fallback_to_core:true,warnings:["validate_metadata_custom_profile_missing_required_fields:0"]}}const TERMINAL_EXEMPT_PLANNING_FIELDS=new Set(["acceptance_criteria","estimated_minutes"]);function isMetadataFieldMissing(item,field,statusRegistry,enforcePlanningFieldsOnTerminal){if(!enforcePlanningFieldsOnTerminal&&TERMINAL_EXEMPT_PLANNING_FIELDS.has(field)&&isTerminalStatus(item.status,statusRegistry)){return false}if(field==="author"){return!toNonEmptyStringOrUndefined(item.author)}if(field==="acceptance_criteria"){return!toNonEmptyStringOrUndefined(item.acceptance_criteria)}if(field==="estimated_minutes"){return!Number.isFinite(item.estimated_minutes)}if(field==="close_reason"){return normalizeStatusForRegistry(item.status,statusRegistry)===statusRegistry.close_status&&!toNonEmptyStringOrUndefined(item.close_reason)}if(field==="reviewer"){return!toNonEmptyStringOrUndefined(item.reviewer)}if(field==="risk"){return!toNonEmptyStringOrUndefined(item.risk)}if(field==="confidence"){if(typeof item.confidence==="number"){return!Number.isFinite(item.confidence)}return!toNonEmptyStringOrUndefined(item.confidence)}if(field==="sprint"){return!toNonEmptyStringOrUndefined(item.sprint)}return!toNonEmptyStringOrUndefined(item.release)}function resolveFileScanMode(scanMode){if(scanMode===void 0){return"default"}const normalized=scanMode.trim().toLowerCase();if(normalized.length===0){return"default"}if(normalized==="default"){return"default"}if(normalized==="tracked-all"||normalized==="tracked_all"){return"tracked-all"}if(normalized==="tracked-all-strict"||normalized==="tracked_all_strict"){return"tracked-all-strict"}throw new PmCliError(`Unknown --scan-mode value "${scanMode}". Supported values: ${VALIDATE_FILE_SCAN_MODES.join(", ")}.`,EXIT_CODE.USAGE)}function resolveWorkspaceRoot(pmRoot){const sourceWorkspaceRoot=process.env.PM_SOURCE_WORKSPACE_ROOT?.trim();if(sourceWorkspaceRoot){return path.resolve(sourceWorkspaceRoot)}const resolvedPmRoot=path.resolve(pmRoot);const normalizedPmRoot=resolvedPmRoot.replaceAll("\\","/");if(normalizedPmRoot.endsWith("/.agents/pm")){return path.dirname(path.dirname(resolvedPmRoot))}const resolvedCwd=path.resolve(process.cwd());const canonicalPmRoot=realpathForWorkspaceRoot(resolvedPmRoot);const canonicalCwd=realpathForWorkspaceRoot(resolvedCwd);const relativeFromPmRoot=path.relative(canonicalPmRoot,canonicalCwd);const cwdInsidePmRoot=relativeFromPmRoot.length===0||!relativeFromPmRoot.startsWith("..")&&!path.isAbsolute(relativeFromPmRoot);if(cwdInsidePmRoot){return resolvedPmRoot}return resolvedCwd}function realpathForWorkspaceRoot(inputPath){try{return realpathSync.native(inputPath)}catch{return path.resolve(inputPath)}}function hasFilesystemErrorCode(error,acceptedCodes){return typeof error==="object"&&error!==null&&"code"in error&&typeof error.code==="string"&&acceptedCodes.includes(error.code)}async function listFilesRecursive(basePath,relativePath,output){const targetDirectory=relativePath.length>0?path.join(basePath,relativePath):basePath;let entries;try{entries=await fs.readdir(targetDirectory,{withFileTypes:true})}catch(error){if(isFileMissingError(error)){return}throw error}for(const entry of entries){if(entry.name.startsWith(".")){continue}const childRelative=relativePath.length>0?path.join(relativePath,entry.name):entry.name;if(entry.isDirectory()){if(DIRECTORY_IGNORE_SET.has(entry.name)){continue}await listFilesRecursive(basePath,childRelative,output);continue}if(!entry.isFile()){continue}output.push(normalizeRelativePath(childRelative))}}async function collectDefaultProjectFileCandidates(workspaceRoot){const discovered=[];for(const directory of FILE_SCAN_DIRECTORIES){await listFilesRecursive(workspaceRoot,directory,discovered)}for(const candidate of FILE_SCAN_ROOT_FILES){const absolute=path.join(workspaceRoot,candidate);try{const stats=await fs.stat(absolute);if(stats.isFile()){discovered.push(normalizeRelativePath(candidate))}}catch{}}return[...new Set(discovered)].sort((left,right)=>left.localeCompare(right))}async function collectTrackedGitFileCandidates(workspaceRoot){try{const{stdout}=await execFileAsync("git",["ls-files","-z"],{cwd:workspaceRoot,encoding:"utf8",maxBuffer:GIT_LS_FILES_MAX_BUFFER,windowsHide:true,timeout:GIT_LS_FILES_TIMEOUT_MS});const discovered=stdout.split("\0").map(value=>normalizeRelativePath(value)).filter(value=>value.length>0);return[...new Set(discovered)].sort((left,right)=>left.localeCompare(right))}catch{return null}}function resolvePmInternalCandidatePrefixes(pmRoot,workspaceRoot){const prefixes=new Set;const configuredDefault=normalizeRelativeDirectoryPath(PM_DIRNAME);if(configuredDefault.length>0){prefixes.add(configuredDefault)}const relativePmRoot=normalizeRelativeDirectoryPath(path.relative(workspaceRoot,pmRoot));if(relativePmRoot.length>0&&!relativePmRoot.startsWith("..")){prefixes.add(relativePmRoot)}return[...prefixes].sort((left,right)=>left.localeCompare(right))}function hasPathPrefix(candidate,prefixes){for(const prefix of prefixes){if(candidate===prefix||candidate.startsWith(`${prefix}/`)){return true}}return false}async function collectProjectFileCandidates(workspaceRoot,scanMode){if(scanMode==="tracked-all"||scanMode==="tracked-all-strict"){const trackedCandidates=await collectTrackedGitFileCandidates(workspaceRoot);if(trackedCandidates){return{requestedMode:scanMode,appliedMode:scanMode,source:"tracked-git",candidateFiles:trackedCandidates,candidateTotal:trackedCandidates.length,candidateScanned:trackedCandidates.length}}const fallbackCandidates=await collectDefaultProjectFileCandidates(workspaceRoot);return{requestedMode:scanMode,appliedMode:"default",source:"tracked-all-fallback-default",candidateFiles:fallbackCandidates,candidateTotal:fallbackCandidates.length,candidateScanned:fallbackCandidates.length}}const defaultCandidates=await collectDefaultProjectFileCandidates(workspaceRoot);return{requestedMode:scanMode,appliedMode:"default",source:"default-curated",candidateFiles:defaultCandidates,candidateTotal:defaultCandidates.length,candidateScanned:defaultCandidates.length}}function summarizeList(values,limit=DIAGNOSTIC_LIST_SUMMARY_LIMIT){if(values.length<=limit){return{values,truncated:false}}return{values:values.slice(0,limit),truncated:true}}function summarizeFileList(values,verboseFileLists){if(verboseFileLists){return{values,truncated:false,total:values.length}}const summary=summarizeList(values,FILE_LIST_SUMMARY_LIMIT);return{values:summary.values,truncated:summary.truncated,total:values.length}}const RESOLUTION_REMEDIATION_FLAG_BY_FIELD={resolution:"--resolution",expected_result:"--expected-result",actual_result:"--actual-result"};const RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD={resolution:"Describe how this item was resolved",expected_result:"Describe the expected result",actual_result:"Describe the actual result"};function buildResolutionRemediationCommand(row){const fieldArguments=row.missing_fields.map(field=>`${RESOLUTION_REMEDIATION_FLAG_BY_FIELD[field]} "${RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD[field]}"`).join(" ");return`pm update ${row.id} ${fieldArguments} --message "Backfill resolution metadata"`}function attachValidateFixHints(check,checkWarnings){const existingResolutionHints=check.details?.missing_resolution_remediation_hints;const aliasedResolution=Array.isArray(existingResolutionHints)&&existingResolutionHints.length>0;const fixHints=aliasedResolution?existingResolutionHints.filter(hint=>typeof hint==="string"):buildRemediationCommands(checkWarnings);if(fixHints.length===0){return}const truncated=aliasedResolution&&check.details?.missing_resolution_remediation_hints_truncated===true;check.details={...check.details,fix_hints:fixHints,...truncated?{fix_hints_truncated:true}:{}}}function resolveRequestedChecks(options){const requested=new Set;if(options.checkCompleteness)requested.add("completeness");if(options.checkMetadata){requested.add("metadata")}if(options.checkResolution){requested.add("resolution")}if(options.checkLifecycle||options.checkStaleBlockers){requested.add("lifecycle")}if(options.checkFiles){requested.add("files")}if(options.checkHistoryDrift){requested.add("history_drift")}if(options.checkCommandReferences){requested.add("command_references")}if(options.checkStorageIntegrity){requested.add("storage_integrity")}if(requested.size===0){if(options.autoFix){requested.add("metadata");requested.add("resolution");requested.add("lifecycle")}if(options.pruneMissing){requested.add("files")}if(requested.size===0){requested.add("metadata");requested.add("resolution");requested.add("lifecycle");requested.add("files");requested.add("command_references");requested.add("history_drift");requested.add("format_version");requested.add("completeness");requested.add("storage_integrity")}return requested}if(options.pruneMissing){requested.add("files")}return requested}const DUPLICATE_ISSUE_CODE_WARNING_TOKEN="validate_metadata_duplicate_issue_codes";function summarizeDuplicateIssueCodes(duplicates,verboseDiagnostics){if(duplicates.length===0){return{rows:[],truncated:false,warnings:[]}}const limit=verboseDiagnostics?duplicates.length:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const shown=duplicates.slice(0,limit);const rows=shown.map(duplicate=>({code:duplicate.code,count:duplicate.count,ids:duplicate.ids,titles:duplicate.titles,remediation_hint:`Items ${duplicate.ids.join(", ")} share issue code "${duplicate.code}"; rename or merge so each logical code maps to one item.`}));return{rows,truncated:shown.length<duplicates.length,warnings:[`${DUPLICATE_ISSUE_CODE_WARNING_TOKEN}:${duplicates.length}`]}}function collectMissingMetadataByField(items,statusRegistry,enforcePlanningFieldsOnTerminal){const missingByField=Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map(field=>[field,[]]));for(const item of items){for(const field of SUPPORTED_METADATA_REQUIRED_FIELDS){if(isMetadataFieldMissing(item,field,statusRegistry,enforcePlanningFieldsOnTerminal)){missingByField[field].push(item.id)}}}return missingByField}function buildMetadataWarningTokens(metadataPolicy,missingByField,duplicateWarnings){const warningTokens=[...metadataPolicy.warnings];for(const field of metadataPolicy.required_fields){const missingItems=missingByField[field];if(missingItems.length>0){warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`)}}warningTokens.push(...duplicateWarnings);return warningTokens}function buildMetadataCounts(metadataPolicy,missingByField){const counts={};for(const field of metadataPolicy.required_fields){const missing=missingByField[field];const value=missing?missing.length:0;const countKey=METADATA_COUNT_KEY_BY_FIELD[field];counts[countKey]=value}return counts}function buildMissingFieldOccurrences(metadataPolicy,missingByField,itemsById){const occurrences=[];for(const field of metadataPolicy.required_fields){const missing=missingByField[field];if(!missing){continue}for(const itemId of missing){const itemType=itemsById.get(itemId)?.type;const normalizedItemType=typeof itemType==="string"&&itemType.length>0?itemType:"Unknown";occurrences.push({item_type:normalizedItemType,field})}}return occurrences}function attachMissingMetadataItemIds(details,metadataPolicy,missingByField,verboseDiagnostics){for(const field of metadataPolicy.required_fields){const missing=missingByField[field];if(!missing||missing.length===0){continue}const idsKey=METADATA_ITEM_IDS_KEY_BY_FIELD[field];const truncatedKey=METADATA_TRUNCATED_KEY_BY_FIELD[field];if(!idsKey||!truncatedKey){continue}const summarized=summarizeList(missing,verboseDiagnostics?missing.length:DIAGNOSTIC_LIST_SUMMARY_LIMIT);details[idsKey]=summarized.values;details[truncatedKey]=summarized.truncated}}function buildCloseReasonBackfillRows(metadataPolicy,missingByField,itemsById){if(!metadataPolicy.required_fields.includes("close_reason")){return[]}const missing=missingByField.close_reason;if(!missing){return[]}return missing.map(itemId=>({id:itemId,resolution:toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution)}))}function buildEstimateBackfillRows(metadataPolicy,missingByField,itemsById){if(!metadataPolicy.required_fields.includes("estimated_minutes")){return[]}const missing=missingByField.estimated_minutes;if(!missing){return[]}return missing.map(itemId=>({id:itemId,type:toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type)}))}function buildMetadataCheck(items,metadataPolicy,statusRegistry,verboseDiagnostics,configuredIssueCodePrefixes){const itemsById=new Map(items.map(item=>[item.id,item]));const enforcePlanningFieldsOnTerminal=metadataPolicy.profile==="strict";const missingByField=collectMissingMetadataByField(items,statusRegistry,enforcePlanningFieldsOnTerminal);const duplicateIssueCodes=findDuplicateIssueCodes(items,{configuredPrefixes:configuredIssueCodePrefixes});const duplicateIssueCodeSummary=summarizeDuplicateIssueCodes(duplicateIssueCodes,verboseDiagnostics);const warningTokens=buildMetadataWarningTokens(metadataPolicy,missingByField,duplicateIssueCodeSummary.warnings);const counts=buildMetadataCounts(metadataPolicy,missingByField);const missingFieldOccurrences=buildMissingFieldOccurrences(metadataPolicy,missingByField,itemsById);const missingByType=buildMissingByTypeCounts(missingFieldOccurrences);const details={checked_items:items.length,metadata_profile:metadataPolicy.profile,metadata_profile_source:metadataPolicy.profile_source,metadata_profile_fallback_to_core:metadataPolicy.fallback_to_core,required_fields:[...metadataPolicy.required_fields],supported_required_fields:[...SUPPORTED_METADATA_REQUIRED_FIELDS],counts,missing_by_type:missingByType,duplicate_issue_codes_count:duplicateIssueCodes.length,duplicate_issue_codes:duplicateIssueCodeSummary.rows,duplicate_issue_codes_truncated:duplicateIssueCodeSummary.truncated};if(metadataPolicy.configured_custom_fields.length>0){details.configured_custom_required_fields=[...metadataPolicy.configured_custom_fields]}attachMissingMetadataItemIds(details,metadataPolicy,missingByField,verboseDiagnostics);const closeReasonBackfillRows=buildCloseReasonBackfillRows(metadataPolicy,missingByField,itemsById);const estimateBackfillRows=buildEstimateBackfillRows(metadataPolicy,missingByField,itemsById);return{check:{name:"metadata",status:warningTokens.length===0?"ok":"warn",ok:warningTokens.length===0,details},warnings:warningTokens,closeReasonBackfillRows,estimateBackfillRows}}function buildResolutionCheck(items,statusRegistry,verboseDiagnostics){const terminalDoneStatuses=new Set(statusRegistry.terminal_done_statuses);terminalDoneStatuses.add(statusRegistry.close_status);const closedItems=items.filter(item=>terminalDoneStatuses.has(normalizeStatusForRegistry(item.status,statusRegistry)));const missingResolutionRows=[];const resolutionBackfillRows=[];for(const item of closedItems){const missingFields=RESOLUTION_FIELD_KEYS.filter(field=>!toNonEmptyStringOrUndefined(item[field]));if(missingFields.length===0){continue}missingResolutionRows.push({id:item.id,missing_fields:missingFields});resolutionBackfillRows.push({id:item.id,missing_fields:missingFields,close_reason:toNonEmptyStringOrUndefined(item.close_reason)})}const warnings=missingResolutionRows.length>0?[`validate_resolution_missing_fields:${missingResolutionRows.length}`]:[];const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(missingResolutionRows.map(row=>`${row.id}:${row.missing_fields.join(",")}`),diagnosticLimit);const remediationHints=missingResolutionRows.map(row=>buildResolutionRemediationCommand(row));const summarizedHints=summarizeList(remediationHints,diagnosticLimit);return{check:{name:"resolution",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{checked_closed_items:closedItems.length,missing_resolution_items:missingResolutionRows.length,missing_resolution_rows:summarizedRows.values,missing_resolution_rows_truncated:summarizedRows.truncated,missing_resolution_remediation_hints:summarizedHints.values,missing_resolution_remediation_hints_truncated:summarizedHints.truncated}},warnings,resolutionBackfillRows}}function escapeRegExp(value){return value.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function buildLifecycleDependencyGraph(activeItems,idPrefix="pm",relationshipRegistry=createRelationshipKindRegistry()){const activeItemIds=new Set(activeItems.map(item=>item.id));const sortedItems=[...activeItems].sort((left,right)=>left.id.localeCompare(right.id));return new Map(sortedItems.map(item=>{const edges=new Set;const blockedBy=toMeaningfulString(item.blocked_by);if(blockedBy&&activeItemIds.has(blockedBy)){edges.add(blockedBy)}(item.dependencies??[]).filter(dependency=>{const dependencyKind=toMeaningfulString(dependency.kind);return dependencyKind!==void 0&&relationshipRegistry.resolve(dependencyKind)?.ordering===true}).map(dependency=>toMeaningfulString(dependency.id)).filter(dependencyId=>dependencyId!==void 0&&activeItemIds.has(dependencyId)).forEach(dependencyId=>edges.add(dependencyId));const definitionOfReady=toMeaningfulString(item.definition_of_ready);extractItemIds(definitionOfReady??"",idPrefix).filter(referencedId=>activeItemIds.has(referencedId)).forEach(referencedId=>edges.add(referencedId));return[item.id,[...edges].sort((left,right)=>left.localeCompare(right))]}))}function buildDependencyReferencesCheck(items,verboseDiagnostics,statusRegistry){const classified=collectDanglingDependencyReferences(items,statusRegistry?status=>isTerminalStatus(status,statusRegistry):void 0);const activeRows=classified.active.map(row=>`${row.holder_id}:${row.target_id}:${row.kind}`);const legacyRows=classified.legacy_terminal.map(row=>`${row.holder_id}:${row.target_id}:${row.kind}:${row.holder_status}`);const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(activeRows,diagnosticLimit);const summarizedLegacyRows=summarizeList(legacyRows,diagnosticLimit);const hints=summarizeList(classified.active.map(row=>{if(row.source==="parent"){return`pm update ${row.holder_id} --unset parent`}return row.source==="blocked_by"?`pm update ${row.holder_id} --unset blocked_by`:`pm update ${row.holder_id} --replace-deps '<correct dependency edges>'`}),diagnosticLimit);return{check:{name:"dependency_references",status:activeRows.length===0?"ok":"warn",ok:activeRows.length===0,details:{checked_items:items.length,dangling_reference_count:activeRows.length+legacyRows.length,active_dangling_reference_count:activeRows.length,dangling_reference_rows:summarizedRows.values,dangling_reference_rows_truncated:summarizedRows.truncated,legacy_terminal_dangling_reference_count:legacyRows.length,legacy_closed_dangling_reference_count:classified.legacy_terminal.filter(row=>row.holder_status==="closed").length,legacy_terminal_dangling_reference_rows:summarizedLegacyRows.values,legacy_terminal_dangling_reference_rows_truncated:summarizedLegacyRows.truncated,no_active_blocker_sentinel_count:classified.no_active_blocker_sentinels.length,remediation_hints:hints.values,remediation_hints_truncated:hints.truncated}},warnings:activeRows.length>0?[`validate_dangling_dependency_references:${activeRows.length}`]:[]}}function extractItemIds(value,idPrefix="pm"){const normalizedPrefix=(idPrefix.trim().toLowerCase()||"pm").replace(/-+$/g,"");const pattern=new RegExp(`(?:^|[^a-z0-9-])(${escapeRegExp(normalizedPrefix)}-[a-z0-9][a-z0-9-]*)`,"gi");return[...new Set([...value.matchAll(pattern)].map(match=>match[1].toLowerCase()))].sort((left,right)=>left.localeCompare(right))}function findLifecycleDependencyCycleComponents(graph){let nextIndex=0;const indexById=new Map;const lowLinkById=new Map;const stack=[];const inStack=new Set;const components=[];const visit=id=>{indexById.set(id,nextIndex);lowLinkById.set(id,nextIndex);nextIndex+=1;stack.push(id);inStack.add(id);for(const dependencyId of graph.get(id)??[]){if(!indexById.has(dependencyId)){visit(dependencyId);lowLinkById.set(id,Math.min(lowLinkById.get(id),lowLinkById.get(dependencyId)))}else if(inStack.has(dependencyId)){lowLinkById.set(id,Math.min(lowLinkById.get(id),indexById.get(dependencyId)))}}if(lowLinkById.get(id)!==indexById.get(id)){return}const component=[];while(stack.length>0){const member=stack.pop();inStack.delete(member);component.push(member);if(member===id){break}}component.sort((left,right)=>left.localeCompare(right));components.push(component)};const sortedNodeIds=[...graph.keys()].sort((left,right)=>left.localeCompare(right));for(const id of sortedNodeIds){if(!indexById.has(id)){visit(id)}}const cycleComponents=components.filter(component=>{if(component.length>1){return true}const selfId=component[0];return(graph.get(selfId)??[]).includes(selfId)});return cycleComponents.sort((left,right)=>left[0].localeCompare(right[0])||left.length-right.length||left.join(",").localeCompare(right.join(",")))}function detectLifecycleDependencyCycles(activeItems,idPrefix="pm"){const graph=buildLifecycleDependencyGraph(activeItems,idPrefix);const cycleComponents=findLifecycleDependencyCycleComponents(graph);const cycleItemIds=[...new Set(cycleComponents.flat())].sort((left,right)=>left.localeCompare(right));const cycleSamplePaths=cycleComponents.map(component=>resolveLifecycleDependencyCycleSamplePath(component,graph).join("->"));return{cycle_count:cycleComponents.length,cycle_item_ids:cycleItemIds,cycle_sample_paths:cycleSamplePaths}}function classifyOrphanedPath(pathValue){if(pathValue.startsWith("docs/")){return"docs_unowned"}if(pathValue.startsWith("tests/")){return"tests_unowned"}if(pathValue.startsWith("src/")){return"source_unowned"}if(pathValue.endsWith(".md")){return"docs_unowned"}return"unlinked_existing"}function directoryOf(relativePath){const slash=relativePath.lastIndexOf("/");return slash===-1?"":relativePath.slice(0,slash)}function sharedDirectoryPrefixLength(left,right){const leftParts=directoryOf(left).split("/").filter(Boolean);const rightParts=directoryOf(right).split("/").filter(Boolean);let count=0;while(count<leftParts.length&&count<rightParts.length&&leftParts[count]===rightParts[count]){count+=1}return count}function scoreOrphanOwnerCandidate(pathValue,linkedPath){const linkedDir=directoryOf(linkedPath);const orphanDir=directoryOf(pathValue);const directoryPrefix=linkedPath.endsWith("/")?linkedPath:`${linkedPath}/`;const isDirectoryPrefix=pathValue.startsWith(directoryPrefix);const sameDirectory=linkedDir.length>0&&linkedDir===orphanDir;const sharedPrefixLength=sharedDirectoryPrefixLength(pathValue,linkedPath);if(!isDirectoryPrefix&&!sameDirectory&&sharedPrefixLength===0){return null}if(isDirectoryPrefix){return{score:linkedPath.length+1e3,confidence:"path_prefix"}}return sameDirectory?{score:sharedPrefixLength+500,confidence:"same_directory"}:{score:sharedPrefixLength,confidence:"shared_directory"}}function shouldReplaceOrphanOwnerCandidate(best,item,score){return best===void 0||score>best.score||score===best.score&&item.id.localeCompare(best.item.id)<0}function findOrphanOwnerCandidate(pathValue,classification,items){const linkKind=classification==="docs_unowned"?"docs":"files";let best;items.flatMap(item=>(linkKind==="docs"?item.docs??[]:item.files??[]).map(link=>({item,link}))).forEach(({item,link})=>{if(link.scope!=="project"){return}const linkedPath=normalizeRelativePath(link.path);if(linkedPath.length===0||linkedPath===pathValue){return}const scored=scoreOrphanOwnerCandidate(pathValue,linkedPath);if(scored===null){return}if(shouldReplaceOrphanOwnerCandidate(best,item,scored.score)){best={item,score:scored.score,confidence:scored.confidence}}});if(!best){return null}return{id:best.item.id,type:best.item.type,title:best.item.title,status:best.item.status,confidence:best.confidence}}function buildOrphanedPathRows(orphanedFiles,items){return orphanedFiles.map(pathValue=>{const classification=classifyOrphanedPath(pathValue);const linkCommand=classification==="docs_unowned"?"docs":"files";const ownerCandidate=findOrphanOwnerCandidate(pathValue,classification,items);const target=ownerCandidate?.id??"<id>";return{path:pathValue,classification,owner_candidate:ownerCandidate,remediation_hint:`pm ${linkCommand} ${target} --add path=${pathValue},scope=project,note="<why this artifact belongs to the item>"`}})}function summarizeOrphanedPathRows(rows){return rows.map(row=>`${row.path}:${row.classification} owner_candidate=${row.owner_candidate?.id??"unowned"} hint=${JSON.stringify(row.remediation_hint)}`)}function closureLikeFieldsForItem(item,lifecyclePatternPolicy){return Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns).filter(([field,patterns])=>{const value=toMeaningfulString(item[field]);return value?patterns.some(pattern=>value.toLowerCase().includes(pattern)):false}).map(([field])=>field).sort((left,right)=>left.localeCompare(right))}function buildTerminalParentFixRow(item,parent,itemsById,canonicalIdByLowercase,statusRegistry){const grandparentId=toMeaningfulString(parent.parent);const grandparent=grandparentId?itemsById.get(canonicalIdByLowercase.get(grandparentId.toLowerCase())??grandparentId):void 0;return{id:item.id,parent_id:parent.id,grandparent_id:grandparent?.id,grandparent_active:grandparent!==void 0&&!isTerminalStatus(grandparent.status,statusRegistry)}}function staleBlockerReasonsForItem(item,blockedStatuses,statusRegistry,lifecyclePatternPolicy){const blockedBy=toMeaningfulString(item.blocked_by);const blockedReason=toMeaningfulString(item.blocked_reason);const blockedReasonNormalized=blockedReason?.toLowerCase();const normalizedStatus=normalizeStatusForRegistry(item.status,statusRegistry);const reasons=[];if(!blockedStatuses.has(normalizedStatus)){if(blockedBy){reasons.push("non_blocked_status_has_blocked_by")}if(blockedReason){reasons.push("non_blocked_status_has_blocked_reason")}return reasons}if(!blockedBy&&!blockedReason){reasons.push("blocked_status_missing_blocker_context")}if(blockedReasonNormalized?.includes("no active blocker")){reasons.push("blocked_status_reason_reports_no_active_blocker")}if(blockedReasonNormalized&&lifecyclePatternPolicy.stale_blocker_reason_patterns.some(pattern=>blockedReasonNormalized.includes(pattern))){reasons.push("blocked_status_reason_matches_stale_pattern")}return reasons}function collectLifecycleScanRows(items,includeStaleBlockers,statusRegistry,lifecyclePatternPolicy){const itemsById=new Map(items.map(item=>[item.id,item]));const canonicalIdByLowercase=new Map(items.map(item=>[item.id.toLowerCase(),item.id]));const blockedStatuses=statusRegistry.blocked_statuses.size>0?statusRegistry.blocked_statuses:new Set(["blocked"]);const rows={activeItems:items.filter(item=>!isTerminalStatus(item.status,statusRegistry)),closureLikeRows:[],terminalParentRows:[],terminalParentFixRows:[],staleBlockerRows:[]};for(const item of rows.activeItems){const closureLikeFields=closureLikeFieldsForItem(item,lifecyclePatternPolicy);if(closureLikeFields.length>0){rows.closureLikeRows.push({id:item.id,fields:closureLikeFields})}const parentId=toMeaningfulString(item.parent);const parent=parentId?itemsById.get(canonicalIdByLowercase.get(parentId.toLowerCase())??parentId):void 0;if(parent&&isTerminalStatus(parent.status,statusRegistry)){rows.terminalParentRows.push({id:item.id,parent_id:parent.id,parent_status:parent.status});rows.terminalParentFixRows.push(buildTerminalParentFixRow(item,parent,itemsById,canonicalIdByLowercase,statusRegistry))}if(includeStaleBlockers){const reasons=staleBlockerReasonsForItem(item,blockedStatuses,statusRegistry,lifecyclePatternPolicy);if(reasons.length>0){rows.staleBlockerRows.push({id:item.id,status:item.status,reasons:[...new Set(reasons)].sort((left,right)=>left.localeCompare(right))})}}}return rows}function sortLifecycleScanRows(rows){rows.closureLikeRows.sort((left,right)=>left.id.localeCompare(right.id));rows.terminalParentRows.sort((left,right)=>left.id.localeCompare(right.id)||left.parent_id.localeCompare(right.parent_id));rows.terminalParentFixRows.sort((left,right)=>left.id.localeCompare(right.id)||left.parent_id.localeCompare(right.parent_id));rows.staleBlockerRows.sort((left,right)=>left.id.localeCompare(right.id))}function lifecycleCycleWarningToken(prefix,severity,count){if(count<=0||severity==="off"){return null}return`${severity==="error"?`${prefix}_error`:prefix}:${count}`}function lifecycleAdvisoryWarningToken(prefix,severity,count){return count>0&&severity!=="off"?`${prefix}:${count}`:null}function buildLifecycleWarnings(rows,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,counts){const warnings=[];if(rows.closureLikeRows.length>0){warnings.push(`validate_lifecycle_active_closure_like_metadata:${rows.closureLikeRows.length}`)}if(rows.terminalParentRows.length>0){warnings.push(`validate_lifecycle_active_terminal_parent:${rows.terminalParentRows.length}`)}if(includeStaleBlockers&&rows.staleBlockerRows.length>0){warnings.push(`validate_lifecycle_stale_blockers:${rows.staleBlockerRows.length}`)}const dependencyWarning=lifecycleCycleWarningToken("validate_lifecycle_dependency_cycles",dependencyCycleSeverity,counts.dependencyCycles);const parentWarning=lifecycleCycleWarningToken("validate_hierarchy_parent_cycle",parentCycleSeverity,counts.activeHierarchyCycles);const cardinalityWarning=lifecycleCycleWarningToken("validate_hierarchy_cardinality_violation",parentCycleSeverity,counts.activeHierarchyCardinality);const divergenceWarning=lifecycleCycleWarningToken("validate_hierarchy_parent_divergence",parentCycleSeverity,counts.activeHierarchyDivergence);const legacyCycleWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_parent_cycle",parentCycleSeverity,counts.legacyHierarchyCycles);const legacyCardinalityWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_cardinality_violation",parentCycleSeverity,counts.legacyHierarchyCardinality);const legacyDivergenceWarning=lifecycleAdvisoryWarningToken("validate_legacy_hierarchy_parent_divergence",parentCycleSeverity,counts.legacyHierarchyDivergence);return[...warnings,...dependencyWarning?[dependencyWarning]:[],...parentWarning?[parentWarning]:[],...cardinalityWarning?[cardinalityWarning]:[],...divergenceWarning?[divergenceWarning]:[],...legacyCycleWarning?[legacyCycleWarning]:[],...legacyCardinalityWarning?[legacyCardinalityWarning]:[],...legacyDivergenceWarning?[legacyDivergenceWarning]:[]]}function linkedArtifactPathExceedsFilesystemLimits(artifactPath){const normalized=normalizeRelativePath(artifactPath);return normalized.length>LINKED_ARTIFACT_MAX_PATH_LENGTH||normalized.split(/[\\/]/).some(segment=>segment.length>LINKED_ARTIFACT_MAX_SEGMENT_LENGTH)}async function linkedArtifactIsMissing(workspaceRoot,artifactPath){const absolutePath=path.isAbsolute(artifactPath)?artifactPath:path.resolve(workspaceRoot,artifactPath);if(linkedArtifactPathExceedsFilesystemLimits(absolutePath)){return false}try{const stats=await fs.stat(absolutePath);return!stats.isFile()&&!stats.isDirectory()}catch(error){return hasFilesystemErrorCode(error,["ENOENT","ENOTDIR"])}}async function collectLinkedPathScanState(items,workspaceRoot){const state={linkedProjectPaths:new Set,remoteLinkedPaths:new Set,missingLinkedPaths:[],staleLinkRows:[]};const linkedArtifacts=items.flatMap(item=>[...(item.files??[]).map(artifact=>({item,artifact,link_kind:"files"})),...(item.docs??[]).map(artifact=>({item,artifact,link_kind:"docs"}))]);for(const{item,artifact,link_kind}of linkedArtifacts){if(artifact.scope!=="project"){continue}if(isRemoteLinkedArtifactReference(artifact.path)){state.remoteLinkedPaths.add(artifact.path.trim());continue}const normalizedPath=normalizeRelativePath(artifact.path);if(normalizedPath.length===0){continue}state.linkedProjectPaths.add(normalizedPath);if(await linkedArtifactIsMissing(workspaceRoot,artifact.path)){state.missingLinkedPaths.push(normalizedPath);state.staleLinkRows.push({item_id:item.id,path:normalizedPath,link_kind})}}return state}function partitionFileCandidates(fileCandidates,pmRoot,workspaceRoot,fileScanMode,includePmInternals,verboseFileLists){const strictTrackedAllMode=fileScanMode==="tracked-all-strict";const strictModeForcesPmInternals=strictTrackedAllMode&&!includePmInternals;const includePmInternalsEffective=includePmInternals||strictTrackedAllMode;const pmInternalCandidatePrefixes=includePmInternalsEffective?[]:resolvePmInternalCandidatePrefixes(pmRoot,workspaceRoot);const excludedPmInternalPaths=pmInternalCandidatePrefixes.length===0?[]:fileCandidates.candidateFiles.filter(candidate=>hasPathPrefix(candidate,pmInternalCandidatePrefixes));const candidateFiles=pmInternalCandidatePrefixes.length===0?fileCandidates.candidateFiles:fileCandidates.candidateFiles.filter(candidate=>!hasPathPrefix(candidate,pmInternalCandidatePrefixes));const excludedByReason={};if(excludedPmInternalPaths.length>0){const summarizedPmInternalPaths=summarizeFileList(excludedPmInternalPaths,verboseFileLists);excludedByReason.pm_internals={count:excludedPmInternalPaths.length,paths:summarizedPmInternalPaths.values,paths_truncated:summarizedPmInternalPaths.truncated,paths_total:summarizedPmInternalPaths.total}}return{strictTrackedAllMode,strictModeForcesPmInternals,includePmInternalsEffective,pmInternalCandidatePrefixes,excludedPmInternalPaths,candidateFiles,excludedByReason}}function buildLifecycleCheck(items,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,statusRegistry,lifecyclePatternPolicy,verboseDiagnostics,idPrefix="pm"){const rows=collectLifecycleScanRows(items,includeStaleBlockers,statusRegistry,lifecyclePatternPolicy);sortLifecycleScanRows(rows);const dependencyCycleDiagnostics=detectLifecycleDependencyCycles(rows.activeItems,idPrefix);const parentCycleDiagnostics=detectLifecycleParentCycles(items,statusRegistry);const statusRoleDiagnostics=inspectStatusRoleAssignments(statusRegistry,items,verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT);const warnings=[...buildLifecycleWarnings(rows,includeStaleBlockers,dependencyCycleSeverity,parentCycleSeverity,{dependencyCycles:dependencyCycleDiagnostics.cycle_count,activeHierarchyCycles:parentCycleDiagnostics.active_cycle_count,activeHierarchyCardinality:parentCycleDiagnostics.active_cardinality_violation_count,activeHierarchyDivergence:parentCycleDiagnostics.active_parent_divergence_count,legacyHierarchyCycles:parentCycleDiagnostics.legacy_cycle_count,legacyHierarchyCardinality:parentCycleDiagnostics.legacy_cardinality_violation_count,legacyHierarchyDivergence:parentCycleDiagnostics.legacy_parent_divergence_count}),...buildStatusRoleWarnings(statusRoleDiagnostics)];const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedClosureLikeRows=summarizeList(rows.closureLikeRows.map(row=>`${row.id}:${row.fields.join(",")}`),diagnosticLimit);const summarizedTerminalParentRows=summarizeList(rows.terminalParentRows.map(row=>`${row.id}:${row.parent_id}:${row.parent_status}`),diagnosticLimit);const summarizedStaleBlockerRows=summarizeList(rows.staleBlockerRows.map(row=>`${row.id}:${row.status}:${row.reasons.join(",")}`),diagnosticLimit);const summarizedDependencyCycleItemIds=summarizeList(dependencyCycleDiagnostics.cycle_item_ids,diagnosticLimit);const summarizedDependencyCycleSamplePaths=summarizeList(dependencyCycleDiagnostics.cycle_sample_paths,diagnosticLimit);const summarizedParentCycleItemIds=summarizeList(parentCycleDiagnostics.cycle_item_ids,diagnosticLimit);const summarizedParentCycleSamplePaths=summarizeList(parentCycleDiagnostics.cycle_sample_paths,diagnosticLimit);const summarizedHierarchyCardinalityRows=summarizeList(parentCycleDiagnostics.cardinality_violation_rows,diagnosticLimit);const summarizedHierarchyDivergenceRows=summarizeList(parentCycleDiagnostics.parent_divergence_rows,diagnosticLimit);const hasErrorSeverityCycle=dependencyCycleDiagnostics.cycle_count>0&&dependencyCycleSeverity==="error"||(parentCycleDiagnostics.active_cycle_count>0||parentCycleDiagnostics.active_cardinality_violation_count>0||parentCycleDiagnostics.active_parent_divergence_count>0)&&parentCycleSeverity==="error";return{check:{name:"lifecycle",status:hasErrorSeverityCycle?"error":warnings.length===0?"ok":"warn",ok:!hasErrorSeverityCycle&&warnings.length===0,details:{checked_active_items:rows.activeItems.length,lifecycle_status_roles:statusRoleDiagnostics,active_closure_like_metadata_items:rows.closureLikeRows.length,active_closure_like_metadata_rows:summarizedClosureLikeRows.values,active_closure_like_metadata_rows_truncated:summarizedClosureLikeRows.truncated,active_terminal_parent_items:rows.terminalParentRows.length,active_terminal_parent_rows:summarizedTerminalParentRows.values,active_terminal_parent_rows_truncated:summarizedTerminalParentRows.truncated,stale_blocker_checks_enabled:includeStaleBlockers,stale_blocker_items:rows.staleBlockerRows.length,stale_blocker_rows:summarizedStaleBlockerRows.values,stale_blocker_rows_truncated:summarizedStaleBlockerRows.truncated,dependency_cycle_severity_policy:dependencyCycleSeverity,dependency_cycle_count:dependencyCycleDiagnostics.cycle_count,dependency_cycle_item_count:dependencyCycleDiagnostics.cycle_item_ids.length,dependency_cycle_item_ids:summarizedDependencyCycleItemIds.values,dependency_cycle_item_ids_truncated:summarizedDependencyCycleItemIds.truncated,dependency_cycle_sample_paths:summarizedDependencyCycleSamplePaths.values,dependency_cycle_sample_paths_truncated:summarizedDependencyCycleSamplePaths.truncated,parent_cycle_severity_policy:parentCycleSeverity,parent_cycle_count:parentCycleDiagnostics.cycle_count,active_parent_cycle_count:parentCycleDiagnostics.active_cycle_count,legacy_parent_cycle_count:parentCycleDiagnostics.legacy_cycle_count,parent_cycle_item_count:parentCycleDiagnostics.cycle_item_ids.length,parent_cycle_item_ids:summarizedParentCycleItemIds.values,parent_cycle_item_ids_truncated:summarizedParentCycleItemIds.truncated,parent_cycle_sample_paths:summarizedParentCycleSamplePaths.values,parent_cycle_sample_paths_truncated:summarizedParentCycleSamplePaths.truncated,hierarchy_cardinality_violation_count:parentCycleDiagnostics.cardinality_violation_count,active_hierarchy_cardinality_violation_count:parentCycleDiagnostics.active_cardinality_violation_count,legacy_hierarchy_cardinality_violation_count:parentCycleDiagnostics.legacy_cardinality_violation_count,hierarchy_cardinality_violation_rows:summarizedHierarchyCardinalityRows.values,hierarchy_cardinality_violation_rows_truncated:summarizedHierarchyCardinalityRows.truncated,hierarchy_parent_divergence_count:parentCycleDiagnostics.parent_divergence_count,active_hierarchy_parent_divergence_count:parentCycleDiagnostics.active_parent_divergence_count,legacy_hierarchy_parent_divergence_count:parentCycleDiagnostics.legacy_parent_divergence_count,hierarchy_parent_divergence_rows:summarizedHierarchyDivergenceRows.values,hierarchy_parent_divergence_rows_truncated:summarizedHierarchyDivergenceRows.truncated,stale_blocker_reason_patterns:[...lifecyclePatternPolicy.stale_blocker_reason_patterns],stale_blocker_reason_pattern_source:lifecyclePatternPolicy.stale_blocker_reason_pattern_source,closure_like_blocked_reason_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.blocked_reason],closure_like_blocked_reason_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.blocked_reason,closure_like_resolution_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.resolution],closure_like_resolution_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.resolution,closure_like_actual_result_patterns:[...lifecyclePatternPolicy.closure_like_metadata_field_patterns.actual_result],closure_like_actual_result_pattern_source:lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.actual_result}},warnings,terminalParentFixRows:rows.terminalParentFixRows}}async function buildFilesCheck(items,workspaceRoot,pmRoot,fileScanMode,includePmInternals,verboseFileLists,statusRegistry=resolveRuntimeStatusRegistry(SETTINGS_DEFAULTS.schema)){const linkedPathState=await collectLinkedPathScanState(items,workspaceRoot);const itemsById=new Map(items.map(item=>[item.id,item]));const uniqueMissingLinkedPaths=[...new Set(linkedPathState.missingLinkedPaths)].sort((left,right)=>left.localeCompare(right));const fileCandidates=await collectProjectFileCandidates(workspaceRoot,fileScanMode);const partition=partitionFileCandidates(fileCandidates,pmRoot,workspaceRoot,fileScanMode,includePmInternals,verboseFileLists);const orphanedFiles=partition.candidateFiles.filter(candidate=>!linkedPathState.linkedProjectPaths.has(candidate));const orphanedPathRows=buildOrphanedPathRows(orphanedFiles,items);const classifiedStalePaths=classifyStaleLinkedPaths(uniqueMissingLinkedPaths,partition.candidateFiles);const classificationByPath=new Map(classifiedStalePaths.map(entry=>[entry.path,entry.classification]));const movedStalePathCount=classifiedStalePaths.filter(entry=>entry.classification==="moved").length;const staleLinkPruneRows=linkedPathState.staleLinkRows.map(row=>({...row,classification:classificationByPath.get(row.path)??"deleted"})).sort((left,right)=>left.item_id.localeCompare(right.item_id)||left.path.localeCompare(right.path)||left.link_kind.localeCompare(right.link_kind));const warnings=[];if(partition.strictModeForcesPmInternals){warnings.push("validate_files_tracked_all_strict_forces_pm_internals")}if(orphanedFiles.length>0){warnings.push(`validate_files_orphaned_paths:${orphanedFiles.length}`)}const uniqueRemoteLinkedPaths=[...linkedPathState.remoteLinkedPaths].sort((left,right)=>left.localeCompare(right));const summarizedRemote=summarizeFileList(uniqueRemoteLinkedPaths,verboseFileLists);const summarizedMissing=summarizeFileList(uniqueMissingLinkedPaths,verboseFileLists);const summarizedOrphaned=summarizeFileList(orphanedFiles,verboseFileLists);const summarizedOrphanedClassifications=summarizeFileList(orphanedPathRows.map(row=>`${row.path}:${row.classification}:owner_candidate=${row.owner_candidate?.id??"unowned"}`),verboseFileLists);const orphanedPathRowDetail=verboseFileLists?orphanedPathRows:summarizeFileList(summarizeOrphanedPathRows(orphanedPathRows),false).values;const summarizedClassifications=summarizeFileList(summarizeStaleLinkedPathClassifications(classifiedStalePaths),verboseFileLists);const missingLinkedPathRows=staleLinkPruneRows;const repairReport=buildLinkedFileRepairReport(missingLinkedPathRows,classifiedStalePaths,id=>itemsById.get(id),statusRegistry,verboseFileLists?Infinity:FILE_LIST_SUMMARY_LIMIT);if(repairReport.active_missing_linked_paths_count>0){warnings.push(`validate_files_missing_linked_paths:${repairReport.active_missing_linked_paths_count}`)}return{check:{name:"files",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{workspace_root:workspaceRoot,scan_mode_requested:fileCandidates.requestedMode,scan_mode_applied:fileCandidates.appliedMode,strict_tracked_all_mode:partition.strictTrackedAllMode,strict_mode_forces_pm_internals:partition.strictModeForcesPmInternals,strict_mode_forces_pm_internals_notice:partition.strictModeForcesPmInternals?"tracked-all-strict force-enables PM internals; pass --include-pm-internals to make inclusion explicit.":null,file_list_detail_mode:verboseFileLists?"full":"summary",file_list_summary_limit:FILE_LIST_SUMMARY_LIMIT,candidate_scan_source:fileCandidates.source,include_pm_internals:partition.includePmInternalsEffective,include_pm_internals_requested:includePmInternals,pm_internal_candidate_prefixes:partition.pmInternalCandidatePrefixes,pm_internal_excluded_count:partition.excludedPmInternalPaths.length,excluded_total:partition.excludedPmInternalPaths.length,excluded_by_reason:partition.excludedByReason,linked_project_paths:linkedPathState.linkedProjectPaths.size,remote_linked_paths_count:uniqueRemoteLinkedPaths.length,remote_linked_paths_total:summarizedRemote.total,remote_linked_paths:summarizedRemote.values,remote_linked_paths_truncated:summarizedRemote.truncated,candidate_total_raw:fileCandidates.candidateTotal,candidate_scanned_raw:fileCandidates.candidateScanned,candidate_total:partition.candidateFiles.length,candidate_scanned:partition.candidateFiles.length,scanned_candidate_files:partition.candidateFiles.length,missing_linked_paths_count:uniqueMissingLinkedPaths.length,missing_linked_paths_total:summarizedMissing.total,missing_linked_paths:summarizedMissing.values,missing_linked_paths_truncated:summarizedMissing.truncated,missing_linked_paths_moved_count:movedStalePathCount,missing_linked_paths_deleted_count:classifiedStalePaths.filter(entry=>entry.classification==="deleted").length,missing_linked_paths_malformed_count:classifiedStalePaths.filter(entry=>entry.classification==="malformed").length,missing_linked_path_classifications:summarizedClassifications.values,missing_linked_path_classifications_truncated:summarizedClassifications.truncated,...repairReport,orphaned_paths_count:orphanedFiles.length,orphaned_paths_total:summarizedOrphaned.total,orphaned_paths:summarizedOrphaned.values,orphaned_paths_truncated:summarizedOrphaned.truncated,orphaned_path_classifications:summarizedOrphanedClassifications.values,orphaned_path_classifications_truncated:summarizedOrphanedClassifications.truncated,orphaned_path_rows_count:orphanedPathRows.length,orphaned_path_rows:orphanedPathRowDetail}},warnings,staleLinkPruneRows}}function buildUntrustedLinkedTestRows(linkedTests,trustDecisions){const rows=[];linkedTests.forEach(({item,linkedTest},index)=>{const trust=trustDecisions[index];if(trust.trusted)return;const command=summarizeCommandPreview(linkedTest.command??"");rows.push(`${item.id}:${trust.source_ref??"unknown"}->${trust.current_source_ref??"unknown"}:${command}`)});return rows}async function buildCommandReferencesCheck(items,idPrefix,verboseDiagnostics,pmRoot){const knownIds=new Set(items.map(item=>item.id.toLowerCase()));let linkedCommandsScanned=0;let referencedPmIdCount=0;const referencedPmIds=new Set;const staleReferenceRows=[];const linkedTests=items.flatMap(item=>(item.tests??[]).map(linkedTest=>({item,linkedTest})));const currentSourceRef=await resolveLinkedTestSourceRef(resolveLinkedTestSourceWorkspaceRoot());const trustDecisions=await resolveLinkedTestTrustBatch(pmRoot,linkedTests.map(({linkedTest})=>linkedTest),currentSourceRef);const untrustedRows=buildUntrustedLinkedTestRows(linkedTests,trustDecisions);for(const{item,linkedTest}of linkedTests){if(typeof linkedTest.command!=="string"||linkedTest.command.trim().length===0){continue}linkedCommandsScanned+=1;const referencedIds=extractReferencedPmItemIdsFromCommand(linkedTest.command,idPrefix);if(referencedIds.length===0){continue}referencedPmIdCount+=referencedIds.length;for(const referencedId of referencedIds){referencedPmIds.add(referencedId);if(!knownIds.has(referencedId.toLowerCase())){staleReferenceRows.push(`${item.id}:${referencedId}:${summarizeCommandPreview(linkedTest.command)}`)}}}const uniqueStaleReferenceRows=[...new Set(staleReferenceRows)].sort((left,right)=>left.localeCompare(right));const stalePmIds=[...new Set(uniqueStaleReferenceRows.map(row=>row.split(":")[1]??""))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right));const warnings=[];if(uniqueStaleReferenceRows.length>0){warnings.push(`validate_command_references_stale_pm_ids:${uniqueStaleReferenceRows.length}`)}if(untrustedRows.length>0){warnings.push(`validate_linked_test_trust_unacknowledged:${untrustedRows.length}`)}const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedRows=summarizeList(uniqueStaleReferenceRows,diagnosticLimit);const summarizedStalePmIds=summarizeList(stalePmIds,diagnosticLimit);const summarizedReferencedPmIds=summarizeList([...referencedPmIds].sort((left,right)=>left.localeCompare(right)),diagnosticLimit);const summarizedUntrustedRows=summarizeList(untrustedRows,diagnosticLimit);return{check:{name:"command_references",status:warnings.length===0?"ok":"warn",ok:warnings.length===0,details:{checked_items:items.length,linked_commands_scanned:linkedCommandsScanned,referenced_pm_ids_count:referencedPmIdCount,unique_referenced_pm_ids_count:referencedPmIds.size,unique_referenced_pm_ids:summarizedReferencedPmIds.values,unique_referenced_pm_ids_truncated:summarizedReferencedPmIds.truncated,linked_test_trust_current_source_ref:currentSourceRef??null,untrusted_linked_tests_count:untrustedRows.length,untrusted_linked_tests:summarizedUntrustedRows.values,untrusted_linked_tests_truncated:summarizedUntrustedRows.truncated,stale_pm_id_references_count:uniqueStaleReferenceRows.length,stale_pm_ids_count:stalePmIds.length,stale_pm_ids:summarizedStalePmIds.values,stale_pm_ids_truncated:summarizedStalePmIds.truncated,stale_pm_id_reference_rows:summarizedRows.values,stale_pm_id_reference_rows_truncated:summarizedRows.truncated}},warnings}}function buildFormatVersionCheck(items,verboseDiagnostics){const scan=scanItemFormatVersions(items.map(item=>({ref:item.id,version:effectiveItemFormatVersion(item)})));const warnings=[];if(scan.outdated.length>0){warnings.push(`validate_format_version_outdated_items:${scan.outdated.length}`)}if(scan.ahead.length>0){warnings.push(`validate_format_version_ahead_items:${scan.ahead.length}`)}const diagnosticLimit=verboseDiagnostics?Number.POSITIVE_INFINITY:DIAGNOSTIC_LIST_SUMMARY_LIMIT;const summarizedOutdated=summarizeList(scan.outdated,diagnosticLimit);const summarizedAhead=summarizeList(scan.ahead,diagnosticLimit);const status=scan.ahead.length>0?"error":scan.outdated.length>0?"warn":"ok";return{check:{name:"format_version",status,ok:status==="ok",details:{checked_items:items.length,current_format_version:CURRENT_ITEM_FORMAT_VERSION,outdated_items_count:scan.outdated.length,outdated_items:summarizedOutdated.values,outdated_items_truncated:summarizedOutdated.truncated,ahead_items_count:scan.ahead.length,ahead_items:summarizedAhead.values,ahead_items_truncated:summarizedAhead.truncated}},warnings}}const VALIDATE_AUTO_FIX_MESSAGE="pm validate auto-fix";async function applyValidateFix(fix,global2,services){switch(fix.kind){case"set_closed_at":await applyClosureTimestampFix(fix,global2);return;case"set_resolution":case"set_close_reason":case"set_estimate":case"reparent":case"unset_parent":{const updateOptions={message:VALIDATE_AUTO_FIX_MESSAGE};if(fix.kind==="set_resolution"){updateOptions.resolution=fix.value}else if(fix.kind==="set_close_reason"){updateOptions.closeReason=fix.value}else if(fix.kind==="set_estimate"){updateOptions.estimatedMinutes=fix.value}else if(fix.kind==="reparent"){updateOptions.parent=fix.parent_id}else{updateOptions.unset=["parent"]}if(!services.runUpdate){throw new PmCliError("Applying validate metadata/lifecycle fixes requires a runUpdate mutation service.",EXIT_CODE.USAGE)}await services.runUpdate(fix.item_id,updateOptions,global2);return}case"prune_file_link":{throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`)}case"prune_doc_link":{throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`)}}}function pruneBatchKey(fix){if(fix.kind!=="prune_file_link"&&fix.kind!=="prune_doc_link"){return null}return`${fix.kind}:${fix.item_id}`}async function applyValidateFixes(applicable,global2,services){const applied=[];const failed=[];const pruneBatches=new Map;for(const fix of applicable.filter(candidate=>pruneBatchKey(candidate)===null)){try{await applyValidateFix(fix,global2,services);applied.push(fix)}catch(error){failed.push({fix,error})}}for(const fix of applicable.filter(candidate=>pruneBatchKey(candidate)!==null)){const batchKey=pruneBatchKey(fix);const existing=pruneBatches.get(batchKey);if(existing){existing.push(fix)}else{pruneBatches.set(batchKey,[fix])}}for(const batch of pruneBatches.values()){const first=batch[0];if(!first){continue}const remove=batch.map(fix=>fix.path).filter(value=>typeof value==="string"&&value.length>0);try{if(first.kind==="prune_file_link"){await runFiles(first.item_id,{remove,message:VALIDATE_AUTO_FIX_MESSAGE},global2)}else{await runDocs(first.item_id,{remove,message:VALIDATE_AUTO_FIX_MESSAGE},global2)}applied.push(...batch)}catch(error){failed.push(...batch.map(fix=>({fix,error})))}}return{applied,failed}}const _testOnlyValidateCommand={applyValidateFix,applyValidateFixes,attachValidateFixHints,buildCommandReferencesCheck,buildDependencyReferencesCheck,buildCloseReasonBackfillRows,buildFilesCheck,buildLifecycleCheck,buildLifecycleDependencyGraph,buildLifecycleParentGraph,buildEstimateBackfillRows,buildMetadataCounts,buildMissingFieldOccurrences,buildOrphanedPathRows,classifyOrphanedPath,collectDefaultProjectFileCandidates,collectTrackedGitFileCandidates,detectLifecycleDependencyCycles,detectLifecycleParentCycles,escapeRegExp,extractItemIds,findLifecycleDependencyCycleComponents,isMetadataFieldMissing,linkedArtifactPathExceedsFilesystemLimits,listFilesRecursive,resolveDependencyCycleSeverity,resolveParentCycleSeverity,resolveFileScanMode,resolveLifecycleDependencyCycleSamplePath,resolveRequestedChecks,resolveValidateMetadataProfile,resolveWorkspaceRoot,sharedDirectoryPrefixLength,summarizeOrphanedPathRows,summarizeDuplicateIssueCodes,toMeaningfulString};function appendInvalidMergeReceiptEvidenceWarning(warnings,invalidEvidenceCount){if(invalidEvidenceCount>0){warnings.push(`merge_receipt_evidence_invalid:${invalidEvidenceCount}`)}}async function buildStorageIntegrityCheck(pmRoot,items,typeToFolder,settings){const scan=await scanStorageIntegrity(pmRoot,new Set(items.map(item=>item.id)),typeToFolder,{schema:settings.schema,extensionFieldNames:collectRegisteredItemFieldNames(getActiveExtensionRegistrations())});const warnings=[];if(scan.unreadable_item_files.length>0){warnings.push(`validate_storage_unreadable_items:${scan.unreadable_item_files.length}`)}if(scan.duplicate_item_ids.length>0){warnings.push(`validate_storage_duplicate_item_ids:${scan.duplicate_item_ids.length}`)}if(scan.history_conflict_marker_streams.length>0){warnings.push(`validate_storage_history_conflict_markers:${scan.history_conflict_marker_streams.length}`)}if(scan.history_unparseable_streams.length>0){warnings.push(`validate_storage_unparseable_history:${scan.history_unparseable_streams.length}`)}if(scan.resurrected_items.length>0){warnings.push(`validate_storage_resurrected_items:${scan.resurrected_items.length}`)}if(scan.unparseable_config_files.length>0){warnings.push(`validate_storage_unparseable_config:${scan.unparseable_config_files.length}`)}const errorCount=warnings.length;const trackedRuntimeCache=await scanTrackedRuntimeCache(pmRoot);if(trackedRuntimeCache.tracked_path_count>0){warnings.push(`validate_storage_tracked_runtime_cache_files:${trackedRuntimeCache.tracked_path_count}`)}const fenceAudit=await auditMergeAttributeFence(pmRoot,resolveProjectMergeTypeFolders(settings));if(fenceAudit.status==="drift"){warnings.push(`validate_merge_fence_drift:${fenceAudit.missing_patterns.length+fenceAudit.stale_patterns.length}`)}const gitWorkspaceRoot=await findGitWorkspaceRoot(pmRoot);const mergeDriverAudit=gitWorkspaceRoot===null?null:await auditMergeDriverConfiguration(gitWorkspaceRoot);if(mergeDriverAudit!==null&&mergeDriverAudit.status!=="ok"){warnings.push(`validate_merge_driver_configuration:${mergeDriverAudit.missing_keys.length+mergeDriverAudit.drifted_keys.length}`)}const mergeReceiptEvidence=await inspectMergeReceiptEvidence(gitWorkspaceRoot??pmRoot,{includeLossless:true,pmRoot});const pendingMergeReceipts=mergeReceiptEvidence.receipts;const{pendingDecisions:pendingMergeDecisions,lossless:losslessMergeReceipts}=partitionMergeReceipts(pendingMergeReceipts);if(pendingMergeDecisions.length>0){warnings.push(`validate_merge_decisions_unreviewed:${pendingMergeDecisions.length}`)}appendInvalidMergeReceiptEvidenceWarning(warnings,mergeReceiptEvidence.invalid_evidence_count);const status=errorCount>0?"error":warnings.length>0?"warn":"ok";return{check:{name:"storage_integrity",status,ok:status==="ok",details:{...scan,merge_fence:fenceAudit,merge_driver_configuration:mergeDriverAudit,pending_merge_decision_count:pendingMergeDecisions.length,pending_merge_decision_items:[...new Set(pendingMergeDecisions.map(receipt=>receipt.item_id))].sort((left,right)=>left.localeCompare(right)),lossless_merge_receipt_count:losslessMergeReceipts.length,invalid_merge_receipt_evidence_count:mergeReceiptEvidence.invalid_evidence_count,invalid_merge_receipt_evidence_details:mergeReceiptEvidence.invalid_evidence,invalid_merge_receipt_evidence_details_truncated:mergeReceiptEvidence.invalid_evidence_truncated,lossless_merge_receipt_items:[...new Set(losslessMergeReceipts.map(receipt=>receipt.item_id))].sort((left,right)=>left.localeCompare(right)),tracked_runtime_cache:{tracker_relative_root:trackedRuntimeCache.tracker_relative_root,tracked_paths:trackedRuntimeCache.tracked_paths,tracked_path_count:trackedRuntimeCache.tracked_path_count,remediation_command:trackedRuntimeCache.remediation_command}}},warnings}}function recordValidateCheck(state,built,fixHintsEnabled){if(fixHintsEnabled){attachValidateFixHints(built.check,built.warnings)}state.checks.push(built.check);state.warnings.push(...built.warnings)}async function executeRequestedValidateChecks(params){const state={closureTimestampFixes:[],checks:[],warnings:[...params.initialWarnings],closeReasonBackfillRows:[],estimateBackfillRows:[],resolutionBackfillRows:[],terminalParentFixRows:[],staleLinkPruneRows:[]};const fixHintsEnabled=params.options.fixHints===true;const fullDiagnostics=params.options.verboseDiagnostics===true||params.options.allAffectedIds===true||params.global.json===true;if(params.requestedChecks.has("completeness")){const built=await readWorkflowCompletenessCheck(params.pmRoot,params.items,fullDiagnostics?Infinity:DIAGNOSTIC_LIST_SUMMARY_LIMIT,params.sourceIncomplete);recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("metadata")){const built=buildMetadataCheck(params.items,params.metadataPolicy,params.statusRegistry,fullDiagnostics,[params.settings.id_prefix]);state.closeReasonBackfillRows=built.closeReasonBackfillRows;state.estimateBackfillRows=built.estimateBackfillRows;const timestamps=await scanClosureTimestamps(params.pmRoot,params.items,params.statusRegistry,params.options.autoFix===true||fixHintsEnabled,fullDiagnostics?Infinity:DIAGNOSTIC_LIST_SUMMARY_LIMIT);state.closureTimestampFixes=timestamps.fixes;Object.assign(built.check.details,timestamps.details);built.warnings.push(...timestamps.warnings);built.check.ok=built.warnings.length===0;built.check.status=built.check.ok?"ok":"warn";recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("resolution")){const built=buildResolutionCheck(params.items,params.statusRegistry,fullDiagnostics);state.resolutionBackfillRows=built.resolutionBackfillRows;recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("lifecycle")){const built=buildLifecycleCheck(params.items,Boolean(params.options.checkStaleBlockers),params.dependencyCycleSeverity,params.parentCycleSeverity,params.statusRegistry,params.lifecyclePatternPolicy,fullDiagnostics,params.settings.id_prefix);state.terminalParentFixRows=built.terminalParentFixRows;recordValidateCheck(state,built,fixHintsEnabled);recordValidateCheck(state,buildDependencyReferencesCheck(params.items,fullDiagnostics,params.statusRegistry),fixHintsEnabled)}if(params.requestedChecks.has("files")){const built=await buildFilesCheck(params.items,params.workspaceRoot,params.pmRoot,params.fileScanMode,Boolean(params.options.includePmInternals),Boolean(params.options.verboseFileLists),params.statusRegistry);state.staleLinkPruneRows=built.staleLinkPruneRows;recordValidateCheck(state,built,fixHintsEnabled)}if(params.requestedChecks.has("command_references")){recordValidateCheck(state,await buildCommandReferencesCheck(params.items,params.settings.id_prefix,fullDiagnostics,params.pmRoot),fixHintsEnabled)}if(params.requestedChecks.has("history_drift")){recordValidateCheck(state,await buildValidateHistoryDriftCheck(params.pmRoot,params.items,fullDiagnostics),fixHintsEnabled)}if(params.requestedChecks.has("format_version")){recordValidateCheck(state,buildFormatVersionCheck(params.items,fullDiagnostics),fixHintsEnabled)}if(params.requestedChecks.has("storage_integrity")){recordValidateCheck(state,await buildStorageIntegrityCheck(params.pmRoot,params.items,resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,params.settings),fixHintsEnabled)}return state}function planValidateFixes(options,state,settings){const planned=[];if(options.autoFix===true){planned.push(...state.closureTimestampFixes);planned.push(...planCloseReasonBackfillFixes(state.closeReasonBackfillRows));planned.push(...planResolutionBackfillFixes(state.resolutionBackfillRows));planned.push(...planEstimateBackfillFixes(state.estimateBackfillRows,settings.validation.estimate_defaults_by_type));planned.push(...planTerminalParentFixes(state.terminalParentFixRows))}if(options.pruneMissing===true){planned.push(...planStaleLinkPruneFixes(state.staleLinkPruneRows))}return planned}async function buildValidateFixesSummary(options,state,settings,grantedFixScopes,global2,services){if(options.autoFix!==true&&options.pruneMissing!==true){return void 0}const planned=planValidateFixes(options,state,settings);const{applicable,gated}=partitionFixesByGrant(planned,grantedFixScopes);const dryRun=options.dryRun===true;const appliedFixRows=[];const failedFixRows=[];if(!dryRun){const applied=await applyValidateFixes(applicable,global2,services);appliedFixRows.push(...applied.applied.map(toFixOutputRow));failedFixRows.push(...applied.failed.map(({fix,error})=>({...toFixOutputRow(fix),error:error instanceof Error?error.message:String(error)})))}return{mode:dryRun?"dry_run":"apply",auto_fix:options.autoFix===true,prune_missing:options.pruneMissing===true,granted_fix_scopes:[...grantedFixScopes].sort((left,right)=>left.localeCompare(right)),planned_count:planned.length,applied_count:appliedFixRows.length,gated_count:gated.length,failed_count:failedFixRows.length,planned_fixes:planned.map(toFixOutputRow),applied_fixes:appliedFixRows,gated_fixes:gated.map(fix=>({...toFixOutputRow(fix),gate_hint:`Withheld: re-run with --fix-scope ${fix.gate} to apply.`})),failed_fixes:failedFixRows}}async function runValidate(options,global2,services={}){assertProjectionModeChoice(options.counts===true,options.full===true,"--counts");const fixesRequested=options.autoFix===true||options.pruneMissing===true;if(options.dryRun===true&&!fixesRequested){throw new PmCliError("--dry-run requires --auto-fix or --prune-missing (there is nothing to preview otherwise).",EXIT_CODE.USAGE)}if(options.fixScope!==void 0&&options.fixScope.length>0&&options.autoFix!==true){throw new PmCliError("--fix-scope requires --auto-fix.",EXIT_CODE.USAGE)}const grantedFixScopes=resolveGrantedFixScopes(options.fixScope);const pmRoot=resolvePmRoot(process.cwd(),global2.path);await assertInitializedTracker(pmRoot);const settings=await readSettings(pmRoot);const statusRegistry=resolveRuntimeStatusRegistry(settings.schema);const typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());const requestedChecks=resolveRequestedChecks(options);const itemReadWarnings=[];const items=await readValidateItems({includeBody:["history_drift","metadata","completeness"].some(check=>requestedChecks.has(check)),pmRoot,settings,typeToFolder:typeRegistry.type_to_folder,warnings:itemReadWarnings});const sourceIncomplete=itemReadWarnings.length>0;if(requestedChecks.has("history_drift")){const authorAttribution=await scanHistoryAuthorAttribution(pmRoot);if(authorAttribution.actionable_unknown_event_count>0){itemReadWarnings.push(`validate_history_unknown_author_events:${authorAttribution.actionable_unknown_event_count}`)}}const metadataProfileSource=typeof options.metadataProfile==="string"?"option":"settings";const metadataProfile=resolveValidateMetadataProfile(typeof options.metadataProfile==="string"?options.metadataProfile:settings.validation.metadata_profile);const metadataPolicy=resolveValidateMetadataPolicy(metadataProfile,metadataProfileSource,settings.validation.metadata_required_fields);const lifecyclePatternPolicy=resolveLifecyclePatternPolicy(settings);const dependencyCycleSeverity=resolveDependencyCycleSeverity(options.dependencyCycleSeverity);const parentCycleSeverity=resolveParentCycleSeverity(options.parentCycleSeverity);const fileScanMode=resolveFileScanMode(options.scanMode);const workspaceRoot=resolveWorkspaceRoot(pmRoot);const state=await executeRequestedValidateChecks({requestedChecks,options,global:global2,pmRoot,workspaceRoot,settings,items,statusRegistry,metadataPolicy,lifecyclePatternPolicy,dependencyCycleSeverity,parentCycleSeverity,fileScanMode,initialWarnings:[...new Set(itemReadWarnings)],sourceIncomplete});const fixes=fixesRequested?await buildValidateFixesSummary(options,state,settings,grantedFixScopes,global2,services):void 0;const normalizedWarnings=[...new Set(state.warnings)].sort((left,right)=>left.localeCompare(right));const hasErrors=state.checks.some(check=>check.status==="error");const result={ok:!hasErrors,has_warnings:normalizedWarnings.length>0,checks:state.checks,warnings:normalizedWarnings,...fixes!==void 0?{fixes}:{},generated_at:nowIso(),projection:{mode:"full",declared_field_groups:[{name:"diagnostic_rows",restore_with:"--full"}],included_field_groups:["diagnostic_rows"]}};if(options.counts!==true)return result;return{...projectValidateCounts(result),projection:{mode:"counts",declared_field_groups:[{name:"diagnostic_rows",restore_with:"--full"}],included_field_groups:[]}}}export{_testOnlyValidateCommand,projectValidateCounts,runValidate};
|
|
2
2
|
//# sourceMappingURL=validate.js.map
|
package/dist/sdk/governance.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from "./governance/workspace-position.js";
|
|
|
22
22
|
export * from "./governance/workflow-policy.js";
|
|
23
23
|
export { runUpgrade, type UpgradeCliResult, type UpgradeCommandOptions, type UpgradeCommandRunner, type UpgradeCommandRunnerResult, type UpgradePackageResult, type UpgradeResult, } from "./governance/upgrade.js";
|
|
24
24
|
export * from "./governance/validate.js";
|
|
25
|
+
export * from "./governance/closure-timestamps.js";
|
|
25
26
|
export * from "./governance/linked-file-report.js";
|
|
26
27
|
export * from "./author-attribution.js";
|
|
27
28
|
export * from "./mutation-guard.js";
|
package/dist/sdk/governance.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="47924d35-d6ce-5507-adbf-c4c3cb25c18e")}catch(e2){}})();export*from"./governance/gc.js";export*from"./governance/health.js";export*from"./governance/extension-host-version.js";export*from"./governance/assurance.js";export*from"./governance/assurance-action.js";export*from"./governance/assurance-mutation-error.js";export*from"./governance/assurance-presets.js";export*from"./governance/assurance-runtime.js";export*from"./governance/boundary-fixtures.js";export*from"./governance/defect-recurrence.js";export*from"./governance/defect-recurrence-coverage.js";import{runReindex}from"./governance/reindex.js";export*from"./governance/stale-work.js";export*from"./governance/storage-integrity.js";export*from"./governance/status-role-diagnostics.js";export*from"./governance/workspace-position.js";export*from"./governance/workflow-policy.js";import{runUpgrade}from"./governance/upgrade.js";export*from"./governance/validate.js";export*from"./governance/closure-timestamps.js";export*from"./governance/linked-file-report.js";export*from"./author-attribution.js";export*from"./mutation-guard.js";export*from"./governance/provenance-health.js";export*from"./similarity.js";export*from"./history/maintenance.js";export*from"./history/attestation.js";export*from"./history/attestation-command.js";export*from"../core/history/digest.js";export{runReindex,runUpgrade};
|
|
2
2
|
//# sourceMappingURL=governance.js.map
|