audit-tools 0.40.1 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/audit/cli/auditStep.d.ts +1 -1
  2. package/dist/audit/cli/conceptualDispatch.d.ts +3 -0
  3. package/dist/audit/cli/conceptualDispatch.d.ts.map +1 -1
  4. package/dist/audit/cli/conceptualDispatch.js +82 -24
  5. package/dist/audit/cli/conceptualDispatch.js.map +1 -1
  6. package/dist/audit/cli/dispatch/hostHandoff.d.ts +12 -0
  7. package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
  8. package/dist/audit/cli/dispatch/hostHandoff.js +169 -78
  9. package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
  10. package/dist/audit/cli/fanoutLanes.d.ts +47 -11
  11. package/dist/audit/cli/fanoutLanes.d.ts.map +1 -1
  12. package/dist/audit/cli/fanoutLanes.js +15 -7
  13. package/dist/audit/cli/fanoutLanes.js.map +1 -1
  14. package/dist/audit/cli/laneSubmissions.d.ts +241 -0
  15. package/dist/audit/cli/laneSubmissions.d.ts.map +1 -0
  16. package/dist/audit/cli/laneSubmissions.js +438 -0
  17. package/dist/audit/cli/laneSubmissions.js.map +1 -0
  18. package/dist/audit/cli/laneValidators.d.ts +65 -0
  19. package/dist/audit/cli/laneValidators.d.ts.map +1 -0
  20. package/dist/audit/cli/laneValidators.js +145 -0
  21. package/dist/audit/cli/laneValidators.js.map +1 -0
  22. package/dist/audit/cli/nextStepCommand.d.ts +1 -1
  23. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  24. package/dist/audit/cli/nextStepCommand.js +118 -69
  25. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  26. package/dist/audit/cli/nextStepHelpers.d.ts +73 -42
  27. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  28. package/dist/audit/cli/nextStepHelpers.js +389 -253
  29. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  30. package/dist/audit/cli/recoverSubmissionCommand.d.ts +16 -0
  31. package/dist/audit/cli/recoverSubmissionCommand.d.ts.map +1 -0
  32. package/dist/audit/cli/recoverSubmissionCommand.js +73 -0
  33. package/dist/audit/cli/recoverSubmissionCommand.js.map +1 -0
  34. package/dist/audit/cli/semanticReviewStep.d.ts +3 -0
  35. package/dist/audit/cli/semanticReviewStep.d.ts.map +1 -1
  36. package/dist/audit/cli/semanticReviewStep.js +30 -1
  37. package/dist/audit/cli/semanticReviewStep.js.map +1 -1
  38. package/dist/audit/cli/steps.d.ts +75 -2
  39. package/dist/audit/cli/steps.d.ts.map +1 -1
  40. package/dist/audit/cli/steps.js +14 -0
  41. package/dist/audit/cli/steps.js.map +1 -1
  42. package/dist/audit/cli.d.ts.map +1 -1
  43. package/dist/audit/cli.js +5 -1
  44. package/dist/audit/cli.js.map +1 -1
  45. package/dist/audit/contracts/wrapperResponse.d.ts +7 -7
  46. package/dist/audit/contracts/wrapperResponse.js +1 -1
  47. package/dist/audit/contracts/wrapperResponse.js.map +1 -1
  48. package/dist/audit/io/artifacts.d.ts +12 -1
  49. package/dist/audit/io/artifacts.d.ts.map +1 -1
  50. package/dist/audit/io/artifacts.js +28 -1
  51. package/dist/audit/io/artifacts.js.map +1 -1
  52. package/dist/audit/orchestrator/ingestionExecutors.d.ts.map +1 -1
  53. package/dist/audit/orchestrator/ingestionExecutors.js +13 -16
  54. package/dist/audit/orchestrator/ingestionExecutors.js.map +1 -1
  55. package/dist/audit/orchestrator/lensSelection.d.ts +19 -0
  56. package/dist/audit/orchestrator/lensSelection.d.ts.map +1 -1
  57. package/dist/audit/orchestrator/lensSelection.js +24 -0
  58. package/dist/audit/orchestrator/lensSelection.js.map +1 -1
  59. package/dist/audit/orchestrator/planningExecutors.d.ts +1 -12
  60. package/dist/audit/orchestrator/planningExecutors.d.ts.map +1 -1
  61. package/dist/audit/orchestrator/planningExecutors.js +14 -64
  62. package/dist/audit/orchestrator/planningExecutors.js.map +1 -1
  63. package/dist/audit/orchestrator/requeueFold.d.ts +43 -0
  64. package/dist/audit/orchestrator/requeueFold.d.ts.map +1 -0
  65. package/dist/audit/orchestrator/requeueFold.js +50 -0
  66. package/dist/audit/orchestrator/requeueFold.js.map +1 -0
  67. package/dist/audit/orchestrator/synthesisExecutors.d.ts.map +1 -1
  68. package/dist/audit/orchestrator/synthesisExecutors.js +2 -0
  69. package/dist/audit/orchestrator/synthesisExecutors.js.map +1 -1
  70. package/dist/audit/reporting/synthesis.d.ts +9 -1
  71. package/dist/audit/reporting/synthesis.d.ts.map +1 -1
  72. package/dist/audit/reporting/synthesis.js +69 -1
  73. package/dist/audit/reporting/synthesis.js.map +1 -1
  74. package/dist/audit/supervisor/operatorHandoff.d.ts +9 -2
  75. package/dist/audit/supervisor/operatorHandoff.d.ts.map +1 -1
  76. package/dist/audit/supervisor/operatorHandoff.js +17 -10
  77. package/dist/audit/supervisor/operatorHandoff.js.map +1 -1
  78. package/dist/audit/types/designAssessment.d.ts +9 -5
  79. package/dist/audit/types/designAssessment.d.ts.map +1 -1
  80. package/dist/remediate/index.d.ts.map +1 -1
  81. package/dist/remediate/index.js +48 -1
  82. package/dist/remediate/index.js.map +1 -1
  83. package/dist/remediate/steps/dispatch/hostHandoff.d.ts +38 -6
  84. package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
  85. package/dist/remediate/steps/dispatch/hostHandoff.js +87 -75
  86. package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
  87. package/dist/shared/decompose/charterClarification.d.ts +1 -1
  88. package/dist/shared/decompose/charterClarification.js +1 -1
  89. package/dist/shared/decompose/charterExtraction.js +1 -1
  90. package/dist/shared/decompose/charterExtraction.js.map +1 -1
  91. package/dist/shared/decompose/systemicChallenge.js +1 -1
  92. package/dist/shared/decompose/systemicChallenge.js.map +1 -1
  93. package/dist/shared/index.d.ts +12 -2
  94. package/dist/shared/index.d.ts.map +1 -1
  95. package/dist/shared/index.js +7 -2
  96. package/dist/shared/index.js.map +1 -1
  97. package/dist/shared/io/auditToolsPaths.d.ts +24 -4
  98. package/dist/shared/io/auditToolsPaths.d.ts.map +1 -1
  99. package/dist/shared/io/auditToolsPaths.js +29 -5
  100. package/dist/shared/io/auditToolsPaths.js.map +1 -1
  101. package/dist/shared/io/schemaVersion.d.ts +5 -4
  102. package/dist/shared/io/schemaVersion.d.ts.map +1 -1
  103. package/dist/shared/io/schemaVersion.js +17 -5
  104. package/dist/shared/io/schemaVersion.js.map +1 -1
  105. package/dist/shared/loopCorePaths.d.ts.map +1 -1
  106. package/dist/shared/loopCorePaths.js +8 -2
  107. package/dist/shared/loopCorePaths.js.map +1 -1
  108. package/dist/shared/submission/expectedSubmissions.d.ts +88 -0
  109. package/dist/shared/submission/expectedSubmissions.d.ts.map +1 -0
  110. package/dist/shared/submission/expectedSubmissions.js +84 -0
  111. package/dist/shared/submission/expectedSubmissions.js.map +1 -0
  112. package/dist/shared/submission/handRecovery.d.ts +37 -0
  113. package/dist/shared/submission/handRecovery.d.ts.map +1 -0
  114. package/dist/shared/submission/handRecovery.js +123 -0
  115. package/dist/shared/submission/handRecovery.js.map +1 -0
  116. package/dist/shared/submission/submissionClassifier.d.ts +48 -0
  117. package/dist/shared/submission/submissionClassifier.d.ts.map +1 -0
  118. package/dist/shared/submission/submissionClassifier.js +83 -0
  119. package/dist/shared/submission/submissionClassifier.js.map +1 -0
  120. package/dist/shared/submission/submissionIdentity.d.ts +49 -0
  121. package/dist/shared/submission/submissionIdentity.d.ts.map +1 -0
  122. package/dist/shared/submission/submissionIdentity.js +90 -0
  123. package/dist/shared/submission/submissionIdentity.js.map +1 -0
  124. package/dist/shared/submission/submissionLedger.d.ts +37 -0
  125. package/dist/shared/submission/submissionLedger.d.ts.map +1 -0
  126. package/dist/shared/submission/submissionLedger.js +81 -0
  127. package/dist/shared/submission/submissionLedger.js.map +1 -0
  128. package/dist/shared/types/finding.d.ts +16 -0
  129. package/dist/shared/types/finding.d.ts.map +1 -1
  130. package/dist/shared/types/finding.js +60 -0
  131. package/dist/shared/types/finding.js.map +1 -1
  132. package/docs/audit-pkg/product.md +0 -2
  133. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"auditToolsPaths.js","sourceRoot":"","sources":["../../../src/shared/io/auditToolsPaths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auditToolsPaths.js","sourceRoot":"","sources":["../../../src/shared/io/auditToolsPaths.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,11 @@
3
3
  * unmissable at the call site.
4
4
  *
5
5
  * State written by an older version of the tool is read back under the CURRENT
6
- * version's semantics. A reader that never compares the stamped
7
- * `schema_version` silently reinterprets old bytes as new-shape data. Stamping
8
- * a version on WRITE and not comparing it on READ is therefore not "versioned"
9
- * at all it is an unchecked cast wearing a version field.
6
+ * version's semantics. A reader that never compares the stamped version (spelled
7
+ * `schema_version` on artifacts, `contract_version` on contracts both are read
8
+ * here) silently reinterprets old bytes as new-shape data. Stamping a version on
9
+ * WRITE and not comparing it on READ is therefore not "versioned" at all it is
10
+ * an unchecked cast wearing a version field.
10
11
  *
11
12
  * There are exactly two correct policies, and which one applies is a property
12
13
  * of the STATE, not of the module:
@@ -1 +1 @@
1
- {"version":3,"file":"schemaVersion.d.ts","sourceRoot":"","sources":["../../../src/shared/io/schemaVersion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;aAEjC,YAAY,EAAE,MAAM;aACpB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,MAAM;gBAFd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM;CASjC;AASD;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,EAC7D,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAC3B,QAAQ,EAAE,MAAM,GACf,CAAC,GAAG,SAAS,CAGf;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAChC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,IAAI,CASN"}
1
+ {"version":3,"file":"schemaVersion.d.ts","sourceRoot":"","sources":["../../../src/shared/io/schemaVersion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;aAEjC,YAAY,EAAE,MAAM;aACpB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,MAAM;gBAFd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM;CASjC;AAoBD;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,EAC7D,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAC3B,QAAQ,EAAE,MAAM,GACf,CAAC,GAAG,SAAS,CAGf;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAChC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,IAAI,CASN"}
@@ -3,10 +3,11 @@
3
3
  * unmissable at the call site.
4
4
  *
5
5
  * State written by an older version of the tool is read back under the CURRENT
6
- * version's semantics. A reader that never compares the stamped
7
- * `schema_version` silently reinterprets old bytes as new-shape data. Stamping
8
- * a version on WRITE and not comparing it on READ is therefore not "versioned"
9
- * at all it is an unchecked cast wearing a version field.
6
+ * version's semantics. A reader that never compares the stamped version (spelled
7
+ * `schema_version` on artifacts, `contract_version` on contracts both are read
8
+ * here) silently reinterprets old bytes as new-shape data. Stamping a version on
9
+ * WRITE and not comparing it on READ is therefore not "versioned" at all it is
10
+ * an unchecked cast wearing a version field.
10
11
  *
11
12
  * There are exactly two correct policies, and which one applies is a property
12
13
  * of the STATE, not of the module:
@@ -49,8 +50,19 @@ export class SchemaVersionMismatchError extends Error {
49
50
  // Both directions accept ANY object — an unstamped payload is a defined input
50
51
  // (discard: stale; throw: mismatch), and the parameter types state that real
51
52
  // contract rather than requiring a `schema_version`-bearing shape.
53
+ //
54
+ // TWO spellings are recognized, because the repo stamps both: `schema_version`
55
+ // on artifacts and `contract_version` on contracts (the version-gate scan's own
56
+ // version-key family). That is a naming convention of the payload FAMILY, not a
57
+ // difference in policy — and a helper that knew only one spelling would return
58
+ // `undefined` for every payload of the other, i.e. discard a current file as if
59
+ // it were never written, or throw on a correctly-stamped one. A silent
60
+ // always-discard is indistinguishable from a working guard in review, so the
61
+ // helper resolves the key rather than making each call site remember it.
62
+ // `schema_version` wins when a payload carries both.
52
63
  function stampedVersion(value) {
53
- return value.schema_version;
64
+ const record = value;
65
+ return "schema_version" in record ? record.schema_version : record.contract_version;
54
66
  }
55
67
  /**
56
68
  * REGENERABLE state: return the payload only when its stamped `schema_version`
@@ -1 +1 @@
1
- {"version":3,"file":"schemaVersion.js","sourceRoot":"","sources":["../../../src/shared/io/schemaVersion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;GAIG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAEjC;IACA;IACA;IAHlB,YACkB,YAAoB,EACpB,QAAgB,EAChB,MAAc;QAE9B,KAAK,CACH,aAAa,YAAY,yBAAyB,MAAM,mBAAmB,QAAQ,KAAK;YACtF,uFAAuF;YACvF,UAAU,YAAY,iDAAiD,CAC1E,CAAC;QARc,iBAAY,GAAZ,YAAY,CAAQ;QACpB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAQ;QAO9B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,mEAAmE;AACnE,SAAS,cAAc,CAAC,KAAa;IACnC,OAAQ,KAAiC,CAAC,cAAc,CAAC;AAC3D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAA2B,EAC3B,QAAgB;IAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAC1C,KAAgC,EAChC,YAAoB,EACpB,QAAgB;IAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAClD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,0BAA0B,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,0BAA0B,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"schemaVersion.js","sourceRoot":"","sources":["../../../src/shared/io/schemaVersion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;GAIG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAEjC;IACA;IACA;IAHlB,YACkB,YAAoB,EACpB,QAAgB,EAChB,MAAc;QAE9B,KAAK,CACH,aAAa,YAAY,yBAAyB,MAAM,mBAAmB,QAAQ,KAAK;YACtF,uFAAuF;YACvF,UAAU,YAAY,iDAAiD,CAC1E,CAAC;QARc,iBAAY,GAAZ,YAAY,CAAQ;QACpB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,WAAM,GAAN,MAAM,CAAQ;QAO9B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,uEAAuE;AACvE,6EAA6E;AAC7E,yEAAyE;AACzE,qDAAqD;AACrD,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,OAAO,gBAAgB,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;AACtF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAA2B,EAC3B,QAAgB;IAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5D,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAC1C,KAAgC,EAChC,YAAoB,EACpB,QAAgB;IAEhB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAClD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,0BAA0B,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,0BAA0B,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loopCorePaths.d.ts","sourceRoot":"","sources":["../../src/shared/loopCorePaths.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAc/C,CAAC;AAOF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUpD"}
1
+ {"version":3,"file":"loopCorePaths.d.ts","sourceRoot":"","sources":["../../src/shared/loopCorePaths.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAoB/C,CAAC;AAOF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUpD"}
@@ -25,17 +25,23 @@
25
25
  export const LOOP_CORE_PATTERNS = [
26
26
  // Path-sorted (JS default string order) so the serialized order is stable and
27
27
  // the hook-parity comparison is deterministic. Groups, for the reader:
28
- // • audit orchestrator step machine + host-handoff boundary
28
+ // • audit orchestrator step machine + host-handoff boundary + gate ingest
29
+ // (the lane modules carry the bound-path rule and the lane validators —
30
+ // the audit draw of the submission core, not a helper beside it)
29
31
  // • remediate step machine + host-handoff/landing + risk/pipeline core
30
- // • shared obligation engine
32
+ // • shared obligation engine + submission core
31
33
  "src/audit/cli/dispatch.ts",
32
34
  "src/audit/cli/dispatch/",
35
+ "src/audit/cli/laneSubmissions.ts",
36
+ "src/audit/cli/laneValidators.ts",
37
+ "src/audit/cli/nextStepHelpers.ts",
33
38
  "src/audit/orchestrator/",
34
39
  "src/remediate/riskSignal.ts",
35
40
  "src/remediate/steps/contractPipeline.ts",
36
41
  "src/remediate/steps/dispatch/",
37
42
  "src/remediate/steps/nextStep.ts",
38
43
  "src/shared/engine/",
44
+ "src/shared/submission/",
39
45
  ];
40
46
  /** Normalize a repo-relative path to forward slashes, no leading "./". */
41
47
  function normalizeRepoRelPath(path) {
@@ -1 +1 @@
1
- {"version":3,"file":"loopCorePaths.js","sourceRoot":"","sources":["../../src/shared/loopCorePaths.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,kFAAkF;AAClF,oFAAoF;AACpF,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,mBAAmB;AACnB,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,iFAAiF;AACjF,kFAAkF;AAClF,iDAAiD;AACjD,EAAE;AACF,kFAAkF;AAClF,iFAAiF;AACjF,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,8EAA8E;IAC9E,uEAAuE;IACvE,8DAA8D;IAC9D,yEAAyE;IACzE,+BAA+B;IAC/B,2BAA2B;IAC3B,yBAAyB;IACzB,yBAAyB;IACzB,6BAA6B;IAC7B,yCAAyC;IACzC,+BAA+B;IAC/B,iCAAiC;IACjC,oBAAoB;CACrB,CAAC;AAEF,0EAA0E;AAC1E,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"loopCorePaths.js","sourceRoot":"","sources":["../../src/shared/loopCorePaths.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,kFAAkF;AAClF,oFAAoF;AACpF,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,mBAAmB;AACnB,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,iFAAiF;AACjF,kFAAkF;AAClF,iDAAiD;AACjD,EAAE;AACF,kFAAkF;AAClF,iFAAiF;AACjF,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,8EAA8E;IAC9E,uEAAuE;IACvE,4EAA4E;IAC5E,4EAA4E;IAC5E,qEAAqE;IACrE,yEAAyE;IACzE,iDAAiD;IACjD,2BAA2B;IAC3B,yBAAyB;IACzB,kCAAkC;IAClC,iCAAiC;IACjC,kCAAkC;IAClC,yBAAyB;IACzB,6BAA6B;IAC7B,yCAAyC;IACzC,+BAA+B;IAC/B,iCAAiC;IACjC,oBAAoB;IACpB,wBAAwB;CACzB,CAAC;AAEF,0EAA0E;AAC1E,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The expected-submission set: what a step emission OWES, stated by name.
3
+ *
4
+ * A fan-out emission used to be implicit — it wrote N lane prompts and, on the
5
+ * next turn, simply looked to see which result files happened to be there. An
6
+ * absent lane was a `continue`, so a lane that was never delivered was
7
+ * indistinguishable from a lane that was merely slow, and the run reported
8
+ * neither the shortfall nor its cause. Recording the set at emit turns that
9
+ * into "expected 3, accepted 2, lane `revealed` is missing".
10
+ *
11
+ * The set is a COHERENCE grouping, never a fit claim: a member is a
12
+ * content-coherent lane, and the diff counts lanes. Nothing here describes a
13
+ * backend, a window, or a partition sized to one — that is the host's business
14
+ * and this package does not own it.
15
+ *
16
+ * Storage-neutral by construction (one core, two draws): the core says what the
17
+ * set IS; the audit draw persists it as a file beside the submissions, the
18
+ * remediate draw carries its equivalent inside `RemediationState`.
19
+ */
20
+ import type { SubmissionIssue, SubmissionReadOutcome } from "./submissionClassifier.js";
21
+ import type { SubmissionRoots } from "./submissionIdentity.js";
22
+ export declare const EXPECTED_SET_CONTRACT_VERSION: "submission-expected-set/v1alpha1";
23
+ export interface ExpectedSubmission {
24
+ readonly submission_id: string;
25
+ /** The content-coherent lane this member answers. */
26
+ readonly lane: string;
27
+ /** Digest of the prompt the lane was given — binds the answer to the ask. */
28
+ readonly prompt_sha256: string;
29
+ /** The tool-computed bound path, repository-relative and forward-slashed. */
30
+ readonly submission_path: string;
31
+ }
32
+ export interface ExpectedSubmissionSet {
33
+ readonly contract_version: typeof EXPECTED_SET_CONTRACT_VERSION;
34
+ readonly run_id: string;
35
+ readonly entries: readonly ExpectedSubmission[];
36
+ }
37
+ /** One lane's declaration, as the emitter knows it. */
38
+ export interface ExpectedSubmissionLane {
39
+ readonly lane: string;
40
+ readonly submissionId: string;
41
+ readonly promptSha256: string;
42
+ }
43
+ /** Per-member verdict of a diff. */
44
+ export type SubmissionClassification = {
45
+ readonly status: "accepted";
46
+ readonly submission_id: string;
47
+ } | {
48
+ readonly status: "issue";
49
+ readonly submission_id: string;
50
+ readonly issue: SubmissionIssue;
51
+ };
52
+ export interface ExpectedSetDiff {
53
+ /** How many lanes were owed. */
54
+ readonly expected: number;
55
+ /** How many of them arrived. */
56
+ readonly accepted: number;
57
+ readonly members: readonly SubmissionClassification[];
58
+ }
59
+ /**
60
+ * Build the set one emission owes. Entries are ordered by `submission_id` — a
61
+ * content-derived key, never emission or filesystem order, so re-recording an
62
+ * unchanged set produces byte-identical content.
63
+ */
64
+ export declare function buildExpectedSubmissionSet(params: {
65
+ readonly runId: string;
66
+ readonly paths: SubmissionRoots;
67
+ readonly lanes: readonly ExpectedSubmissionLane[];
68
+ }): ExpectedSubmissionSet;
69
+ /**
70
+ * Merge `additional` into `base`, keyed by `submission_id`. A re-emitted lane
71
+ * re-declares the identical member (the id is deterministic), and a step that
72
+ * materializes several lane groups accumulates them into one statement of what
73
+ * is currently owed. Returns the merged set plus the ids that are NEW, so a
74
+ * caller records an `expected` event once per lane rather than on every
75
+ * re-emission.
76
+ */
77
+ export declare function mergeExpectedSets(base: ExpectedSubmissionSet | undefined, additional: ExpectedSubmissionSet): {
78
+ readonly set: ExpectedSubmissionSet;
79
+ readonly addedIds: readonly string[];
80
+ };
81
+ /** Drop members that are no longer owed (they were accepted and applied). */
82
+ export declare function withoutExpectedSubmissions(set: ExpectedSubmissionSet, submissionIds: readonly string[]): ExpectedSubmissionSet;
83
+ /**
84
+ * Diff what was owed against what is on disk. Every member is classified by its
85
+ * own id: arrived, or named with the reason it did not.
86
+ */
87
+ export declare function diffExpectedSet(set: ExpectedSubmissionSet, observed: ReadonlyMap<string, SubmissionReadOutcome>): ExpectedSetDiff;
88
+ //# sourceMappingURL=expectedSubmissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expectedSubmissions.d.ts","sourceRoot":"","sources":["../../../src/shared/submission/expectedSubmissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACtB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,eAAO,MAAM,6BAA6B,EACxC,kCAA2C,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,6BAA6B,CAAC;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACjD;AAED,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,oCAAoC;AACpC,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC/D;IACE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CACjC,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACvD;AAMD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,sBAAsB,EAAE,CAAC;CACnD,GAAG,qBAAqB,CAcxB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,GAAG,SAAS,EACvC,UAAU,EAAE,qBAAqB,GAChC;IAAE,QAAQ,CAAC,GAAG,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAkB/E;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,qBAAqB,EAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,qBAAqB,CAOvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,GACnD,eAAe,CAkBjB"}
@@ -0,0 +1,84 @@
1
+ import { classifyRead } from "./submissionClassifier.js";
2
+ import { submissionPathFor } from "./submissionIdentity.js";
3
+ export const EXPECTED_SET_CONTRACT_VERSION = "submission-expected-set/v1alpha1";
4
+ function compareIds(left, right) {
5
+ return left < right ? -1 : left > right ? 1 : 0;
6
+ }
7
+ /**
8
+ * Build the set one emission owes. Entries are ordered by `submission_id` — a
9
+ * content-derived key, never emission or filesystem order, so re-recording an
10
+ * unchanged set produces byte-identical content.
11
+ */
12
+ export function buildExpectedSubmissionSet(params) {
13
+ const entries = params.lanes.map((lane) => ({
14
+ submission_id: lane.submissionId,
15
+ lane: lane.lane,
16
+ prompt_sha256: lane.promptSha256,
17
+ submission_path: submissionPathFor(params.paths, lane.submissionId),
18
+ }));
19
+ return {
20
+ contract_version: EXPECTED_SET_CONTRACT_VERSION,
21
+ run_id: params.runId,
22
+ entries: entries.sort((left, right) => compareIds(left.submission_id, right.submission_id)),
23
+ };
24
+ }
25
+ /**
26
+ * Merge `additional` into `base`, keyed by `submission_id`. A re-emitted lane
27
+ * re-declares the identical member (the id is deterministic), and a step that
28
+ * materializes several lane groups accumulates them into one statement of what
29
+ * is currently owed. Returns the merged set plus the ids that are NEW, so a
30
+ * caller records an `expected` event once per lane rather than on every
31
+ * re-emission.
32
+ */
33
+ export function mergeExpectedSets(base, additional) {
34
+ const merged = new Map();
35
+ for (const entry of base?.entries ?? [])
36
+ merged.set(entry.submission_id, entry);
37
+ const addedIds = [];
38
+ for (const entry of additional.entries) {
39
+ if (!merged.has(entry.submission_id))
40
+ addedIds.push(entry.submission_id);
41
+ merged.set(entry.submission_id, entry);
42
+ }
43
+ return {
44
+ set: {
45
+ contract_version: EXPECTED_SET_CONTRACT_VERSION,
46
+ run_id: additional.run_id,
47
+ entries: [...merged.values()].sort((left, right) => compareIds(left.submission_id, right.submission_id)),
48
+ },
49
+ addedIds: addedIds.sort(compareIds),
50
+ };
51
+ }
52
+ /** Drop members that are no longer owed (they were accepted and applied). */
53
+ export function withoutExpectedSubmissions(set, submissionIds) {
54
+ const dropped = new Set(submissionIds);
55
+ return {
56
+ contract_version: EXPECTED_SET_CONTRACT_VERSION,
57
+ run_id: set.run_id,
58
+ entries: set.entries.filter((entry) => !dropped.has(entry.submission_id)),
59
+ };
60
+ }
61
+ /**
62
+ * Diff what was owed against what is on disk. Every member is classified by its
63
+ * own id: arrived, or named with the reason it did not.
64
+ */
65
+ export function diffExpectedSet(set, observed) {
66
+ const members = [];
67
+ let accepted = 0;
68
+ for (const entry of set.entries) {
69
+ const outcome = observed.get(entry.submission_id) ?? { kind: "missing" };
70
+ const issue = classifyRead(outcome, {
71
+ submissionId: entry.submission_id,
72
+ lane: entry.lane,
73
+ submissionPath: entry.submission_path,
74
+ });
75
+ if (issue === null) {
76
+ accepted += 1;
77
+ members.push({ status: "accepted", submission_id: entry.submission_id });
78
+ continue;
79
+ }
80
+ members.push({ status: "issue", submission_id: entry.submission_id, issue });
81
+ }
82
+ return { expected: set.entries.length, accepted, members };
83
+ }
84
+ //# sourceMappingURL=expectedSubmissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expectedSubmissions.js","sourceRoot":"","sources":["../../../src/shared/submission/expectedSubmissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { SubmissionIssue } from "./submissionClassifier.js";
2
+ export interface HandRecoveryRequest {
3
+ readonly root: string;
4
+ readonly artifactsDir: string;
5
+ readonly runId: string;
6
+ readonly submissionId: string;
7
+ /** Where the operator's corrected payload currently sits. */
8
+ readonly fromPath: string;
9
+ /**
10
+ * The lane this submission answers, when the caller knows it. Recorded on
11
+ * the ledger so the repair reads in lane vocabulary; absent, it is looked up
12
+ * from the recorded expectation and only then falls back to the raw id.
13
+ */
14
+ readonly lane?: string;
15
+ /**
16
+ * The DRAW's submission home, when it is not the artifacts dir's
17
+ * `submissions/`. Declared by the calling bin, never by the operator — the
18
+ * remediate draw binds its work-item submissions under the run directory,
19
+ * and the core stays storage-neutral rather than picking one for both.
20
+ */
21
+ readonly submissionDir?: string;
22
+ }
23
+ export type HandRecoveryOutcome = {
24
+ readonly ok: true;
25
+ readonly submission_path: string;
26
+ } | {
27
+ readonly ok: false;
28
+ readonly issue: SubmissionIssue;
29
+ };
30
+ /**
31
+ * Validate the operator's payload with the normal lane's validator and, only
32
+ * if it passes, land it at the tool-owned path. A refusal writes nothing and
33
+ * records nothing — a run must never look hand-repaired because a repair was
34
+ * ATTEMPTED.
35
+ */
36
+ export declare function recoverSubmission(request: HandRecoveryRequest, validate: (value: unknown) => SubmissionIssue | null): Promise<HandRecoveryOutcome>;
37
+ //# sourceMappingURL=handRecovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handRecovery.d.ts","sourceRoot":"","sources":["../../../src/shared/submission/handRecovery.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAWjE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAAE,CAAC;AA6B5D;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,eAAe,GAAG,IAAI,GACnD,OAAO,CAAC,mBAAmB,CAAC,CAsF9B"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Hand recovery — the ONLY place a human hand may re-land a submission.
3
+ *
4
+ * An operator sometimes has to rescue a submission a host mangled. The danger
5
+ * is that the rescue becomes a second, weaker door into the tool: a path that
6
+ * skips the schema the normal lane enforces, or that lets the operator choose
7
+ * where the payload lands. Both are closed here by construction — the caller
8
+ * hands in the NORMAL lane's validator (there is no other validator to pass),
9
+ * and the destination is derived from the submission id, so `--from` says what
10
+ * to land and never where.
11
+ *
12
+ * The third property is that the rescue is not erased: a successful recovery
13
+ * appends `recovered_by_hand`, so a run repaired by an operator stays
14
+ * distinguishable from one the host got right.
15
+ */
16
+ import { unlink } from "node:fs/promises";
17
+ import { readOptionalJsonFile, writeJsonFile } from "../io/json.js";
18
+ import { discardOnSchemaVersionMismatch } from "../io/schemaVersion.js";
19
+ import { expectedSubmissionsPath, submissionsDir, } from "../io/auditToolsPaths.js";
20
+ import { EXPECTED_SET_CONTRACT_VERSION } from "./expectedSubmissions.js";
21
+ import { readSubmissionDocument } from "./submissionClassifier.js";
22
+ import { absoluteSubmissionPath, submissionPathFor, } from "./submissionIdentity.js";
23
+ import { SUBMISSION_LEDGER_EVENT_CONTRACT_VERSION, appendSubmissionEvent, } from "./submissionLedger.js";
24
+ /**
25
+ * Resolve which lane the id belongs to from the recorded expectation, so the
26
+ * ledger entry reads in lane vocabulary. Best-effort: a draw that keeps its
27
+ * expected set somewhere other than the artifacts dir simply records the id.
28
+ *
29
+ * The set is REGENERABLE bookkeeping (rewritten at every emit), so one left by
30
+ * another release is discarded rather than read under this release's field
31
+ * semantics — a lane name is a label on the record, and a wrong one taken from
32
+ * a foreign contract is worse than the raw id this function already falls back
33
+ * to. Discarding lands on exactly that existing degrade path.
34
+ */
35
+ async function resolveLane(artifactsDir, submissionId) {
36
+ const set = discardOnSchemaVersionMismatch(await readOptionalJsonFile(expectedSubmissionsPath(artifactsDir)).catch(() => undefined), EXPECTED_SET_CONTRACT_VERSION);
37
+ return (set?.entries?.find((entry) => entry.submission_id === submissionId)?.lane ??
38
+ submissionId);
39
+ }
40
+ /**
41
+ * Validate the operator's payload with the normal lane's validator and, only
42
+ * if it passes, land it at the tool-owned path. A refusal writes nothing and
43
+ * records nothing — a run must never look hand-repaired because a repair was
44
+ * ATTEMPTED.
45
+ */
46
+ export async function recoverSubmission(request, validate) {
47
+ const paths = {
48
+ root: request.root,
49
+ submissionDir: request.submissionDir ?? submissionsDir(request.artifactsDir),
50
+ };
51
+ // BOTH destinations are resolved first, because both can refuse: the
52
+ // repo-relative form runs the containment check, and a submission directory
53
+ // that escapes the declared root throws. Computed after the write, that
54
+ // refusal arrived with the payload already landed and `recovered_by_hand`
55
+ // already appended — a rescue reported as failed that a re-run would then
56
+ // record twice. Resolved here, a refusal is what the rejection path already
57
+ // guarantees: nothing written, nothing recorded.
58
+ const landingPath = absoluteSubmissionPath(paths, request.submissionId);
59
+ const boundPath = submissionPathFor(paths, request.submissionId);
60
+ const read = await readSubmissionDocument(request.fromPath);
61
+ if (read.kind === "missing") {
62
+ return {
63
+ ok: false,
64
+ issue: {
65
+ code: "submission_missing",
66
+ message: `nothing to recover at ${request.fromPath}`,
67
+ submission_id: request.submissionId,
68
+ },
69
+ };
70
+ }
71
+ if (read.kind === "malformed") {
72
+ return {
73
+ ok: false,
74
+ issue: {
75
+ code: "submission_malformed",
76
+ message: `the payload at ${request.fromPath} is not JSON: ${read.detail}`,
77
+ submission_id: request.submissionId,
78
+ },
79
+ };
80
+ }
81
+ const issue = validate(read.value);
82
+ if (issue !== null) {
83
+ return { ok: false, issue };
84
+ }
85
+ const lane = request.lane ?? (await resolveLane(request.artifactsDir, request.submissionId));
86
+ await writeJsonFile(landingPath, read.value);
87
+ try {
88
+ await appendSubmissionEvent(request.artifactsDir, {
89
+ contract_version: SUBMISSION_LEDGER_EVENT_CONTRACT_VERSION,
90
+ run_id: request.runId,
91
+ submission_id: request.submissionId,
92
+ lane,
93
+ kind: "recovered_by_hand",
94
+ message: `re-landed by hand from ${request.fromPath}`,
95
+ recorded_at: new Date().toISOString(),
96
+ });
97
+ }
98
+ catch (error) {
99
+ // The payload is landed but the repair is unrecorded — the single state
100
+ // this verb must never leave behind, because the next `next-step` would
101
+ // consume it as a clean first-try submission and the run would read as one
102
+ // that never drifted. That is precisely the distinguishability the ledger
103
+ // exists to guarantee, so the write is rolled back and the operator keeps a
104
+ // failed rescue they can retry rather than a silent falsification.
105
+ const detail = error instanceof Error ? error.message : String(error);
106
+ try {
107
+ await unlink(landingPath);
108
+ }
109
+ catch (rollbackError) {
110
+ const rollbackDetail = rollbackError instanceof Error
111
+ ? rollbackError.message
112
+ : String(rollbackError);
113
+ throw new Error(`hand recovery for '${request.submissionId}' could not record the ledger event ` +
114
+ `(${detail}), and the landed payload could NOT be rolled back (${rollbackDetail}). ` +
115
+ `The payload IS on disk at ${boundPath} with no recovered_by_hand record — ` +
116
+ "remove it or retry the recovery before the next next-step consumes it.", { cause: error });
117
+ }
118
+ throw new Error(`hand recovery for '${request.submissionId}' could not record the ledger event: ` +
119
+ `${detail}. The payload was NOT landed (rolled back) — retry the recovery.`, { cause: error });
120
+ }
121
+ return { ok: true, submission_path: boundPath };
122
+ }
123
+ //# sourceMappingURL=handRecovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handRecovery.js","sourceRoot":"","sources":["../../../src/shared/submission/handRecovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ export declare const SUBMISSION_ISSUE_CODES: readonly ["submission_missing", "submission_malformed", "submission_contract_invalid", "submission_rejected", "duplicate_submission_id"];
2
+ export type SubmissionIssueCode = (typeof SUBMISSION_ISSUE_CODES)[number];
3
+ /**
4
+ * One classified failure. `TCode` widens for a draw that adds its own domain
5
+ * codes; the base parameterization is the shared vocabulary above.
6
+ *
7
+ * Two optional locators, because a submission is identified differently on the
8
+ * two lanes it can arrive through: an expected-set member is named by
9
+ * `submission_id` + `submission_path`, and a host work item by `work_item_id` +
10
+ * `result_path` (the field name its own persisted contract already uses).
11
+ */
12
+ export interface SubmissionIssue<TCode extends string = SubmissionIssueCode> {
13
+ readonly code: TCode;
14
+ readonly message: string;
15
+ readonly submission_id?: string;
16
+ readonly submission_path?: string;
17
+ readonly work_item_id?: string;
18
+ readonly result_path?: string;
19
+ }
20
+ /** The three-way read every gate narrows on — never a throw out of one lane. */
21
+ export type SubmissionReadOutcome = {
22
+ readonly kind: "missing";
23
+ } | {
24
+ readonly kind: "malformed";
25
+ readonly detail: string;
26
+ } | {
27
+ readonly kind: "value";
28
+ readonly value: unknown;
29
+ };
30
+ /**
31
+ * Read the bytes at a bound path and classify the outcome. A file that is not
32
+ * there and a file that will not parse are DIFFERENT answers; every other IO
33
+ * failure reads as malformed rather than escaping, so one unreadable lane can
34
+ * never destroy a sibling lane's already-consumed work.
35
+ */
36
+ export declare function readSubmissionDocument(absolutePath: string): Promise<SubmissionReadOutcome>;
37
+ /** Where a classified read came from, for the issue's message and locators. */
38
+ export interface SubmissionReadContext {
39
+ readonly submissionId: string;
40
+ readonly lane: string;
41
+ readonly submissionPath: string;
42
+ }
43
+ /**
44
+ * Turn a non-`value` read into the issue that names it, or `null` when the
45
+ * submission arrived. Lane vocabulary throughout: a member is a lane.
46
+ */
47
+ export declare function classifyRead(outcome: SubmissionReadOutcome, context: SubmissionReadContext): SubmissionIssue | null;
48
+ //# sourceMappingURL=submissionClassifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissionClassifier.d.ts","sourceRoot":"","sources":["../../../src/shared/submission/submissionClassifier.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,sBAAsB,0IAWzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe,CAAC,KAAK,SAAS,MAAM,GAAG,mBAAmB;IACzE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,gFAAgF;AAChF,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAExD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,qBAAqB,CAAC,CAqBhC;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,qBAAqB,GAC7B,eAAe,GAAG,IAAI,CAkBxB"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The ONE failure vocabulary for a host submission both orchestrators read.
3
+ *
4
+ * Before this module the two draws had drifted: remediate classified a failed
5
+ * read into a named issue code, while the audit ingest collapsed a missing
6
+ * file, unparseable bytes, a contract-invalid body and a failed conversion into
7
+ * the same bare `null` — so a host that never wrote its submission and a host
8
+ * that wrote garbage were indistinguishable to every caller. One union, two
9
+ * thin draws.
10
+ *
11
+ * The vocabulary is deliberately narrow: it names what happened to a
12
+ * SUBMISSION. Domain corroboration a single draw performs (git ancestry, write
13
+ * scope, a required test rerun) extends this union on that draw's side rather
14
+ * than pulling its vocabulary in here — see `RemediationIssueCode`.
15
+ */
16
+ import { readFile } from "node:fs/promises";
17
+ export const SUBMISSION_ISSUE_CODES = [
18
+ /** Nothing exists at the bound path. */
19
+ "submission_missing",
20
+ /** Something exists at the bound path but is not JSON. */
21
+ "submission_malformed",
22
+ /** Valid JSON that fails the lane's schema / binding contract. */
23
+ "submission_contract_invalid",
24
+ /** Well-formed and valid, but refused for a stated reason. */
25
+ "submission_rejected",
26
+ /** A second submission re-uses an identity already accepted this run. */
27
+ "duplicate_submission_id",
28
+ ];
29
+ /**
30
+ * Read the bytes at a bound path and classify the outcome. A file that is not
31
+ * there and a file that will not parse are DIFFERENT answers; every other IO
32
+ * failure reads as malformed rather than escaping, so one unreadable lane can
33
+ * never destroy a sibling lane's already-consumed work.
34
+ */
35
+ export async function readSubmissionDocument(absolutePath) {
36
+ let source;
37
+ try {
38
+ source = await readFile(absolutePath, "utf8");
39
+ }
40
+ catch (error) {
41
+ if (error.code === "ENOENT") {
42
+ return { kind: "missing" };
43
+ }
44
+ return {
45
+ kind: "malformed",
46
+ detail: error instanceof Error ? error.message : String(error),
47
+ };
48
+ }
49
+ try {
50
+ return { kind: "value", value: JSON.parse(source) };
51
+ }
52
+ catch (error) {
53
+ return {
54
+ kind: "malformed",
55
+ detail: error instanceof Error ? error.message : String(error),
56
+ };
57
+ }
58
+ }
59
+ /**
60
+ * Turn a non-`value` read into the issue that names it, or `null` when the
61
+ * submission arrived. Lane vocabulary throughout: a member is a lane.
62
+ */
63
+ export function classifyRead(outcome, context) {
64
+ if (outcome.kind === "value")
65
+ return null;
66
+ const locators = {
67
+ submission_id: context.submissionId,
68
+ submission_path: context.submissionPath,
69
+ };
70
+ if (outcome.kind === "missing") {
71
+ return {
72
+ code: "submission_missing",
73
+ message: `lane '${context.lane}' submitted nothing at its bound path`,
74
+ ...locators,
75
+ };
76
+ }
77
+ return {
78
+ code: "submission_malformed",
79
+ message: `lane '${context.lane}' submitted bytes that are not JSON: ${outcome.detail}`,
80
+ ...locators,
81
+ };
82
+ }
83
+ //# sourceMappingURL=submissionClassifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissionClassifier.js","sourceRoot":"","sources":["../../../src/shared/submission/submissionClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,wCAAwC;IACxC,oBAAoB;IACpB,0DAA0D;IAC1D,sBAAsB;IACtB,kEAAkE;IAClE,6BAA6B;IAC7B,8DAA8D;IAC9D,qBAAqB;IACrB,yEAAyE;IACzE,yBAAyB;CACjB,CAAC;AA4BX;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,YAAoB;IAEpB,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QACD,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC/D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,EAAE,CAAC;IACjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC/D,CAAC;IACJ,CAAC;AACH,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA8B,EAC9B,OAA8B;IAE9B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,QAAQ,GAAG;QACf,aAAa,EAAE,OAAO,CAAC,YAAY;QACnC,eAAe,EAAE,OAAO,CAAC,cAAc;KAC/B,CAAC;IACX,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,SAAS,OAAO,CAAC,IAAI,uCAAuC;YACrE,GAAG,QAAQ;SACZ,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,SAAS,OAAO,CAAC,IAAI,wCAAwC,OAAO,CAAC,MAAM,EAAE;QACtF,GAAG,QAAQ;KACZ,CAAC;AACJ,CAAC"}