@pactosigna/trace 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -111,7 +111,10 @@ var RiskGapCodeSchema = z.enum([
111
111
  ]);
112
112
  var RiskGapSeveritySchema = z.enum(["error", "warning"]);
113
113
  var MitigationSchema = z.object({
114
- control: z.string().min(1),
114
+ control: z.string().min(1).regex(
115
+ /^[A-Z][A-Z0-9-]+(#[\w-]+)?$/,
116
+ "control must be a document ID reference (e.g. SRS-DOC-001, SDP-001#4-2-stage-gates), not prose"
117
+ ),
115
118
  iso_category: IsoCategorySchema,
116
119
  reduces: ReducesTargetSchema
117
120
  });
@@ -901,6 +904,7 @@ function detectUnitNoVerification(documents, links, deviceSafetyClass) {
901
904
  return documents.filter((d) => {
902
905
  if (d.type !== "detailed_design") return false;
903
906
  if (!isApprovedOrEffective(d)) return false;
907
+ if (d.frontmatter.software_item_type !== "unit") return false;
904
908
  return !verifiedDocIds.has(d.id);
905
909
  }).map(
906
910
  (d) => buildGap(
@@ -913,6 +917,8 @@ function detectUnitNoVerification(documents, links, deviceSafetyClass) {
913
917
  }
914
918
  function detectRiskControlNoVerification(documents, links) {
915
919
  const verifiedDocIds = buildVerifiedDocIds(links);
920
+ const docById = new Map(documents.map((d) => [d.id, d]));
921
+ const TESTABLE_TYPES = /* @__PURE__ */ new Set(["requirement", "architecture", "detailed_design"]);
916
922
  const gaps = [];
917
923
  for (const doc of documents) {
918
924
  if (!RISK_ENTRY_TYPES.has(doc.type)) continue;
@@ -929,7 +935,21 @@ function detectRiskControlNoVerification(documents, links) {
929
935
  }
930
936
  }
931
937
  for (const control of controls) {
932
- if (!verifiedDocIds.has(extractDocumentId(control))) {
938
+ const controlDocId = extractDocumentId(control);
939
+ const controlDoc = docById.get(controlDocId);
940
+ if (!controlDoc) {
941
+ gaps.push(
942
+ buildGap(
943
+ doc,
944
+ "risk_control_no_verification",
945
+ "warning",
946
+ `Risk "${doc.title}" has mitigation control "${control}" referencing document "${controlDocId}" which does not exist in the document corpus.`
947
+ )
948
+ );
949
+ continue;
950
+ }
951
+ if (!TESTABLE_TYPES.has(controlDoc.type)) continue;
952
+ if (!verifiedDocIds.has(controlDocId)) {
933
953
  gaps.push(
934
954
  buildGap(
935
955
  doc,
@@ -4129,7 +4149,10 @@ var RiskGapCodeSchema2 = z33.enum([
4129
4149
  ]);
4130
4150
  var RiskGapSeveritySchema2 = z33.enum(["error", "warning"]);
4131
4151
  var MitigationSchema2 = z33.object({
4132
- control: z33.string().min(1),
4152
+ control: z33.string().min(1).regex(
4153
+ /^[A-Z][A-Z0-9-]+(#[\w-]+)?$/,
4154
+ "control must be a document ID reference (e.g. SRS-DOC-001, SDP-001#4-2-stage-gates), not prose"
4155
+ ),
4133
4156
  iso_category: IsoCategorySchema2,
4134
4157
  reduces: ReducesTargetSchema2
4135
4158
  });
@@ -5625,7 +5648,13 @@ function validateDocument(content, filePath) {
5625
5648
  }
5626
5649
  }
5627
5650
  }
5628
- const SKIP_UNKNOWN_SECTION_TYPES = /* @__PURE__ */ new Set(["architecture", "detailed_design"]);
5651
+ const SKIP_UNKNOWN_SECTION_TYPES = /* @__PURE__ */ new Set([
5652
+ "architecture",
5653
+ "detailed_design",
5654
+ "sop",
5655
+ "policy",
5656
+ "work_instruction"
5657
+ ]);
5629
5658
  if (docType && !SKIP_UNKNOWN_SECTION_TYPES.has(docType)) {
5630
5659
  const bodyFormat = BODY_FORMAT[docType];
5631
5660
  const knownSections = /* @__PURE__ */ new Set();
package/dist/index.js CHANGED
@@ -1077,7 +1077,10 @@ var RiskGapCodeSchema = z.enum([
1077
1077
  ]);
1078
1078
  var RiskGapSeveritySchema = z.enum(["error", "warning"]);
1079
1079
  var MitigationSchema = z.object({
1080
- control: z.string().min(1),
1080
+ control: z.string().min(1).regex(
1081
+ /^[A-Z][A-Z0-9-]+(#[\w-]+)?$/,
1082
+ "control must be a document ID reference (e.g. SRS-DOC-001, SDP-001#4-2-stage-gates), not prose"
1083
+ ),
1081
1084
  iso_category: IsoCategorySchema,
1082
1085
  reduces: ReducesTargetSchema
1083
1086
  });
@@ -1867,6 +1870,7 @@ function detectUnitNoVerification(documents, links, deviceSafetyClass) {
1867
1870
  return documents.filter((d) => {
1868
1871
  if (d.type !== "detailed_design") return false;
1869
1872
  if (!isApprovedOrEffective(d)) return false;
1873
+ if (d.frontmatter.software_item_type !== "unit") return false;
1870
1874
  return !verifiedDocIds.has(d.id);
1871
1875
  }).map(
1872
1876
  (d) => buildGap(
@@ -1879,6 +1883,8 @@ function detectUnitNoVerification(documents, links, deviceSafetyClass) {
1879
1883
  }
1880
1884
  function detectRiskControlNoVerification(documents, links) {
1881
1885
  const verifiedDocIds = buildVerifiedDocIds(links);
1886
+ const docById = new Map(documents.map((d) => [d.id, d]));
1887
+ const TESTABLE_TYPES = /* @__PURE__ */ new Set(["requirement", "architecture", "detailed_design"]);
1882
1888
  const gaps = [];
1883
1889
  for (const doc of documents) {
1884
1890
  if (!RISK_ENTRY_TYPES.has(doc.type)) continue;
@@ -1895,7 +1901,21 @@ function detectRiskControlNoVerification(documents, links) {
1895
1901
  }
1896
1902
  }
1897
1903
  for (const control of controls) {
1898
- if (!verifiedDocIds.has(extractDocumentId(control))) {
1904
+ const controlDocId = extractDocumentId(control);
1905
+ const controlDoc = docById.get(controlDocId);
1906
+ if (!controlDoc) {
1907
+ gaps.push(
1908
+ buildGap(
1909
+ doc,
1910
+ "risk_control_no_verification",
1911
+ "warning",
1912
+ `Risk "${doc.title}" has mitigation control "${control}" referencing document "${controlDocId}" which does not exist in the document corpus.`
1913
+ )
1914
+ );
1915
+ continue;
1916
+ }
1917
+ if (!TESTABLE_TYPES.has(controlDoc.type)) continue;
1918
+ if (!verifiedDocIds.has(controlDocId)) {
1899
1919
  gaps.push(
1900
1920
  buildGap(
1901
1921
  doc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactosigna/trace",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "description": "QMS traceability engine — gap detection, risk analysis, impact analysis (IEC 62304, ISO 14971)",
6
6
  "publishConfig": {