opencode-ship 1.1.0 → 1.1.1-rc.9

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/core.js CHANGED
@@ -1,4 +1,4 @@
1
- // opencode-ship/core v1.1.0
1
+ // opencode-ship/core v1.1.1-rc.9
2
2
 
3
3
  // src/adapter.js
4
4
  import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
@@ -1086,6 +1086,12 @@ function bucketFor(check) {
1086
1086
  if (check.state === "failure") return "fail";
1087
1087
  return "pending";
1088
1088
  }
1089
+ function finalReviewGateSnapshot(manifest) {
1090
+ return {
1091
+ standards: manifest?.finalStandardsReview ?? null,
1092
+ spec: manifest?.finalSpecReview ?? null
1093
+ };
1094
+ }
1089
1095
  function gateSnapshot({ manifest, prHead, checks }) {
1090
1096
  const required = manifest.adapter?.ci?.requiredChecks ?? [];
1091
1097
  const observed = checks ?? [];
@@ -1107,6 +1113,7 @@ function gateSnapshot({ manifest, prHead, checks }) {
1107
1113
  prHead: prHead ?? null,
1108
1114
  reviewerSha: manifest?.lastReviewerSha ?? null,
1109
1115
  verifierSha: manifest?.lastVerifierSha ?? null,
1116
+ finalReviews: finalReviewGateSnapshot(manifest ?? {}),
1110
1117
  checks: observed,
1111
1118
  missingChecks: missing,
1112
1119
  failingChecks: failing,
@@ -1116,10 +1123,39 @@ function gateSnapshot({ manifest, prHead, checks }) {
1116
1123
  function checkGates({ manifest, prHead, checks, requires }) {
1117
1124
  const snap = gateSnapshot({ manifest, prHead, checks });
1118
1125
  const need = new Set(requires ?? ["review", "local-verification", "remote-ci"]);
1126
+ const hasDualFinalReview = Boolean(
1127
+ manifest?.finalStandardsReview || manifest?.finalSpecReview
1128
+ );
1119
1129
  if (need.has("review")) {
1120
- if (!manifest?.lastReviewerSha) return { ok: false, reason: "missing-review", snapshot: snap };
1121
- if (manifest.lastReviewerSha !== prHead) {
1122
- return { ok: false, reason: "head-changed-after-review", snapshot: snap };
1130
+ if (hasDualFinalReview) {
1131
+ const standards = manifest?.finalStandardsReview;
1132
+ const spec = manifest?.finalSpecReview;
1133
+ if (!standards || !standards.headSha) {
1134
+ return { ok: false, reason: "missing-final-review", axis: "standards", snapshot: snap };
1135
+ }
1136
+ if (!spec || !spec.headSha) {
1137
+ return { ok: false, reason: "missing-final-review", axis: "spec", snapshot: snap };
1138
+ }
1139
+ if (standards.headSha !== prHead) {
1140
+ return { ok: false, reason: "head-changed-after-final-review", axis: "standards", snapshot: snap };
1141
+ }
1142
+ if (spec.headSha !== prHead) {
1143
+ return { ok: false, reason: "head-changed-after-final-review", axis: "spec", snapshot: snap };
1144
+ }
1145
+ if (standards.headSha !== spec.headSha) {
1146
+ return { ok: false, reason: "final-review-head-mismatch", snapshot: snap };
1147
+ }
1148
+ if ((standards.packageHash ?? null) !== (spec.packageHash ?? null)) {
1149
+ return { ok: false, reason: "final-review-package-mismatch", snapshot: snap };
1150
+ }
1151
+ if ((standards.verdict ?? null) !== "pass" || (spec.verdict ?? null) !== "pass") {
1152
+ return { ok: false, reason: "final-review-failed", snapshot: snap };
1153
+ }
1154
+ } else {
1155
+ if (!manifest?.lastReviewerSha) return { ok: false, reason: "missing-review", snapshot: snap };
1156
+ if (manifest.lastReviewerSha !== prHead) {
1157
+ return { ok: false, reason: "head-changed-after-review", snapshot: snap };
1158
+ }
1123
1159
  }
1124
1160
  }
1125
1161
  if (need.has("local-verification")) {
@@ -1147,6 +1183,17 @@ function gateFailureEnvelope(result) {
1147
1183
  return { kind: "missing-gate", gate: "review" };
1148
1184
  case "missing-verifier":
1149
1185
  return { kind: "missing-gate", gate: "local-verification" };
1186
+ case "missing-final-review":
1187
+ return {
1188
+ kind: "missing-final-review",
1189
+ axis: result.axis
1190
+ };
1191
+ case "final-review-head-mismatch":
1192
+ return { kind: "final-review-head-mismatch" };
1193
+ case "final-review-package-mismatch":
1194
+ return { kind: "final-review-package-mismatch" };
1195
+ case "final-review-failed":
1196
+ return { kind: "final-review-failed" };
1150
1197
  case "head-changed-after-review":
1151
1198
  return {
1152
1199
  kind: "head-changed-after-review",
@@ -1159,6 +1206,12 @@ function gateFailureEnvelope(result) {
1159
1206
  headSha: result.snapshot.prHead ?? "",
1160
1207
  verifierSha: result.snapshot.verifierSha ?? ""
1161
1208
  };
1209
+ case "head-changed-after-final-review":
1210
+ return {
1211
+ kind: "head-changed-after-final-review",
1212
+ axis: result.axis,
1213
+ headSha: result.snapshot.prHead ?? ""
1214
+ };
1162
1215
  case "ci-missing":
1163
1216
  return { kind: "ci-missing", missing: result.snapshot.missingChecks };
1164
1217
  case "ci-failing":