@shrkcrft/inspector 0.1.0-alpha.31 → 0.1.0-alpha.32

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.
Files changed (134) hide show
  1. package/dist/agent-task-prep.d.ts.map +1 -1
  2. package/dist/agent-task-prep.js +9 -1
  3. package/dist/codemod-assist.d.ts.map +1 -1
  4. package/dist/codemod-assist.js +3 -1
  5. package/dist/comment-syntax.d.ts +15 -0
  6. package/dist/comment-syntax.d.ts.map +1 -0
  7. package/dist/comment-syntax.js +15 -0
  8. package/dist/contribution-load-failures.d.ts +18 -2
  9. package/dist/contribution-load-failures.d.ts.map +1 -1
  10. package/dist/contribution-load-failures.js +20 -3
  11. package/dist/contributions-report.js +2 -2
  12. package/dist/convention-applicability.d.ts +46 -0
  13. package/dist/convention-applicability.d.ts.map +1 -0
  14. package/dist/convention-applicability.js +247 -0
  15. package/dist/convention-filter-level.d.ts +13 -0
  16. package/dist/convention-filter-level.d.ts.map +1 -0
  17. package/dist/convention-filter-level.js +13 -0
  18. package/dist/convention-registry.d.ts +29 -4
  19. package/dist/convention-registry.d.ts.map +1 -1
  20. package/dist/convention-registry.js +58 -23
  21. package/dist/custom-checks.d.ts.map +1 -1
  22. package/dist/custom-checks.js +6 -4
  23. package/dist/decision-records.d.ts +4 -0
  24. package/dist/decision-records.d.ts.map +1 -1
  25. package/dist/decision-records.js +165 -66
  26. package/dist/declared-reference-coverage.d.ts +1 -1
  27. package/dist/declared-reference-coverage.d.ts.map +1 -1
  28. package/dist/declared-reference-coverage.js +6 -1
  29. package/dist/feedback-ingestion.d.ts.map +1 -1
  30. package/dist/feedback-ingestion.js +7 -1
  31. package/dist/file-languages.d.ts +9 -0
  32. package/dist/file-languages.d.ts.map +1 -0
  33. package/dist/file-languages.js +91 -0
  34. package/dist/fix-preview.d.ts.map +1 -1
  35. package/dist/fix-preview.js +78 -17
  36. package/dist/fuzzy-impact.d.ts.map +1 -1
  37. package/dist/fuzzy-impact.js +2 -1
  38. package/dist/git-helpers.d.ts +29 -4
  39. package/dist/git-helpers.d.ts.map +1 -1
  40. package/dist/git-helpers.js +69 -10
  41. package/dist/i-contribution-file-validation.d.ts +8 -0
  42. package/dist/i-contribution-file-validation.d.ts.map +1 -1
  43. package/dist/i-convention-applicability-reason.d.ts +29 -0
  44. package/dist/i-convention-applicability-reason.d.ts.map +1 -0
  45. package/dist/i-convention-applicability-reason.js +1 -0
  46. package/dist/i-convention-applicability.d.ts +9 -0
  47. package/dist/i-convention-applicability.d.ts.map +1 -0
  48. package/dist/i-convention-applicability.js +1 -0
  49. package/dist/i-convention-scope.d.ts +19 -0
  50. package/dist/i-convention-scope.d.ts.map +1 -0
  51. package/dist/i-convention-scope.js +1 -0
  52. package/dist/i-file-language.d.ts +11 -0
  53. package/dist/i-file-language.d.ts.map +1 -0
  54. package/dist/i-file-language.js +1 -0
  55. package/dist/i-not-applicable-convention.d.ts +17 -0
  56. package/dist/i-not-applicable-convention.d.ts.map +1 -0
  57. package/dist/i-not-applicable-convention.js +1 -0
  58. package/dist/i-reference-pack-origin.d.ts +13 -0
  59. package/dist/i-reference-pack-origin.d.ts.map +1 -0
  60. package/dist/i-reference-pack-origin.js +1 -0
  61. package/dist/i-stale-path-hint-input.d.ts +18 -0
  62. package/dist/i-stale-path-hint-input.d.ts.map +1 -0
  63. package/dist/i-stale-path-hint-input.js +1 -0
  64. package/dist/i-unverifiable-remedy-group.d.ts +10 -0
  65. package/dist/i-unverifiable-remedy-group.d.ts.map +1 -0
  66. package/dist/i-unverifiable-remedy-group.js +1 -0
  67. package/dist/index.d.ts +17 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +25 -0
  70. package/dist/knowledge-authoring.d.ts +1 -1
  71. package/dist/knowledge-authoring.d.ts.map +1 -1
  72. package/dist/knowledge-authoring.js +7 -6
  73. package/dist/knowledge-contribution-slots.d.ts +18 -0
  74. package/dist/knowledge-contribution-slots.d.ts.map +1 -0
  75. package/dist/knowledge-contribution-slots.js +25 -0
  76. package/dist/knowledge-entry-rejections.d.ts +17 -0
  77. package/dist/knowledge-entry-rejections.d.ts.map +1 -0
  78. package/dist/knowledge-entry-rejections.js +79 -0
  79. package/dist/knowledge-entry-verdict-record.d.ts +12 -0
  80. package/dist/knowledge-entry-verdict-record.d.ts.map +1 -1
  81. package/dist/knowledge-min-referenced-valve.d.ts +12 -0
  82. package/dist/knowledge-min-referenced-valve.d.ts.map +1 -0
  83. package/dist/knowledge-min-referenced-valve.js +12 -0
  84. package/dist/knowledge-rejected-entry.d.ts +28 -0
  85. package/dist/knowledge-rejected-entry.d.ts.map +1 -0
  86. package/dist/knowledge-rejected-entry.js +1 -0
  87. package/dist/knowledge-rename-command.d.ts +20 -0
  88. package/dist/knowledge-rename-command.d.ts.map +1 -0
  89. package/dist/knowledge-rename-command.js +34 -0
  90. package/dist/knowledge-rename-verb.d.ts +11 -0
  91. package/dist/knowledge-rename-verb.d.ts.map +1 -0
  92. package/dist/knowledge-rename-verb.js +11 -0
  93. package/dist/knowledge-rename.d.ts +1 -1
  94. package/dist/knowledge-rename.d.ts.map +1 -1
  95. package/dist/knowledge-rename.js +6 -5
  96. package/dist/knowledge-stale-gate.d.ts +2 -0
  97. package/dist/knowledge-stale-gate.d.ts.map +1 -1
  98. package/dist/knowledge-stale-gate.js +75 -3
  99. package/dist/knowledge-stale-quality-gate.d.ts.map +1 -1
  100. package/dist/knowledge-stale-quality-gate.js +34 -4
  101. package/dist/knowledge-stale.d.ts +10 -0
  102. package/dist/knowledge-stale.d.ts.map +1 -1
  103. package/dist/knowledge-stale.js +227 -33
  104. package/dist/knowledge-unverifiable-remedy.d.ts +56 -0
  105. package/dist/knowledge-unverifiable-remedy.d.ts.map +1 -0
  106. package/dist/knowledge-unverifiable-remedy.js +0 -0
  107. package/dist/pack-contributions-inventory.d.ts.map +1 -1
  108. package/dist/pack-contributions-inventory.js +4 -2
  109. package/dist/propose-knowledge.js +3 -2
  110. package/dist/reference-pack-origin.d.ts +18 -0
  111. package/dist/reference-pack-origin.d.ts.map +1 -0
  112. package/dist/reference-pack-origin.js +38 -0
  113. package/dist/repository-stats.d.ts.map +1 -1
  114. package/dist/repository-stats.js +3 -77
  115. package/dist/resolve-project-config.d.ts.map +1 -1
  116. package/dist/resolve-project-config.js +10 -1
  117. package/dist/self-config-doctor-v2.d.ts +1 -1
  118. package/dist/self-config-doctor-v2.d.ts.map +1 -1
  119. package/dist/self-config-doctor-v2.js +76 -12
  120. package/dist/self-config-doctor.d.ts.map +1 -1
  121. package/dist/self-config-doctor.js +2 -1
  122. package/dist/sharkcraft-inspector.d.ts.map +1 -1
  123. package/dist/sharkcraft-inspector.js +52 -12
  124. package/dist/stale-path-hint.d.ts +3 -0
  125. package/dist/stale-path-hint.d.ts.map +1 -0
  126. package/dist/stale-path-hint.js +47 -0
  127. package/dist/template-authoring.d.ts +1 -1
  128. package/dist/template-authoring.d.ts.map +1 -1
  129. package/dist/template-authoring.js +2 -1
  130. package/dist/validate-contribution-file.d.ts.map +1 -1
  131. package/dist/validate-contribution-file.js +15 -10
  132. package/dist/why-file.d.ts.map +1 -1
  133. package/dist/why-file.js +5 -4
  134. package/package.json +17 -17
@@ -24,7 +24,8 @@
24
24
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
25
25
  import * as nodePath from 'node:path';
26
26
  import { globListSelects, globToRegex } from '@shrkcrft/boundaries';
27
- import { KNOWLEDGE_REFERENCE_KINDS, todayUtcIso, verifiedOnAgeDays, } from '@shrkcrft/knowledge';
27
+ import { KnowledgeReferenceRoot } from '@shrkcrft/core';
28
+ import { KNOWLEDGE_REFERENCE_KINDS, referenceRootProblem, anchorShapeProblem, anchorsListProblem, declaredAnchorItems, declaredReferenceItems, knowledgeAnchors, knowledgeSourceFormat, referenceShapeProblem, referencesListProblem, todayUtcIso, verifiedOnAgeDays, } from '@shrkcrft/knowledge';
28
29
  import { isCacheBackedKind, isReferenceCacheWarm, referenceIdExists, referenceIdsFor, } from "./reference-registry.js";
29
30
  import { listPolicyDeclarations } from "./policy-registry.js";
30
31
  import { checkReferenceContent, checkReferenceCount, hasContentAssertion, } from "./reference-content-check.js";
@@ -32,13 +33,28 @@ import { ReferenceFailure } from "./reference-failure.js";
32
33
  import { KnowledgeEntryVerdict } from "./knowledge-entry-verdict.js";
33
34
  import { KnowledgeUnverifiableReason } from "./knowledge-unverifiable-reason.js";
34
35
  import { KnowledgeAdvisoryCode } from "./knowledge-advisory-code.js";
36
+ import { knowledgeRejectedEntries } from "./knowledge-entry-rejections.js";
35
37
  import { ReferenceAssetKind } from "./reference-asset-kind.js";
38
+ import { stalePathHint } from "./stale-path-hint.js";
36
39
  import { buildSymbolIndex } from "./symbol-index.js";
37
40
  // The `command` reference case (and its anchor twin) — one injected resolver.
38
41
  import { COMMAND_INDEX_NOT_INJECTED, resolveShrkCommandReference } from "./reference-registry.js";
39
42
  import { CommandResolutionStatus } from "./command-resolution-status.js";
40
43
  import { resolveSymbolInFile, SymbolResolution } from "./symbol-index.js";
44
+ import { packOriginByName, packOriginOfFile } from "./reference-pack-origin.js";
41
45
  export const KNOWLEDGE_STALE_SCHEMA = 'sharkcraft.knowledge-stale/v1';
46
+ /** The `byReferenceKind` bucket of an item with no kind to bucket under (a string, a non-list value). */
47
+ const MALFORMED_KIND_BUCKET = '(malformed)';
48
+ /**
49
+ * A declared value as a check row carries it: `null` / `undefined` become their
50
+ * text, so no renderer dereferences them; anything else as declared
51
+ * (`formatKnowledgeReference` renders a non-object as written). The CHECK reads
52
+ * the original, so a `null` item says "is not an object (got null)" — the
53
+ * validator's words — not "is the string \"null\"".
54
+ */
55
+ function displayedReference(value) {
56
+ return (value === null || value === undefined ? String(value) : value);
57
+ }
42
58
  export var ReferenceCheckOutcome;
43
59
  (function (ReferenceCheckOutcome) {
44
60
  ReferenceCheckOutcome["Ok"] = "ok";
@@ -269,11 +285,20 @@ function workspacePackages(inspection) {
269
285
  WORKSPACE_PACKAGES.set(inspection, out);
270
286
  return out;
271
287
  }
272
- function checkPackageReference(inspection, id) {
288
+ function checkPackageReference(inspection, id, origin) {
273
289
  const dir = workspacePackages(inspection).get(id);
274
290
  if (dir) {
275
291
  return { outcome: ReferenceCheckOutcome.Ok, message: `Package exists: ${id} (${dir})` };
276
292
  }
293
+ // A pack's entry naming the pack that ships it (round 15 follow-up): the
294
+ // consumer's root package.json names neither its installed packs nor their
295
+ // names, but the contributing pack is installed by definition.
296
+ if (origin && origin.packageName === id) {
297
+ return {
298
+ outcome: ReferenceCheckOutcome.Ok,
299
+ message: `Package exists: ${id} (the contributing pack, installed at ${origin.displayRoot})`,
300
+ };
301
+ }
277
302
  // Last-resort backstop for repos without a `workspaces` field — reported as
278
303
  // probable, because a directory name is not a package name.
279
304
  const rel = id.startsWith('@') ? (id.split('/')[1] ?? '') : id;
@@ -479,14 +504,102 @@ function escapeRe(s) {
479
504
  * `contains` / `matches` / `count`, does the target still say what the asset
480
505
  * claims. Every non-ok result carries a {@link ReferenceFailure}.
481
506
  */
482
- function checkReference(inspection, ref, graph, excludeDirs = []) {
483
- const base = checkReferenceTarget(inspection, ref, graph);
484
- const result = base.outcome === ReferenceCheckOutcome.Ok
485
- ? applyAssertions(inspection.projectRoot, ref, base, excludeDirs)
486
- : base;
487
- if (result.outcome === ReferenceCheckOutcome.Ok || result.failure !== undefined)
507
+ function checkReference(inspection, ref, graph, excludeDirs = [], origin, subject) {
508
+ // THE item-shape predicate the validator applies (a string the grammar
509
+ // refused, a number, a non-string `path`): MALFORMED here — never a crash in a
510
+ // path join, never a silent row.
511
+ const shape = referenceShapeProblem(ref);
512
+ if (shape) {
513
+ return {
514
+ outcome: ReferenceCheckOutcome.Invalid,
515
+ failure: ReferenceFailure.Malformed,
516
+ message: `malformed reference: ${shape}.`,
517
+ };
518
+ }
519
+ // THE `root` predicate the validator applies (round 15 follow-up): `root:
520
+ // pack` on an asset no pack contributes is MALFORMED — never a silent
521
+ // fallback to the project root, which would read a different file.
522
+ const rootProblem = referenceRootProblem(ref, origin !== undefined);
523
+ if (rootProblem?.severity === 'error') {
524
+ return {
525
+ outcome: ReferenceCheckOutcome.Invalid,
526
+ failure: ReferenceFailure.Malformed,
527
+ message: `malformed reference: ${rootProblem.message}.`,
528
+ };
529
+ }
530
+ // A `root: pack` that has an effect (the predicate's warning means none)
531
+ // moves every path read — the target, `contains` / `matches`, a `count`
532
+ // source — into the contributing pack's directory. The consumer's code graph
533
+ // never indexes a pack's files, and its count exclusions are consumer paths.
534
+ const pack = origin !== undefined && rootProblem === undefined && isPackRooted(ref) ? origin : undefined;
535
+ const rootDir = pack ? pack.packageRoot : inspection.projectRoot;
536
+ const base = checkReferenceTarget(inspection, ref, pack ? undefined : graph, rootDir, origin);
537
+ const asserted = base.outcome === ReferenceCheckOutcome.Ok ? applyAssertions(rootDir, ref, base, pack ? [] : excludeDirs) : base;
538
+ const result = asserted.outcome === ReferenceCheckOutcome.Ok || asserted.failure !== undefined
539
+ ? asserted
540
+ : { ...asserted, failure: defaultFailure(ref.kind, asserted.outcome) };
541
+ const labelled = pack ? packRootedResult(result, pack) : result;
542
+ return withStalePathHint(labelled, ref, origin, pack !== undefined, subject);
543
+ }
544
+ /** A reference whose path resolves against its contributing pack's directory (`root: pack`). */
545
+ function isPackRooted(ref) {
546
+ return ref !== null && typeof ref === 'object' && ref.root === KnowledgeReferenceRoot.Pack;
547
+ }
548
+ /**
549
+ * Every row of a pack-rooted reference names the root it resolved against —
550
+ * the renderers (text, gate violations, markdown, MCP) all print the message.
551
+ * A missing path is fixed in the pack, never by a consumer-side rename (the
552
+ * hint is {@link stalePathHint}'s).
553
+ */
554
+ function packRootedResult(result, pack) {
555
+ return { ...result, message: `${result.message} (root: pack — ${pack.packageName} at ${pack.displayRoot})` };
556
+ }
557
+ /**
558
+ * A missing path's hint, from THE authority ({@link stalePathHint}, round 15
559
+ * closing A3): who declared the reference decides who fixes it — a pack (the
560
+ * round-15 repro: a pack doc referencing its own file read STALE, with a hint
561
+ * to rename a file the consumer does not own), a Markdown entry's frontmatter,
562
+ * or a rename. No other code path sets a missing path's `suggestion`.
563
+ */
564
+ function withStalePathHint(result, ref, origin, packRooted, subject) {
565
+ if (result.failure !== ReferenceFailure.PathMissing || typeof ref.path !== 'string' || ref.path === '')
488
566
  return result;
489
- return { ...result, failure: defaultFailure(ref.kind, result.outcome) };
567
+ const suggestion = stalePathHint({
568
+ kind: String(ref.kind),
569
+ path: normalizeRel(ref.path),
570
+ packRooted,
571
+ ...(origin !== undefined ? { pack: origin } : {}),
572
+ ...(subject?.sourceFormat !== undefined ? { sourceFormat: subject.sourceFormat } : {}),
573
+ ...(subject?.source !== undefined ? { source: subject.source } : {}),
574
+ });
575
+ return suggestion === undefined ? result : { ...result, suggestion };
576
+ }
577
+ /**
578
+ * A reference as the changeset scope sees it: a pack-rooted path — and a
579
+ * pack-rooted `count` source's globs, the tree the count is MEASURED over —
580
+ * made project-relative. Unprefixed, a count over the pack's `src/*.ts` was
581
+ * scoped in by a change to the CONSUMER's `src/` and never by the pack's.
582
+ */
583
+ function scopedReference(ref, origin) {
584
+ if (!origin || !isPackRooted(ref) || origin.displayRoot === '.')
585
+ return ref;
586
+ const at = (rel) => `${origin.displayRoot}/${normalizeRel(rel)}`;
587
+ const globs = ref.count?.source?.files;
588
+ return {
589
+ ...ref,
590
+ ...(typeof ref.path === 'string' ? { path: at(ref.path) } : {}),
591
+ ...(ref.count && Array.isArray(globs)
592
+ ? {
593
+ count: {
594
+ ...ref.count,
595
+ source: {
596
+ ...ref.count.source,
597
+ files: globs.map((g) => (typeof g === 'string' && g.startsWith('!') ? `!${at(g.slice(1))}` : at(String(g)))),
598
+ },
599
+ },
600
+ }
601
+ : {}),
602
+ };
490
603
  }
491
604
  /** The failure mode of a non-ok check that did not name one. */
492
605
  function defaultFailure(kind, outcome) {
@@ -543,8 +656,10 @@ function assertionFailure(base, a, what) {
543
656
  };
544
657
  }
545
658
  /** Does the reference's TARGET exist? (Assertions are layered on by {@link checkReference}.) */
546
- function checkReferenceTarget(inspection, ref, graph) {
547
- const projectRoot = inspection.projectRoot;
659
+ function checkReferenceTarget(inspection, ref, graph, rootDir = inspection.projectRoot, origin) {
660
+ // The directory a path resolves against: the project root, or the
661
+ // contributing pack's directory for a `root: pack` reference.
662
+ const projectRoot = rootDir;
548
663
  switch (ref.kind) {
549
664
  case 'file': {
550
665
  if (!ref.path)
@@ -564,7 +679,7 @@ function checkReferenceTarget(inspection, ref, graph) {
564
679
  outcome: ReferenceCheckOutcome.Stale,
565
680
  failure: ReferenceFailure.PathMissing,
566
681
  message: `Directory missing: ${ref.path}`,
567
- suggestion: 'Move the directory or update the knowledge reference.',
682
+ // The hint is {@link stalePathHint}'s — who declared it decides (A3).
568
683
  };
569
684
  }
570
685
  case 'symbol': {
@@ -615,7 +730,7 @@ function checkReferenceTarget(inspection, ref, graph) {
615
730
  case 'package': {
616
731
  if (!ref.id)
617
732
  return missingField('package', 'id');
618
- return checkPackageReference(inspection, ref.id);
733
+ return checkPackageReference(inspection, ref.id, origin);
619
734
  }
620
735
  case 'url': {
621
736
  // We never fetch URLs. Mark them unknown unless we can resolve to a
@@ -643,12 +758,12 @@ function missingField(kind, field) {
643
758
  message: `malformed reference: ${kind} reference missing required field \`${field}\`.`,
644
759
  };
645
760
  }
761
+ /** A missing file — its hint is {@link stalePathHint}'s, who declared the reference decides (A3). */
646
762
  function staleFile(rel) {
647
763
  return {
648
764
  outcome: ReferenceCheckOutcome.Stale,
649
765
  failure: ReferenceFailure.PathMissing,
650
766
  message: `File missing: ${rel}`,
651
- suggestion: 'Restore the file or run `shrk knowledge rename-file <old> <new> --dry-run`.',
652
767
  };
653
768
  }
654
769
  function staleId(kind, id) {
@@ -700,7 +815,10 @@ function subjectTouchesChangedFiles(subject, changed) {
700
815
  if (changedList.includes(normalizeScopePath(subject.source)))
701
816
  return true;
702
817
  for (const ref of subject.references ?? []) {
703
- if (pathTouched(ref.path, changedList))
818
+ // A malformed item (a string, a number) points at no path.
819
+ if (ref === null || typeof ref !== 'object')
820
+ continue;
821
+ if (pathTouched(typeof ref.path === 'string' ? ref.path : undefined, changedList))
704
822
  return true;
705
823
  // The scope the count is MEASURED over (`inspectSource` selects through
706
824
  // `globListSelects`), so a change to a file its `!` excludes is no touch.
@@ -822,10 +940,14 @@ const PATH_ONLY_ADVISORY_CAP = 5;
822
940
  * — the strong form (`symbol` pinned to the path) catches it. Never gating.
823
941
  */
824
942
  function pathOnlyAdvisories(projectRoot, entry, refs, cache) {
825
- if (refs.length === 0 || !refs.every((r) => r.kind === 'file' || r.kind === 'directory'))
943
+ // A malformed item (a string, a null, a non-string path) earns no advisory — it is an INVALID row.
944
+ if (refs.length === 0 ||
945
+ !refs.every((r) => referenceShapeProblem(r) === undefined && (r.kind === 'file' || r.kind === 'directory'))) {
826
946
  return [];
947
+ }
827
948
  const files = refs
828
- .filter((r) => r.kind === 'file' && r.path !== undefined && TS_SOURCE.test(r.path))
949
+ // A pack-rooted path names a file in the pack, not in this tree (round 15 follow-up).
950
+ .filter((r) => r.kind === 'file' && r.path !== undefined && TS_SOURCE.test(r.path) && !isPackRooted(r))
829
951
  .map((r) => r.path);
830
952
  if (files.length === 0)
831
953
  return [];
@@ -916,12 +1038,12 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
916
1038
  * for a knowledge entry, a boundary rule and a policy check, so every asset
917
1039
  * kind is verified by one checker.
918
1040
  */
919
- const checkOne = (subjectId, ref, assetKind) => {
920
- const result = checkReference(inspection, ref, options.graph, excludeDirs);
1041
+ const checkOne = (subjectId, ref, assetKind, origin, subject) => {
1042
+ const result = checkReference(inspection, ref, options.graph, excludeDirs, origin, subject);
921
1043
  const outcome = result.outcome;
922
1044
  const check = {
923
1045
  entryId: subjectId,
924
- reference: ref,
1046
+ reference: displayedReference(ref),
925
1047
  outcome,
926
1048
  message: result.message,
927
1049
  ...(result.confidence ? { symbolConfidence: result.confidence } : {}),
@@ -931,10 +1053,16 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
931
1053
  ...(result.actual !== undefined ? { actual: result.actual } : {}),
932
1054
  ...(assetKind ? { assetKind } : {}),
933
1055
  };
934
- tallyOutcome((byReferenceKind[ref.kind] ??= { checked: 0, ok: 0, stale: 0, missing: 0, unknown: 0, invalid: 0 }), outcome);
1056
+ // A malformed item (a string, a number) has no kind to bucket under.
1057
+ const kindKey = ref !== null && typeof ref === 'object' && typeof ref.kind === 'string' ? ref.kind : MALFORMED_KIND_BUCKET;
1058
+ tallyOutcome((byReferenceKind[kindKey] ??= { checked: 0, ok: 0, stale: 0, missing: 0, unknown: 0, invalid: 0 }), outcome);
935
1059
  if (result.failure)
936
1060
  failureCounts[result.failure] += 1;
937
1061
  const isStaleOrMissing = outcome === ReferenceCheckOutcome.Stale || outcome === ReferenceCheckOutcome.Missing;
1062
+ // A pack's reference is fixed in the pack (round 15 follow-up): a candidate
1063
+ // from THIS tree is never its rename — `fix --knowledge-stale` would point
1064
+ // a pack's entry at a consumer file. Its hint names `root: pack` instead.
1065
+ const findRename = isStaleOrMissing && origin === undefined;
938
1066
  // A bare MEMBER name: the qualified spelling resolves in the same file, so
939
1067
  // it is the replacement (`shrk fix --knowledge-stale` applies it).
940
1068
  if (isStaleOrMissing && result.suggestedSymbol) {
@@ -948,7 +1076,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
948
1076
  // only for the single unambiguous candidate. Wide mode also
949
1077
  // emits scored candidate lists for the multi-candidate cases that
950
1078
  // strict silently drops.
951
- if (isStaleOrMissing && ref.kind === 'symbol' && ref.symbol && !check.replaceWith) {
1079
+ if (findRename && ref.kind === 'symbol' && ref.symbol && !check.replaceWith) {
952
1080
  const all = (getSymbolIndex().get(ref.symbol) ?? []).filter((p) => p !== ref.path);
953
1081
  if (all.length === 1) {
954
1082
  check.replaceWith = {
@@ -966,7 +1094,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
966
1094
  }
967
1095
  }
968
1096
  // File rename detection (directory move, basename match).
969
- if (isStaleOrMissing && ref.kind === 'file' && ref.path && !check.replaceWith) {
1097
+ if (findRename && ref.kind === 'file' && ref.path && !check.replaceWith) {
970
1098
  const indexed = getFileBasenameIndex();
971
1099
  const uniq = pickUniqueRenameCandidate(ref.path, indexed);
972
1100
  if (uniq) {
@@ -988,7 +1116,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
988
1116
  }
989
1117
  }
990
1118
  // Directory rename detection.
991
- if (isStaleOrMissing && ref.kind === 'directory' && ref.path && !check.replaceWith) {
1119
+ if (findRename && ref.kind === 'directory' && ref.path && !check.replaceWith) {
992
1120
  const indexed = getDirBasenameIndex();
993
1121
  const uniq = pickUniqueRenameCandidate(ref.path, indexed);
994
1122
  if (uniq) {
@@ -1012,21 +1140,61 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
1012
1140
  return check;
1013
1141
  };
1014
1142
  for (const entry of inspection.knowledgeEntries) {
1143
+ // EVERY declared item is judged (`declaredReferenceItems` /
1144
+ // `declaredAnchorItems`): a non-list `references` or `anchors` is never
1145
+ // iterated (it crashed every inspection-backed verb) — each is reported
1146
+ // below as one INVALID row — and a malformed item is checked into an
1147
+ // INVALID row carrying the validator's words (`displayedReference`).
1148
+ const refs = declaredReferenceItems(entry);
1149
+ const anchorItems = declaredAnchorItems(entry);
1150
+ // The contributing pack (round 15 follow-up) — what a `root: pack` reference resolves against.
1151
+ const entrySource = inspection.entrySources?.get(entry.id);
1152
+ const packOrigin = entrySource?.type === 'pack' ? packOriginByName(inspection, entrySource.packageName) : undefined;
1015
1153
  if (options.changedFiles &&
1016
1154
  !subjectTouchesChangedFiles({
1017
1155
  source: relativeSource(projectRoot, entry.source?.origin),
1018
- references: entry.references ?? [],
1019
- anchors: entry.anchors ?? [],
1156
+ references: refs.map((r) => scopedReference(r, packOrigin)),
1157
+ anchors: knowledgeAnchors(entry),
1020
1158
  }, options.changedFiles)) {
1021
1159
  continue;
1022
1160
  }
1023
- const refs = entry.references ?? [];
1024
- const anchors = entry.anchors ?? [];
1161
+ const sourceFormat = knowledgeSourceFormat(entry);
1025
1162
  let checkable = 0;
1026
1163
  let failing = 0;
1164
+ // A non-list `references` / `anchors` value (TypeScript or Markdown), or a
1165
+ // malformed anchor item: declared, never checkable — MALFORMED, the same
1166
+ // problem the validator reports. One INVALID row each.
1167
+ const malformedRow = (declaredValue, message) => {
1168
+ counts.invalid += 1;
1169
+ failureCounts[ReferenceFailure.Malformed] += 1;
1170
+ tallyOutcome((byReferenceKind[MALFORMED_KIND_BUCKET] ??= { checked: 0, ok: 0, stale: 0, missing: 0, unknown: 0, invalid: 0 }), ReferenceCheckOutcome.Invalid);
1171
+ referenceChecks.push({
1172
+ entryId: entry.id,
1173
+ // As declared: a string renders as written, a map as `kind:value`.
1174
+ reference: displayedReference(declaredValue),
1175
+ outcome: ReferenceCheckOutcome.Invalid,
1176
+ failure: ReferenceFailure.Malformed,
1177
+ message,
1178
+ });
1179
+ };
1180
+ const listProblem = referencesListProblem(entry.references, sourceFormat);
1181
+ if (listProblem) {
1182
+ totalReferences += 1;
1183
+ malformedRow(entry.references, `malformed reference: ${listProblem}.`);
1184
+ }
1185
+ // An anchor row names WHICH anchor (`anchors`, `anchor #N` — the doctor's
1186
+ // spelling): rendered through the reference grammar, an anchor object read
1187
+ // `undefined:<id>`.
1188
+ const anchorsProblem = anchorsListProblem(entry.anchors);
1189
+ if (anchorsProblem) {
1190
+ totalAnchors += 1;
1191
+ malformedRow('anchors', `malformed anchor: ${anchorsProblem}.`);
1192
+ }
1193
+ // Who fixes a missing path (A3): a Markdown entry names its `references:` frontmatter.
1194
+ const hintSubject = { sourceFormat, source: relativeSource(projectRoot, entry.source?.origin) };
1027
1195
  for (const ref of refs) {
1028
1196
  totalReferences += 1;
1029
- const check = checkOne(entry.id, ref);
1197
+ const check = checkOne(entry.id, ref, undefined, packOrigin, hintSubject);
1030
1198
  if (check.outcome === ReferenceCheckOutcome.Ok)
1031
1199
  counts.ok += 1;
1032
1200
  else if (check.outcome === ReferenceCheckOutcome.Stale)
@@ -1044,8 +1212,16 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
1044
1212
  }
1045
1213
  referenceChecks.push(check);
1046
1214
  }
1047
- for (const anchor of anchors) {
1215
+ for (const [i, item] of anchorItems.entries()) {
1048
1216
  totalAnchors += 1;
1217
+ // THE anchor item-shape predicate the validator applies: a `null` item
1218
+ // crashed `checkAnchor` (`anchor.kind`), a non-string path its path join.
1219
+ const shape = anchorShapeProblem(item);
1220
+ if (shape) {
1221
+ malformedRow(`anchor #${i + 1}`, `malformed anchor: ${shape}.`);
1222
+ continue;
1223
+ }
1224
+ const anchor = item;
1049
1225
  const inspected = checkAnchor(inspection, anchor, options.graph);
1050
1226
  const failure = inspected.outcome === ReferenceCheckOutcome.Ok
1051
1227
  ? undefined
@@ -1066,18 +1242,21 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
1066
1242
  });
1067
1243
  }
1068
1244
  const verdict = classifyChecks(checkable, failing);
1069
- const declared = refs.length + anchors.length;
1245
+ const declared = refs.length + anchorItems.length + (listProblem ? 1 : 0) + (anchorsProblem ? 1 : 0);
1070
1246
  const reason = verdict !== KnowledgeEntryVerdict.Unverifiable
1071
1247
  ? undefined
1072
1248
  : declared === 0
1073
1249
  ? KnowledgeUnverifiableReason.NoReferences
1074
1250
  : KnowledgeUnverifiableReason.OnlyUnverifiableReferences;
1075
1251
  const type = String(entry.type);
1252
+ const origin = inspection.entrySources?.get(entry.id);
1076
1253
  entryVerdicts.push({
1077
1254
  entryId: entry.id,
1078
1255
  verdict,
1079
1256
  ...(reason ? { reason } : {}),
1080
1257
  source: relativeSource(projectRoot, entry.source?.origin),
1258
+ sourceFormat,
1259
+ ...(origin?.type === 'pack' && origin.packageName ? { pack: origin.packageName } : {}),
1081
1260
  type,
1082
1261
  checkable,
1083
1262
  failing,
@@ -1112,15 +1291,29 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
1112
1291
  references: p.references ?? [],
1113
1292
  })),
1114
1293
  ];
1294
+ // The contributing pack of a boundary rule / policy check a pack declares
1295
+ // (round 15 follow-up) — the same `root: pack` resolution a knowledge entry gets.
1296
+ const subjectPackOrigin = (subject) => {
1297
+ if (subject.assetKind === ReferenceAssetKind.BoundaryRule) {
1298
+ const src = inspection.boundarySources?.get(subject.id);
1299
+ return src?.type === 'pack' ? packOriginByName(inspection, src.packageName) : undefined;
1300
+ }
1301
+ const decl = policyDecls.find((p) => p.qualifiedId === subject.id);
1302
+ return decl?.source === 'pack' ? packOriginOfFile(inspection, decl.sourceFile) : undefined;
1303
+ };
1115
1304
  for (const subject of subjects) {
1305
+ const packOrigin = subjectPackOrigin(subject);
1116
1306
  if (options.changedFiles &&
1117
- !subjectTouchesChangedFiles({ source: subject.source ?? '(unknown source)', references: subject.references }, options.changedFiles)) {
1307
+ !subjectTouchesChangedFiles({
1308
+ source: subject.source ?? '(unknown source)',
1309
+ references: subject.references.map((r) => scopedReference(r, packOrigin)),
1310
+ }, options.changedFiles)) {
1118
1311
  continue;
1119
1312
  }
1120
1313
  let checkable = 0;
1121
1314
  let failing = 0;
1122
1315
  for (const ref of subject.references) {
1123
- const check = checkOne(subject.id, ref, subject.assetKind);
1316
+ const check = checkOne(subject.id, ref, subject.assetKind, packOrigin);
1124
1317
  if (isCheckableOutcome(check.outcome)) {
1125
1318
  checkable += 1;
1126
1319
  if (isFailingOutcome(check.outcome))
@@ -1227,6 +1420,7 @@ export function buildKnowledgeStaleReport(inspection, options = {}) {
1227
1420
  coverage,
1228
1421
  entryVerdicts,
1229
1422
  unverifiableIds,
1423
+ rejectedEntries: knowledgeRejectedEntries(inspection),
1230
1424
  failureCounts,
1231
1425
  byAssetKind,
1232
1426
  byEntryType,
@@ -0,0 +1,56 @@
1
+ import type { IKnowledgeEntryVerdictRecord } from './knowledge-entry-verdict-record.js';
2
+ import { KnowledgeMinReferencedValve } from './knowledge-min-referenced-valve.js';
3
+ import type { IUnverifiableRemedyGroup } from './i-unverifiable-remedy-group.js';
4
+ /** The channel sentence: both formats can declare references. */
5
+ export declare const DECLARE_REFERENCES_REMEDY = "Declare references[] (TypeScript) or a references: frontmatter list (Markdown)";
6
+ /** The valve a surface names (the verb takes the flag; `quality` refuses it). */
7
+ export declare function minReferencedValveText(valve: KnowledgeMinReferencedValve): string;
8
+ /**
9
+ * The fix for ONE unverifiable entry — `undefined` only for a local TypeScript
10
+ * (or other non-Markdown) entry that declares NOTHING (the heading names
11
+ * `references[]`). It branches on the verdict REASON (round 15 closing, A4): an
12
+ * entry that declares references, none checkable (a malformed item — a
13
+ * non-boolean `required`, an unknown kind or `root` — or only `url:`s), is told
14
+ * to fix what it declared, never to "add a references: frontmatter list" /
15
+ * "declare references[]" it already has. A pack's entries are fixed upstream;
16
+ * their `file:` / `directory:` paths resolve against the CONSUMER's root unless
17
+ * the reference declares `root: pack` (round 15 follow-up, F7 — then against
18
+ * the pack's own directory), and `package:` reads the consumer's root
19
+ * package.json plus the pack's own name.
20
+ */
21
+ export declare function unverifiableFileRemedy(v: Pick<IKnowledgeEntryVerdictRecord, 'sourceFormat' | 'pack' | 'reason'>): string | undefined;
22
+ /**
23
+ * {@link unverifiableFileRemedy} for EVERY entry — what a per-entry row (the
24
+ * `--require-references` violation) prints: a local TypeScript entry that
25
+ * declares nothing is told to declare `references[]`, one whose references are
26
+ * all uncheckable to fix them (it read "declare references[]").
27
+ */
28
+ export declare function unverifiableEntryRemedy(v: Pick<IKnowledgeEntryVerdictRecord, 'sourceFormat' | 'pack' | 'reason'>): string;
29
+ /**
30
+ * The heading of the unverifiable list, after `UNVERIFIABLE (N) — never
31
+ * checked; ` — by reason (round 15 closing, A4): it told every entry to
32
+ * "declare references[] …, a references: frontmatter list (Markdown) or
33
+ * anchors[]", over entries whose references exist and are malformed.
34
+ */
35
+ export declare function unverifiableListHeading(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'verdict' | 'reason'>[]): string;
36
+ /**
37
+ * The remedy sentence for a run with unverifiable entries: the channel (or,
38
+ * for entries that declare references none of which is checkable, the fix to
39
+ * them — round 15 closing, A4), the valve this surface can name, and — when a
40
+ * pack contributed any of them — the pack that fixes them upstream.
41
+ */
42
+ export declare function unverifiableRemedy(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'verdict' | 'pack' | 'reason'>[], valve: KnowledgeMinReferencedValve): string;
43
+ /**
44
+ * Unverifiable entries grouped by declaring file AND remedy, in report order —
45
+ * THE grouping the stale-check's per-file lines and `quality`'s notes read. A
46
+ * file whose entries need different fixes gets one group per fix: the first
47
+ * entry's remedy used to speak for its whole file (round 15 closing, A4).
48
+ */
49
+ export declare function unverifiableRemedyGroups(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'entryId' | 'verdict' | 'source' | 'sourceFormat' | 'pack' | 'reason'>[]): IUnverifiableRemedyGroup[];
50
+ /**
51
+ * `<file>: <remedy>` for each file whose unverifiable entries need more than
52
+ * `references[]`, capped — `<file> (<ids>): <remedy>` when that file's entries
53
+ * need different fixes ({@link unverifiableRemedyGroups}).
54
+ */
55
+ export declare function unverifiableFileRemedies(verdicts: readonly Pick<IKnowledgeEntryVerdictRecord, 'entryId' | 'verdict' | 'source' | 'sourceFormat' | 'pack' | 'reason'>[]): string[];
56
+ //# sourceMappingURL=knowledge-unverifiable-remedy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-unverifiable-remedy.d.ts","sourceRoot":"","sources":["../src/knowledge-unverifiable-remedy.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAEjF,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,mFAC4C,CAAC;AAKnF,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,MAAM,CAIjF;AAWD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,GACxE,MAAM,GAAG,SAAS,CAyBpB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,GACxE,MAAM,CAER;AAiBD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,QAAQ,CAAC,EAAE,GAAG,MAAM,CAK7H;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,EACtF,KAAK,EAAE,2BAA2B,GACjC,MAAM,CAmBR;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,GAC7H,wBAAwB,EAAE,CAc5B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,IAAI,CAAC,4BAA4B,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,GAC7H,MAAM,EAAE,CAUV"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack-contributions-inventory.d.ts","sourceRoot":"","sources":["../src/pack-contributions-inventory.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAQvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAGvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,eAAO,MAAM,mCAAmC,+CACF,CAAC;AAE/C,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IAChD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,wDAAwD;IACxD,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACjD;AAED,oBAAY,YAAY;IACtB,mBAAmB,2BAA2B;IAC9C,0BAA0B,kCAAkC;IAC5D,mBAAmB,0BAA0B;IAC7C,kBAAkB,yBAAyB;IAC3C,mBAAmB,yBAAyB;IAC5C,mBAAmB,0BAA0B;IAC7C,cAAc,oBAAoB;IAClC,kBAAkB,wBAAwB;IAC1C,aAAa,mBAAmB;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS;QACzB,MAAM,EAAE,kBAAkB,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,mCAAmC,CAAC;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,SAAS;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,EAAE,OAAO,CAAC;KAC3B,EAAE,CAAC;IACJ;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE;QACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS;QAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;KACxC,EAAE,CAAC;IACJ;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS;QAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;QAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;KACtD,EAAE,CAAC;IACJ;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;CACjC;AAUD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAoC5E,CAAC;AAEH,8GAA8G;AAC9G,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAGlF;AAwTD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,qBAAqB,GAChC,2BAA2B,CAE7B;AAED;;;GAGG;AACH,wBAAsB,oCAAoC,CACxD,UAAU,EAAE,qBAAqB,GAChC,OAAO,CAAC,2BAA2B,CAAC,CAGtC;AAyVD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,2BAA2B,GAAG,MAAM,CAkD5E;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,2BAA2B,GAAG,MAAM,CA4DhF;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,2BAA2B,GAC/B,SAAS,qBAAqB,EAAE,CAElC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,2BAA2B,GAAG,IAAI,EACvC,IAAI,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;CAAE,GAChH,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBvE"}
1
+ {"version":3,"file":"pack-contributions-inventory.d.ts","sourceRoot":"","sources":["../src/pack-contributions-inventory.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@
25
25
  import { readFileSync } from 'node:fs';
26
26
  import * as nodePath from 'node:path';
27
27
  import { CONTRIBUTION_FILE_KEYS } from '@shrkcrft/plugin-api';
28
- import { collectContributionLoadFailures, collectContributionRejections, collectRegistryOutcomes, formatEntryRejection, } from "./contribution-load-failures.js";
28
+ import { collectContributionLoadFailures, collectContributionRejections, collectRegistryOutcomes, formatEntryRejection, rejectedEntrySlot, } from "./contribution-load-failures.js";
29
29
  import { ContributionKind } from "./contribution-kind.js";
30
30
  import { describePackAssetFreshness, detectPackAssetFreshness } from "./pack-asset-freshness.js";
31
31
  export { ContributionKind } from "./contribution-kind.js";
@@ -826,7 +826,9 @@ export function renderInventoryMarkdown(inv) {
826
826
  lines.push('| File | Kind | Pack | Entry | Reasons |');
827
827
  lines.push('| --- | --- | --- | --- | --- |');
828
828
  for (const r of rejections) {
829
- lines.push(`| \`${r.file}\` | ${r.kind} | ${r.packageName ?? ''} | ${r.entryId !== undefined ? `\`${r.entryId}\`` : '(no id)'} ${r.exportName ?? ''}[${r.index}] | ${r.reasons.join('; ')} |`);
829
+ // THE slot label (round 15 closing review, A5): a whole Markdown document
830
+ // printed `[-1]` here; every other surface reads `rejectedEntrySlot`.
831
+ lines.push(`| \`${r.file}\` | ${r.kind} | ${r.packageName ?? ''} | ${r.entryId !== undefined ? `\`${r.entryId}\`` : '(no id)'} (${rejectedEntrySlot(r)}) | ${r.reasons.join('; ')} |`);
830
832
  }
831
833
  }
832
834
  lines.push('');
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { existsSync, readdirSync, statSync } from 'node:fs';
14
14
  import * as nodePath from 'node:path';
15
+ import { knowledgeAnchors, knowledgeReferences } from '@shrkcrft/knowledge';
15
16
  import { getChangedFiles, getCommitSubjects, isGitRepo } from "./git-helpers.js";
16
17
  import { inspectSharkcraft } from "./sharkcraft-inspector.js";
17
18
  import { buildSymbolIndex, SymbolDeclarationKind, SymbolVisibility, } from "./symbol-index.js";
@@ -111,7 +112,7 @@ function buildCoverageIndex(entries) {
111
112
  const files = new Map();
112
113
  const symbolByFile = new Map();
113
114
  for (const entry of entries) {
114
- for (const ref of entry.references ?? []) {
115
+ for (const ref of knowledgeReferences(entry)) {
115
116
  if (ref.kind === 'symbol' && ref.symbol) {
116
117
  const symbolKey = ref.path
117
118
  ? `${ref.path}::${ref.symbol}`
@@ -130,7 +131,7 @@ function buildCoverageIndex(entries) {
130
131
  files.set(ref.path, entry.id);
131
132
  }
132
133
  }
133
- for (const anchor of entry.anchors ?? []) {
134
+ for (const anchor of knowledgeAnchors(entry)) {
134
135
  if (anchor.kind === 'symbol' && anchor.symbol) {
135
136
  const symbolKey = anchor.path
136
137
  ? `${anchor.path}::${anchor.symbol}`
@@ -0,0 +1,18 @@
1
+ import type { IReferencePackOrigin } from './i-reference-pack-origin.js';
2
+ import type { ISharkcraftInspection } from './sharkcraft-inspector.js';
3
+ /**
4
+ * The contributing pack of an asset whose provenance names it (`entrySources`
5
+ * / `boundarySources` → `{ type: 'pack', packageName }`), with its package
6
+ * directory from THE discovered pack list (`inspection.packs.validPacks`) —
7
+ * the directory the loaders read the pack's contribution files from. A name
8
+ * no valid pack carries has no directory: `undefined`.
9
+ */
10
+ export declare function packOriginByName(inspection: ISharkcraftInspection, packageName: string | undefined): IReferencePackOrigin | undefined;
11
+ /**
12
+ * The contributing pack of an asset known only by its declaring FILE (a
13
+ * pack's policy check): the valid pack whose package directory contains it —
14
+ * the innermost one, so a pack nested in another pack's `node_modules`
15
+ * resolves to itself.
16
+ */
17
+ export declare function packOriginOfFile(inspection: ISharkcraftInspection, absFile: string | undefined): IReferencePackOrigin | undefined;
18
+ //# sourceMappingURL=reference-pack-origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-pack-origin.d.ts","sourceRoot":"","sources":["../src/reference-pack-origin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOvE;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,oBAAoB,GAAG,SAAS,CAIlC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,oBAAoB,GAAG,SAAS,CAUlC"}