@1aboveio/skills 0.10.0

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 (397) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +90 -0
  3. package/bin/1aboveio-skills.mjs +18 -0
  4. package/package.json +28 -0
  5. package/runtime/skills/distribution/generated/recipes.json +1189 -0
  6. package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
  7. package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  8. package/skills/backend/airflow-dag-develop/LICENSE +3 -0
  9. package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
  10. package/skills/backend/app-debug/LICENSE +3 -0
  11. package/skills/backend/app-debug/SKILL.md +109 -0
  12. package/skills/backend/app-debug/references/common-errors.md +128 -0
  13. package/skills/backend/python-backend/LICENSE +3 -0
  14. package/skills/backend/python-backend/SKILL.md +326 -0
  15. package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
  16. package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
  17. package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
  18. package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
  19. package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
  20. package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
  21. package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
  22. package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
  23. package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
  24. package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
  25. package/skills/cicd-pipeline/docker/LICENSE +3 -0
  26. package/skills/cicd-pipeline/docker/SKILL.md +126 -0
  27. package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
  28. package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
  29. package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
  30. package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
  31. package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
  32. package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
  33. package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
  34. package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
  35. package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
  36. package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
  37. package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
  38. package/skills/cicd-pipeline/mergify/LICENSE +3 -0
  39. package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
  40. package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
  41. package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
  42. package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
  43. package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
  44. package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
  45. package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
  46. package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
  47. package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
  48. package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
  49. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
  50. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
  51. package/skills/cicd-pipeline/podman/LICENSE +3 -0
  52. package/skills/cicd-pipeline/podman/SKILL.md +70 -0
  53. package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
  54. package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  55. package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
  56. package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
  57. package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
  58. package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
  59. package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
  60. package/skills/engineering/e2e-test/LICENSE +3 -0
  61. package/skills/engineering/e2e-test/SKILL.md +156 -0
  62. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
  63. package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
  64. package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
  65. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  66. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
  67. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
  68. package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
  69. package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
  70. package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
  71. package/skills/engineering/e2e-test/references/debugging.md +36 -0
  72. package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
  73. package/skills/engineering/e2e-test/references/reviewing.md +39 -0
  74. package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
  75. package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
  76. package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
  77. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  78. package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
  79. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  80. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  81. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  82. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  83. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
  84. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  85. package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
  86. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
  87. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  88. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  89. package/skills/engineering/engineering-runtime/SKILL.md +10 -0
  90. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  91. package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
  92. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  93. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  94. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  95. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  96. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  97. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  98. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  99. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
  100. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
  101. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  102. package/skills/engineering/ensure-coverage/SKILL.md +136 -0
  103. package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
  104. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
  105. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
  106. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  107. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  108. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  109. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
  110. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  111. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
  112. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
  113. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
  114. package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
  115. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
  116. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
  117. package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
  118. package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
  119. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
  120. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  121. package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
  122. package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
  123. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
  124. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
  125. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
  126. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
  127. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
  128. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
  129. package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
  130. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
  131. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  132. package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
  133. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
  134. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  135. package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
  136. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  137. package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
  138. package/skills/engineering/harness-runtime/LICENSE +3 -0
  139. package/skills/engineering/harness-runtime/SKILL.md +18 -0
  140. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  141. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  142. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  143. package/skills/engineering/harness-runtime/contracts.md +15 -0
  144. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  145. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  146. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  147. package/skills/engineering/harness-runtime/index.mjs +767 -0
  148. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  149. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  150. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
  151. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  152. package/skills/engineering/implement-and-pr/LICENSE +3 -0
  153. package/skills/engineering/implement-and-pr/SKILL.md +176 -0
  154. package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
  155. package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
  156. package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
  157. package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
  158. package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
  159. package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
  160. package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
  161. package/skills/engineering/resolve-issues/LICENSE +3 -0
  162. package/skills/engineering/resolve-issues/SKILL.md +167 -0
  163. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
  164. package/skills/engineering/resolve-issues/references/breaker.md +82 -0
  165. package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
  166. package/skills/engineering/resolve-issues/references/delivery.md +108 -0
  167. package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
  168. package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
  169. package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
  170. package/skills/engineering/resolve-issues/references/finalization.md +68 -0
  171. package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
  172. package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
  173. package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
  174. package/skills/engineering/resolve-issues/references/intake.md +86 -0
  175. package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
  176. package/skills/engineering/resolve-issues/references/interference.md +87 -0
  177. package/skills/engineering/resolve-issues/references/loop.md +134 -0
  178. package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
  179. package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
  180. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
  181. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
  182. package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
  183. package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
  184. package/skills/engineering/resolve-issues/references/run-state.md +288 -0
  185. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
  186. package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
  187. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
  188. package/skills/engineering/resolve-issues/references/why.md +653 -0
  189. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
  190. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
  191. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
  192. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
  193. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
  194. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
  195. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
  196. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  197. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
  198. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
  199. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
  200. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
  201. package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
  202. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
  203. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
  204. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
  205. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
  206. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
  207. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
  208. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
  209. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
  210. package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
  211. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  212. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
  213. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
  214. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
  215. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
  216. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
  217. package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
  218. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
  219. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
  220. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
  221. package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
  222. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
  223. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
  224. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
  225. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
  226. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
  227. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
  228. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
  229. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
  230. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
  231. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
  232. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
  233. package/skills/engineering/resolve-release/LICENSE +3 -0
  234. package/skills/engineering/resolve-release/SKILL.md +112 -0
  235. package/skills/engineering/resolve-release/references/assembly.md +137 -0
  236. package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
  237. package/skills/engineering/resolve-release/references/candidate.md +167 -0
  238. package/skills/engineering/resolve-release/references/exposure.md +178 -0
  239. package/skills/engineering/resolve-release/references/handoff.md +24 -0
  240. package/skills/engineering/resolve-release/references/postmortem.md +230 -0
  241. package/skills/engineering/resolve-release/references/preflight.md +207 -0
  242. package/skills/engineering/resolve-release/references/principles.md +94 -0
  243. package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
  244. package/skills/engineering/resolve-release/references/related-skills.md +12 -0
  245. package/skills/engineering/resolve-release/references/routing.md +149 -0
  246. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
  247. package/skills/engineering/resolve-release/references/versioning.md +202 -0
  248. package/skills/engineering/resolve-release/references/why.md +53 -0
  249. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
  250. package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
  251. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
  252. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
  253. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
  254. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
  255. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
  256. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
  257. package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
  258. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
  259. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
  260. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
  261. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
  262. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
  263. package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
  264. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
  265. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
  266. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
  267. package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
  268. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
  269. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
  270. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
  271. package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
  272. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
  273. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
  274. package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
  275. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
  276. package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
  277. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
  278. package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
  279. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
  280. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
  281. package/skills/engineering/resolve-release/vendor/README.md +60 -0
  282. package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
  283. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
  284. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
  285. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
  286. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
  287. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
  288. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
  289. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
  290. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
  291. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
  292. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
  293. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
  294. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
  295. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
  296. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
  297. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
  298. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
  299. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
  300. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
  301. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
  302. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
  303. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
  304. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
  305. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
  306. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
  307. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
  308. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
  309. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
  310. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
  311. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
  312. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
  313. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
  314. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
  315. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
  316. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
  317. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
  318. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
  319. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  320. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
  321. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
  322. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
  323. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
  324. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
  325. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
  326. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
  327. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
  328. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
  329. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
  330. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
  331. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
  332. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
  333. package/skills/engineering/review-pr/LICENSE +3 -0
  334. package/skills/engineering/review-pr/SKILL.md +123 -0
  335. package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
  336. package/skills/engineering/review-pr/references/code-correctness.md +5 -0
  337. package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
  338. package/skills/engineering/review-pr/references/coordination.md +18 -0
  339. package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
  340. package/skills/engineering/review-pr/references/finding-themes.md +7 -0
  341. package/skills/engineering/review-pr/references/github-posting.md +98 -0
  342. package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
  343. package/skills/engineering/review-pr/references/incremental-output.md +16 -0
  344. package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
  345. package/skills/engineering/review-pr/references/output-format.md +99 -0
  346. package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
  347. package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
  348. package/skills/engineering/review-pr/references/re-review.md +18 -0
  349. package/skills/engineering/review-pr/references/review-method.md +199 -0
  350. package/skills/engineering/review-pr/references/review-mode.md +30 -0
  351. package/skills/engineering/review-pr/references/review-posture.md +53 -0
  352. package/skills/engineering/review-pr/references/round1-depth.md +62 -0
  353. package/skills/engineering/review-pr/references/scripts.md +17 -0
  354. package/skills/engineering/review-pr/references/workflow.md +16 -0
  355. package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
  356. package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
  357. package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
  358. package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
  359. package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
  360. package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
  361. package/skills/engineering/smoke/LICENSE +3 -0
  362. package/skills/engineering/smoke/SKILL.md +131 -0
  363. package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
  364. package/skills/engineering/smoke/references/manifest.md +192 -0
  365. package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
  366. package/skills/fullstack/better-auth/LICENSE +3 -0
  367. package/skills/fullstack/better-auth/SKILL.md +601 -0
  368. package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
  369. package/skills/fullstack/monorepo/LICENSE +3 -0
  370. package/skills/fullstack/monorepo/SKILL.md +465 -0
  371. package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
  372. package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
  373. package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
  374. package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
  375. package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
  376. package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
  377. package/skills/fullstack/prisma-setup/LICENSE +3 -0
  378. package/skills/fullstack/prisma-setup/SKILL.md +180 -0
  379. package/skills/fullstack/prisma-setup/nextjs.md +258 -0
  380. package/skills/fullstack/prisma-setup/turborepo.md +301 -0
  381. package/skills/fullstack/shadcn/LICENSE +3 -0
  382. package/skills/fullstack/shadcn/SKILL.md +119 -0
  383. package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
  384. package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
  385. package/skills/fullstack/shadcn/cli.md +411 -0
  386. package/skills/fullstack/shadcn/customization.md +224 -0
  387. package/skills/fullstack/shadcn/evals/evals.json +90 -0
  388. package/skills/fullstack/shadcn/mcp.md +101 -0
  389. package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
  390. package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
  391. package/skills/fullstack/shadcn/rules/composition.md +195 -0
  392. package/skills/fullstack/shadcn/rules/data-table.md +201 -0
  393. package/skills/fullstack/shadcn/rules/forms.md +255 -0
  394. package/skills/fullstack/shadcn/rules/icons.md +103 -0
  395. package/skills/fullstack/shadcn/rules/styling.md +167 -0
  396. package/skills/fullstack/zod-v4/LICENSE +3 -0
  397. package/skills/fullstack/zod-v4/SKILL.md +287 -0
@@ -0,0 +1,707 @@
1
+ ---
2
+ name: cloud-build
3
+ description: "Build or debug Cloud Build pipelines for Cloud Run: cloudbuild.yaml, triggers, Artifact Registry, Docker builds, migration jobs, deploy steps, secrets, VPC, notifications. Not for staged multi-environment promotion (cloud-deploy)."
4
+ ---
5
+
6
+ # Cloud Build Direct Deploy to Cloud Run
7
+
8
+ Simpler alternative to Cloud Deploy for single-container services without staged promotion or verification gates.
9
+
10
+ ## Related Skills
11
+
12
+ - [google-cloud](../google-cloud/SKILL.md) - Centralized GCP operations
13
+ - [IAM patterns](../google-cloud/references/iam.md) - Service accounts, roles, IAP, token minting
14
+ - [VPC configuration](../google-cloud/references/vpc.md) - Networks, subnets, Cloud Run with VPC
15
+ - [Secrets Manager](../google-cloud/references/secrets.md) - Secret setup, access, Cloud Run integration
16
+ - [cloud-deploy](../cloud-deploy/SKILL.md) - Complex deployments with Cloud Deploy + Skaffold
17
+ - [cloud-debug](../cloud-debug/SKILL.md) - Debugging Cloud Build/Deploy failures
18
+
19
+ ## When to Use
20
+
21
+ - Single container deployments
22
+ - Services handling own migrations (e.g., Airflow standalone)
23
+ - No need for staged promotion with verification
24
+
25
+ For complex deployments with migrations and verification, use `cloud-deploy` skill.
26
+
27
+ ## Architecture
28
+
29
+ **GitFlow (default)** — a long-lived integration branch plus a production branch:
30
+
31
+ ```
32
+ dev push ────→ Cloud Build ────→ Cloud Run (dev)
33
+ PR to master ─→ Cloud Build ────→ Cloud Run (staging)
34
+ v*-rc.* tag ──→ Cloud Build ────→ Cloud Run (prod, 0% traffic candidate)
35
+ ```
36
+
37
+ **GitHub Flow** — one long-lived branch; see [GitHub Flow variant](#github-flow-variant) for the trigger set and what changes:
38
+
39
+ ```
40
+ PR opened ─────→ Cloud Build ────→ build + test only, no deploy
41
+ merge to main ─→ Cloud Build ────→ Cloud Run (staging, 100% traffic)
42
+ v*-rc.* tag ───→ Cloud Build ────→ Cloud Run (prod, 0% traffic candidate)
43
+ ```
44
+
45
+ **The prod fork is identical in both.** It keys off the rc tag, not off a branch — which is the practical payoff of triggering production on a tag: the release path stops caring what the branching model is.
46
+
47
+ ## Environment Configuration
48
+
49
+ ### Triggers
50
+
51
+ - **Dev**: `dev` branch push — active development
52
+ - **Staging**: PR to `master` — PR validation
53
+ - **Prod**: `v*-rc.*` tag push — builds a candidate revision at 0% traffic; the release lane verifies it and shifts traffic
54
+
55
+ ### Database
56
+
57
+ - **Dev**: Dedicated dev DB — migrations skipped for faster iteration
58
+ - **Staging**: Dedicated staging DB — runs migrations + test seeds
59
+ - **Prod**: Production DB — runs migrations + prod seeds
60
+
61
+ Dev skips migrations/seeds during build for speed. Cloud Run Jobs are still configured so they can be triggered manually when needed.
62
+
63
+ **For Cloud SQL connection patterns, see [google-cloud skill VPC reference](../google-cloud/references/vpc.md) — Cloud SQL Connection Standard.**
64
+
65
+ ### Build Steps
66
+
67
+ All environments run: **setup env → build → update job → deploy → test**
68
+
69
+ Staging + Prod additionally run: **migrate → seed**
70
+
71
+ Step descriptions:
72
+ - **setup env**: Initialize environment-specific variables (VPC, secrets)
73
+ - **build**: Build and push Docker image to Artifact Registry
74
+ - **update job**: Configure Cloud Run Jobs (for migrate/seed) — does not execute them
75
+ - **migrate**: Execute database migration job
76
+ - **deploy**: Deploy to Cloud Run service
77
+ - **seed**: Execute database seed job
78
+ - **test**: Run integration tests against deployed service
79
+
80
+ ### Migration Best Practice: Skip When Schema Inputs Are Unchanged
81
+
82
+ If migrations run through Cloud Build, prefer a single combined **migrate-if-needed** step rather than separate "check", "update job", and "execute job" steps. The step should:
83
+
84
+ 1. Hash only the files that define database shape
85
+ 2. Compare that hash to the last applied hash stored outside the build workspace
86
+ 3. Skip migration image build, job update, and job execution when the hash is unchanged
87
+
88
+ Use a persistent marker such as a GCS object:
89
+
90
+ ```text
91
+ gs://$PROJECT_ID_cloudbuild/migrate-markers/{service}-${_ENV}.digest
92
+ ```
93
+
94
+ Why:
95
+ - Avoids slow no-op migration runs on every deploy
96
+ - Works with Cloud Build's shallow clone and source mirror limitations
97
+ - Keeps migration execution tied to actual schema changes rather than every app change
98
+
99
+ Do not hash the whole repo. Hash only migration-relevant inputs for the ORM in use.
100
+
101
+ Practical rules:
102
+ - Do **not** gate migrations with `git diff HEAD^ HEAD`. Merge commits, shallow clones, and repository-event checkouts can compare against the wrong parent and produce false positives.
103
+ - The **first** build after adopting digest-based gating should usually run migrations once, because there is no previous marker yet. That is expected marker seeding, not a failure of the gate.
104
+ - After a successful migration job, write the new digest marker even if the job only reports "database schema is up to date". Otherwise every later build will look like a first run.
105
+ - Prefer `gcr.io/google.com/cloudsdktool/cloud-sdk:slim` and keep the skip path to a single always-started SDK step. A split "decide" + "maybe-run" pattern is usually slower for the common unchanged-schema case.
106
+ - If Cloud Build UI still shows a migration step, check whether it truly executed a Cloud Run Job or only started a step that exited early. Those are different.
107
+
108
+ ### Prisma Example
109
+
110
+ For Prisma, prefer hashing:
111
+ - `prisma/schema.prisma`
112
+ - `prisma/migrations/**`
113
+
114
+ If the digest is unchanged, skip all migration job work. A pragmatic pattern is a single slim SDK step that:
115
+ - computes the digest
116
+ - compares it with the stored marker
117
+ - exits immediately when unchanged
118
+ - otherwise deploys and executes the migration job
119
+ - writes the new digest back to GCS after success
120
+
121
+ Example:
122
+
123
+ ```yaml
124
+ - name: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
125
+ id: migrate-if-needed
126
+ entrypoint: bash
127
+ args:
128
+ - -ceu
129
+ - |
130
+ digest_file="/workspace/migration-digest.txt"
131
+ marker="gs://${PROJECT_ID}_cloudbuild/migrate-markers/{service}-${_ENV}.digest"
132
+ current_digest="$$( \
133
+ { \
134
+ printf '%s\0' prisma/schema.prisma; \
135
+ find prisma/migrations -type f -print0; \
136
+ } | sort -z | xargs -0 sha256sum | sha256sum | cut -d' ' -f1 \
137
+ )"
138
+ previous_digest="$$(gcloud storage cat "$${marker}" 2>/dev/null || true)"
139
+
140
+ if [[ -n "$${previous_digest}" && "$${previous_digest}" == "$${current_digest}" ]]; then
141
+ echo "Prisma schema unchanged; skipping migrate job."
142
+ exit 0
143
+ fi
144
+
145
+ printf '%s' "$${current_digest}" > "$${digest_file}"
146
+
147
+ migration_script="$$(cat <<'EOF'
148
+ status_output=$$(pnpm prisma migrate status 2>&1 || true)
149
+ echo "$${status_output}"
150
+ if grep -qi "Database schema is up to date" <<<"$${status_output}"; then
151
+ echo "Database already up to date"
152
+ exit 0
153
+ fi
154
+ if grep -qi "Following migration" <<<"$${status_output}" || grep -qi "have not yet been applied" <<<"$${status_output}"; then
155
+ pnpm prisma migrate deploy
156
+ exit 0
157
+ fi
158
+ echo "Unexpected prisma migrate status output"
159
+ exit 1
160
+ EOF
161
+ )"
162
+
163
+ gcloud run jobs deploy {service}-${_ENV}-migrate \
164
+ --image=$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}:$COMMIT_SHA \
165
+ --region=$LOCATION \
166
+ --command=bash \
167
+ --args=-ceu \
168
+ --args="$${migration_script}"
169
+
170
+ gcloud run jobs execute {service}-${_ENV}-migrate --region=$LOCATION --wait --format=none
171
+ gcloud storage cp "$${digest_file}" "$${marker}"
172
+ ```
173
+
174
+ ### Tortoise ORM + Aerich Example
175
+
176
+ For Tortoise ORM, there is no single canonical schema file like Prisma. Hash:
177
+ - `aerich.ini` or equivalent Aerich config
178
+ - `migrations/**` or `aerich/**` migration files
179
+ - the model packages that define Tortoise tables
180
+
181
+ The same preference applies here: a combined digest-check + migrate-if-needed step is usually better than separate decision and execution steps unless the pipeline has a strong reason to split them.
182
+
183
+ Example:
184
+
185
+ ```yaml
186
+ - name: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
187
+ id: check-migrations
188
+ entrypoint: bash
189
+ args:
190
+ - -ceu
191
+ - |
192
+ marker="gs://${PROJECT_ID}_cloudbuild/migrate-markers/{service}-${_ENV}.digest"
193
+ current_digest="$$( \
194
+ { \
195
+ printf '%s\0' aerich.ini; \
196
+ find migrations -type f -print0 2>/dev/null || true; \
197
+ find app/models -type f \\( -name '*.py' -o -name '*.sql' \\) -print0; \
198
+ } \
199
+ | sort -z \
200
+ | xargs -0 sha256sum \
201
+ | sha256sum \
202
+ | cut -d' ' -f1)"
203
+ previous_digest="$$(gcloud storage cat "$${marker}" 2>/dev/null || true)"
204
+
205
+ if [[ -n "$${previous_digest}" && "$${previous_digest}" == "$${current_digest}" ]]; then
206
+ echo "Aerich inputs unchanged; skipping migrate job."
207
+ exit 0
208
+ fi
209
+
210
+ touch /workspace/.migrate-needed
211
+ printf '%s' "$${current_digest}" > /workspace/.new-migration-digest
212
+ ```
213
+
214
+ For Aerich, keep the migration command deterministic inside the Cloud Run Job:
215
+
216
+ ```bash
217
+ aerich upgrade
218
+ ```
219
+
220
+ If you generate migrations in CI, treat that as a separate workflow with tighter review controls. For normal deploys, prefer committing generated migration files and only applying them in Cloud Build.
221
+
222
+ ## cloudbuild.yaml
223
+
224
+ ```yaml
225
+ substitutions:
226
+ _ENV: dev
227
+ _MIN_INSTANCES: '0'
228
+ _DATABASE_URL_SECRET: {service}-database-url-${_ENV}
229
+ _SECRET_KEY: {service}-secret-key
230
+ # VPC configuration per environment
231
+ _VPC_NETWORK_DEV: 'default'
232
+ _VPC_SUBNET_DEV: 'default'
233
+ _VPC_NETWORK_STAGING: 'default'
234
+ _VPC_SUBNET_STAGING: 'default'
235
+ _VPC_NETWORK_PROD: 'prod'
236
+ _VPC_SUBNET_PROD: 'prod'
237
+
238
+ steps:
239
+ # Initialize environment-specific variables
240
+ - name: 'bash'
241
+ env:
242
+ - '_ENV=${_ENV}'
243
+ - '_VPC_NETWORK_DEV=${_VPC_NETWORK_DEV}'
244
+ - '_VPC_NETWORK_STAGING=${_VPC_NETWORK_STAGING}'
245
+ - '_VPC_NETWORK_PROD=${_VPC_NETWORK_PROD}'
246
+ - '_VPC_SUBNET_DEV=${_VPC_SUBNET_DEV}'
247
+ - '_VPC_SUBNET_STAGING=${_VPC_SUBNET_STAGING}'
248
+ - '_VPC_SUBNET_PROD=${_VPC_SUBNET_PROD}'
249
+ args:
250
+ - '-c'
251
+ - |
252
+ ENV_UPPER=$$(echo "$$_ENV" | tr '[:lower:]' '[:upper:]')
253
+ NETWORK_VAR="_VPC_NETWORK_$$ENV_UPPER"
254
+ SUBNET_VAR="_VPC_SUBNET_$$ENV_UPPER"
255
+ VPC_NETWORK="$${!NETWORK_VAR}"
256
+ VPC_SUBNET="$${!SUBNET_VAR}"
257
+ echo "VPC_NETWORK=$$VPC_NETWORK" > /workspace/env.sh
258
+ echo "VPC_SUBNET=$$VPC_SUBNET" >> /workspace/env.sh
259
+ echo "Initialized: VPC network=$$VPC_NETWORK, subnet=$$VPC_SUBNET"
260
+
261
+ # Build the Docker image
262
+ - name: 'gcr.io/cloud-builders/docker'
263
+ args:
264
+ - 'build'
265
+ - '-t'
266
+ - '$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}:$COMMIT_SHA'
267
+ - '-t'
268
+ - '$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}:latest'
269
+ - '.'
270
+
271
+ # Push to Artifact Registry
272
+ - name: 'gcr.io/cloud-builders/docker'
273
+ args:
274
+ - 'push'
275
+ - '--all-tags'
276
+ - '$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}'
277
+
278
+ # Deploy to Cloud Run
279
+ - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
280
+ entrypoint: bash
281
+ args:
282
+ - '-c'
283
+ - |
284
+ source /workspace/env.sh
285
+ gcloud run deploy {service}-${_ENV} \
286
+ --image=$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}:$COMMIT_SHA \
287
+ --region=$LOCATION \
288
+ --platform=managed \
289
+ --min-instances=${_MIN_INSTANCES} \
290
+ --max-instances=1 \
291
+ --memory=2Gi \
292
+ --cpu=1 \
293
+ --port=8080 \
294
+ --cpu-boost \
295
+ --no-cpu-throttling \
296
+ --timeout=300 \
297
+ --set-secrets=DATABASE_URL=${_DATABASE_URL_SECRET}:latest,SECRET_KEY=${_SECRET_KEY}:latest \
298
+ --network=$${VPC_NETWORK} \
299
+ --subnet=$${VPC_SUBNET}
300
+
301
+ options:
302
+ logging: CLOUD_LOGGING_ONLY
303
+ machineType: E2_HIGHCPU_8
304
+ ```
305
+
306
+ ## Infrastructure Configuration
307
+
308
+ For IAM, VPC, Secrets, and IAP patterns, see the [google-cloud](../google-cloud/SKILL.md) skill:
309
+
310
+ - **VPC**: [google-cloud/vpc.md](../google-cloud/references/vpc.md) - Network/subnet setup for Cloud Run
311
+ - **Secrets**: [google-cloud/secrets.md](../google-cloud/references/secrets.md) - Secret Manager setup and Cloud Run integration
312
+ - **IAM/IAP**: [google-cloud/iam.md](../google-cloud/references/iam.md) - Service accounts, roles, IAP access, token minting
313
+
314
+ ### Build Triggers
315
+
316
+ ```bash
317
+ # Dev
318
+ gcloud builds triggers create github --name="{service}-dev" \
319
+ --repo-name="REPO" --repo-owner="OWNER" --branch-pattern="^dev$" \
320
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=dev,_MIN_INSTANCES=0"
321
+
322
+ # Staging
323
+ gcloud builds triggers create github --name="{service}-staging" \
324
+ --repo-name="REPO" --repo-owner="OWNER" --pull-request-pattern="^master$" \
325
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=staging,_MIN_INSTANCES=0"
326
+
327
+ # Prod — fires on release-candidate tags minted by the release lane, not on branch push
328
+ gcloud builds triggers create github --name="{service}-prod" \
329
+ --repo-name="REPO" --repo-owner="OWNER" --tag-pattern="^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$" \
330
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=prod,_MIN_INSTANCES=1"
331
+ ```
332
+
333
+ **Footgun: the prod tag pattern must not match the final `v<version>` tag.** The release lane mints `v1.4.0-rc.1` to produce a candidate, and then — after the candidate verifies ALIVE and traffic is at 100% — mints `v1.4.0`. A loose pattern like `^v.*$` matches both, so the final tag fires a second production build that rebuilds and redeploys an already-live release at 0% traffic for no reason. Anchor the `-rc.<n>` suffix, as above, and check the pattern against both tag shapes before creating the trigger.
334
+
335
+ Dev and staging triggers are unchanged: `dev` still builds on branch push, staging still builds on PRs to `master`.
336
+
337
+ ### GitHub Flow variant
338
+
339
+ One long-lived branch (`main`), short-lived feature branches, no `dev`. Three triggers, the same `cloudbuild.yaml`:
340
+
341
+ ```bash
342
+ # PR — build and test only. No deploy: a PR is not an environment.
343
+ gcloud builds triggers create github --name="{service}-pr" \
344
+ --repo-name="REPO" --repo-owner="OWNER" --pull-request-pattern="^main$" \
345
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=ci"
346
+
347
+ # Staging — every merge to main deploys at 100% and records the SHA-keyed verdict
348
+ gcloud builds triggers create github --name="{service}-staging" \
349
+ --repo-name="REPO" --repo-owner="OWNER" --branch-pattern="^main$" \
350
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=staging,_MIN_INSTANCES=0"
351
+
352
+ # Prod — byte-identical to the GitFlow prod trigger
353
+ gcloud builds triggers create github --name="{service}-prod" \
354
+ --repo-name="REPO" --repo-owner="OWNER" --tag-pattern="^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$" \
355
+ --build-config="cloudbuild.yaml" --substitutions="_ENV=prod,_MIN_INSTANCES=1"
356
+ ```
357
+
358
+ **`_ENV=staging` takes the dev fork's behavior, not the GitFlow staging behavior.** It deploys at 100% and runs the smoke as a **non-blocking recorder** publishing a `dev-smoke`-style commit status — because under GitHub Flow this environment *is* the integration environment. Reuse the [dev fork step](#integration-dev-deploy-100-record-the-verdict-never-fail-the-build) verbatim, matching on `staging` instead of `dev`. Everything else — build, migrations, seeds, the prod fork — is unchanged.
359
+
360
+ **What the recorded verdict means here is weaker, and that is the one thing to understand.** In GitFlow, the promoted SHA and the validated SHA are the same commit: `dev` is validated, and the promotion fast-forwards it into `main`. Under GitHub Flow there is only one branch, so the release lane cuts `release/<version>` at a validated SHA, merges it back into `main`, and the **shipped SHA is that merge commit** — which also carries anything else that landed on `main` meanwhile. Those commits never earned a verdict.
361
+
362
+ So under GitHub Flow the SHA-keyed staging verdict is a **pre-filter, not the release gate**. The gate is the prod candidate at 0% traffic, which validates the *exact shipped SHA* on real infrastructure before any user reaches it. That is sound precisely because of the 0%-candidate design — under a deploy-then-smoke pipeline the same topology would ship unvalidated commits straight to users.
363
+
364
+ **Order is forced: merge first, then tag.** `version.mjs tag` refuses a SHA that is not an ancestor of the production branch, so the release branch cannot be rc-tagged before it lands on `main`. Merge the release PR, then mint the rc on the merge commit. Release-lane sequencing: `resolve-release` step 1.
365
+
366
+ ## Build Notifications
367
+
368
+ Build notifications can be routed via Cloud Build Pub/Sub topic to external services (Slack, Discord, webhooks). Configure the notification sink at the project level.
369
+
370
+ **Critical:** Do NOT set `options.pubsubTopic` in `cloudbuild.yaml` — it overrides the built-in topic and can break your notification pipeline.
371
+
372
+ ## Post-deploy smoke gate (Cloud Run)
373
+
374
+ A "deploy SUCCESS" only proves the revision is `Ready` — not that the real built image, with real secrets/env, actually works. The bug class this catches lives *only* in the deployed artifact (a secret with a trailing newline, an env substitution like `_ENV` stripped at deploy, a file not `COPY`ed into the image, a `redirect_uri` from the container bind origin, traffic pinned to a stale revision). No PR-lane or `next dev` test sees it. Run a curated **smoke gate** against the deployed revision — the canonical doctrine, the manifest format, and the `--target` semantics live in the **`smoke` skill** (`skills/engineering/smoke`); this section is only the Cloud Run/Cloud Build *placement*.
375
+
376
+ **The pipeline owns artifacts. The release lane owns exposure.** That seam decides what each fork of the build is allowed to do. The build's job ends at producing something verifiable — an image, a revision, a verdict. Deciding that users should see it is the release lane's job, not a build step's.
377
+
378
+ **Where it blocks depends on who the environment serves.** The blocking placement protects *users*, so it belongs on the **production** path. An integration environment (`dev`) has no users to protect — there, a blocking smoke only converts small bugs and infra flakes into failed builds and full rebuild cycles. So the same seam cuts differently per fork, and each fork's contract output is different:
379
+
380
+ - **`dev` output: a SHA-keyed verdict.** Deploy at 100%, smoke as a non-blocking recorder, publish the verdict as a commit status. Nothing is gated here; the verdict blocks later, at the dev→main promotion, where the release lane pins its candidate to a validated SHA (`resolve-release` principle 11).
381
+ - **prod output: a 0%-traffic candidate revision.** Deploy with `--no-traffic`, surface the revision name and candidate URL, and **stop**. The build does not smoke it and does not shift traffic — `resolve-release` does both.
382
+
383
+ **Why the prod gate moved out of the build.** The gate did not disappear; it moved to where it can be operated:
384
+
385
+ - **Validation becomes retryable without a rebuild.** A red smoke inside the build means re-triggering the whole build to retry a config or secret fix. Against an already-deployed candidate URL it is a re-run measured in seconds.
386
+ - **The traffic shift sits behind a human authorization point.** A build step promoting traffic is an automatic decision made by whoever pushed a tag. In the release lane it is an explicit act with a person and a version behind it.
387
+ - **The pipeline can change without the release doctrine changing.** `cloudbuild.yaml` is free to change builders, regions, or step order; the release contract is still "give me a candidate at 0%."
388
+
389
+ ### Production: build a candidate, stop before traffic
390
+
391
+ The prod fork's entire contract is three facts:
392
+
393
+ - **In:** a tag push matching `v*-rc.*` — release-candidate tags, minted by the release lane.
394
+ - **Out:** a candidate revision deployed at **0% traffic**, with its revision name and candidate URL discoverable by the caller.
395
+ - **Never:** it does not validate, and it does not shift traffic.
396
+
397
+ ```
398
+ tag v*-rc.* → build → deploy --no-traffic --tag candidate → publish {revision, url} → END
399
+
400
+ resolve-release: smoke --profile prod-preview (read-only) ──┤
401
+ ALIVE → update-traffic 100%, tag v<version>
402
+ DEAD → delete the 0% revision (traffic never moved)
403
+ ```
404
+
405
+ Because traffic never moved, a DEAD verdict is not a rollback and has no user impact — the candidate revision is simply deleted.
406
+
407
+ ```yaml
408
+ # Prod fork: deploy the candidate at 0% traffic, then stop.
409
+ - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
410
+ id: deploy-candidate
411
+ entrypoint: bash
412
+ args:
413
+ - '-c'
414
+ - |
415
+ [[ "${_ENV}" == "prod" ]] || exit 0
416
+ source /workspace/env.sh
417
+ gcloud run deploy {service}-${_ENV} \
418
+ --image=$LOCATION-docker.pkg.dev/$PROJECT_ID/{repo}/{service}:$COMMIT_SHA \
419
+ --region=$LOCATION \
420
+ --platform=managed \
421
+ --min-instances=${_MIN_INSTANCES} \
422
+ --max-instances=1 \
423
+ --memory=2Gi \
424
+ --cpu=1 \
425
+ --port=8080 \
426
+ --cpu-boost \
427
+ --no-cpu-throttling \
428
+ --timeout=300 \
429
+ --set-secrets=DATABASE_URL=${_DATABASE_URL_SECRET}:latest,SECRET_KEY=${_SECRET_KEY}:latest \
430
+ --network=$${VPC_NETWORK} \
431
+ --subnet=$${VPC_SUBNET} \
432
+ --no-traffic \
433
+ --tag=candidate
434
+
435
+ # Publish the candidate coordinates for the release lane. Build ends here.
436
+ - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
437
+ id: publish-candidate
438
+ entrypoint: bash
439
+ args:
440
+ - '-c'
441
+ - |
442
+ [[ "${_ENV}" == "prod" ]] || exit 0
443
+ svc="$$(gcloud run services describe {service}-${_ENV} --region=$LOCATION --format=json)"
444
+
445
+ # Read BOTH coordinates off the same `candidate` traffic entry. Do not reach for
446
+ # .status.latestCreatedRevisionName: "latest" and "the one I just tagged" are the
447
+ # same thing only when nothing else is deploying, and the case where they diverge
448
+ # is exactly the case you need this to be right — a concurrent build would hand the
449
+ # release lane one revision's name beside another revision's URL.
450
+ revision="$$(jq -r '.status.traffic[] | select(.tag=="candidate") | .revisionName' <<<"$${svc}")"
451
+ url="$$(jq -r '.status.traffic[] | select(.tag=="candidate") | .url' <<<"$${svc}")"
452
+ [[ -n "$${url}" && "$${url}" != "null" ]] || { echo "no candidate tag URL"; exit 1; }
453
+ [[ -n "$${revision}" && "$${revision}" != "null" ]] || { echo "no candidate revision"; exit 1; }
454
+
455
+ # Prove the tagged revision runs THIS build's image before publishing it as the
456
+ # candidate. Without this, a failed deploy that left the previous candidate in place
457
+ # publishes stale coordinates the release lane would validate and promote.
458
+ running="$$(gcloud run revisions describe "$${revision}" --region=$LOCATION \
459
+ --format='value(spec.containers[0].image)')"
460
+ [[ "$${running}" == *":$COMMIT_SHA" ]] || {
461
+ echo "candidate $${revision} runs $${running}, not $COMMIT_SHA"; exit 1; }
462
+
463
+ jq -n --arg r "$${revision}" --arg u "$${url}" --arg s "$COMMIT_SHA" --arg t "$TAG_NAME" \
464
+ '{revision:$$r, candidate_url:$$u, commit_sha:$$s, rc_tag:$$t}' \
465
+ > /workspace/candidate.json
466
+ gcloud storage cp /workspace/candidate.json \
467
+ "gs://$${PROJECT_ID}_cloudbuild/candidates/{service}-$TAG_NAME.json"
468
+ cat /workspace/candidate.json
469
+ ```
470
+
471
+ **The `candidate` tag moves; the revision name does not.** Each prod build re-points `--tag=candidate` at its own new revision, so the tag URL always means "the newest candidate," not "the candidate I built." That is why the published JSON carries the **revision name** and why the release lane deletes a failed candidate **by name** — and it is a second reason `resolve-release` principle 7 serializes releases: two candidates in flight would leave the earlier one addressable only by revision, its URL silently repointed at the later build.
472
+
473
+ **Surface the coordinates as a GCS object keyed by the RC tag, not as log output.** The release lane already knows the tag it pushed, so it can fetch `candidates/{service}-<rc-tag>.json` without knowing the build ID — no build lookup, no log scraping, and the object outlives log retention. The `cat` at the end is a convenience for humans reading the build, not the interface. Derive the URL from `gcloud run services describe` rather than from `gcloud run deploy` output: the tag URL lives in `status.traffic[]`, and describing the service after the deploy also proves the tag actually landed (the guard above fails the build if it did not).
474
+
475
+ **Verification-time policy belongs to the release lane.** Against production, the release lane runs smoke under a **read-only production Validation Profile** (`prod-preview`/`prod-active`); the profile's semantics are the `smoke` skill's to document, not this file's.
476
+
477
+ **Notification.** A prod build that fails now means the *candidate was never produced* — it flows into the **existing Cloud Build → Pub/Sub notification** above, no new sink. The smoke verdict is no longer a build event at all; it belongs to the release lane.
478
+
479
+ **Debug-loop tip.** Moving validation out of the build is exactly what makes retrying it cheap — this used to be an optional "split it into a second trigger" refinement, and it is now the default. Re-running smoke against the already-deployed candidate URL costs seconds and needs no rebuild. (For staged multi-environment promotion, prefer `cloud-deploy`'s verify phase, which gates promotion and is likewise retryable without a rebuild.)
480
+
481
+ ### Integration (`dev`): deploy 100%, record the verdict, never fail the build
482
+
483
+ `dev` deploys straight to **100% traffic** on build success — no `--no-traffic` staging, no smoke step that can fail the build. Smoke still runs, as a **recorder**:
484
+
485
+ ```
486
+ build → deploy (100% traffic) → smoke → publish SHA-keyed verdict (never fails the build)
487
+ ```
488
+
489
+ ```yaml
490
+ # Dev fork: deploy at 100% traffic (the standard deploy step above), then record a verdict.
491
+ - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
492
+ id: record-smoke-verdict
493
+ entrypoint: bash
494
+ secretEnv: ['GITHUB_TOKEN']
495
+ args:
496
+ - '-c'
497
+ - |
498
+ [[ "${_ENV}" == "dev" ]] || exit 0
499
+ post_status() { # $1=state $2=description
500
+ curl -sS -X POST \
501
+ -H "Authorization: Bearer $${GITHUB_TOKEN}" \
502
+ -H "Accept: application/vnd.github+json" \
503
+ "https://api.github.com/repos/OWNER/REPO/statuses/$COMMIT_SHA" \
504
+ -d "$$(jq -n --arg s "$$1" --arg d "$$2" \
505
+ '{state:$$s, context:"dev-smoke", description:$$d}')"
506
+ }
507
+
508
+ svc="$$(gcloud run services describe {service}-${_ENV} --region=$LOCATION --format=json)"
509
+ serving="$$(jq -r '.status.traffic[] | select(.percent==100) | .revisionName' <<<"$${svc}")"
510
+ url="$$(jq -r '.status.url' <<<"$${svc}")"
511
+
512
+ # Identify the serving revision by the IMAGE it runs, not by its name: revision
513
+ # names are Cloud Run's own counter (`{service}-dev-00042-abc`) and carry no SHA.
514
+ # The image tag is the only thing that ties the running code to this commit.
515
+ running="$$(gcloud run revisions describe "$${serving}" --region=$LOCATION \
516
+ --format='value(spec.containers[0].image)')"
517
+ if [[ "$${running}" != *":$COMMIT_SHA" ]]; then
518
+ # Traffic is pinned to a stale revision. Smoking now would test OLD code and
519
+ # publish a green verdict against THIS SHA — a false ALIVE that the release lane
520
+ # would later read as authorization to promote. Fail the status, run nothing.
521
+ post_status failure "traffic on $${serving} running $${running##*:} — not this SHA; no verdict earned"
522
+ exit 0
523
+ fi
524
+
525
+ node <smoke>/scripts/smoke.mjs verdict --target "$${url}" --out /workspace/smoke-verdict.json \
526
+ && state=success || state=failure
527
+ post_status "$${state}" "$$(jq -r '.summary // "smoke verdict unavailable"' /workspace/smoke-verdict.json)"
528
+
529
+ exit 0 # never fail the dev build on a DEAD verdict
530
+
531
+ availableSecrets:
532
+ secretManager:
533
+ - versionName: projects/$PROJECT_ID/secrets/github-status-token/versions/latest
534
+ env: GITHUB_TOKEN
535
+ ```
536
+
537
+ - After traffic shifts, **confirm the serving revision is running this commit's image**, then run smoke against the live service URL. Capture the exit code instead of letting it fail the step. Compare **images, not revision names** — Cloud Run names revisions from its own counter, so a name-based check silently never matches and degrades to no check at all. On a mismatch, publish `failure` and **run no smoke**: traffic is on older code, so any verdict it produced would be a green light keyed to a SHA that never served.
538
+ - **Publish the verdict as a commit status on the SHA** (context `dev-smoke`, state `success`/`failure`, description naming the broken path on DEAD). This is the artifact the release lane reads: `resolve-release` pins its release candidate to a SHA with green CI **and** `dev-smoke` ALIVE. The image for a SHA is immutable, so the recorded verdict stays valid after `dev` moves on — no re-run at release time.
539
+ - The step then **exits 0 regardless of verdict**: a DEAD verdict marks the SHA unpromotable; it must not block the next dev iteration.
540
+ - **Non-blocking must not mean silent.** On DEAD, still notify (a Pub/Sub message from the step, or a webhook on the `dev-smoke` status change) so a broken dev is known in minutes, not discovered at release time.
541
+
542
+ ## Rules
543
+
544
+ ### Entrypoint Fail-Fast
545
+
546
+ All `entrypoint.sh` scripts that use case statements MUST fail on unknown or missing commands. Never silently default to starting a server or executing arbitrary commands.
547
+
548
+ ```bash
549
+ # WRONG - silently starts server on unknown command
550
+ *)
551
+ exec python -m app.main
552
+ ;;
553
+
554
+ # WRONG - executes arbitrary commands
555
+ *)
556
+ exec "$@"
557
+ ;;
558
+
559
+ # CORRECT - fail fast with clear error
560
+ "")
561
+ echo "Error: No command specified."
562
+ echo "Usage: entrypoint.sh {migrate|seed|test|serve}"
563
+ exit 1
564
+ ;;
565
+ *)
566
+ echo "Error: Unknown command '$1'"
567
+ echo "Usage: entrypoint.sh {migrate|seed|test|serve}"
568
+ exit 1
569
+ ;;
570
+ ```
571
+
572
+ **Why:** Silent defaults cause Cloud Run Jobs to hang indefinitely when passed unrecognized commands (e.g., a `seed` command that doesn't exist). The job appears stuck because it started a server instead of failing immediately.
573
+
574
+ ### Debug Master Branch Issues by Comparing to Dev
575
+
576
+ When debugging and fixing issues on the master branch, always ask: **"Why didn't this occur on the dev branch?"**
577
+
578
+ This question helps identify:
579
+ - **Environment differences**: VPC, secrets, min instances, database configuration
580
+ - **Missing build steps**: Dev skips migrations/seeds - did this mask an issue?
581
+ - **Trigger differences**: Dev triggers on branch push, staging on PR, prod on a `v*-rc.*` tag push
582
+ - **Data differences**: Dev may have different seed data or database state
583
+
584
+ If the issue only manifests on master/prod:
585
+ 1. Compare the cloudbuild.yaml substitutions between environments
586
+ 2. Check if migrations ran correctly (dev skips them)
587
+ 3. Verify secrets are correctly configured for the environment
588
+ 4. Confirm VPC/network settings match expectations
589
+
590
+ **Why:** Issues that appear only in production often stem from environment-specific configuration that was never tested because dev has different settings. Systematically comparing environments catches configuration drift early.
591
+
592
+ ## Key Patterns
593
+
594
+ - **Substitutions**: `${_ENV}` for Cloud Build substitutions
595
+ - **Bash escaping**: `$$VAR` for bash variables (becomes `$VAR`)
596
+ - **Env file**: `/workspace/env.sh` persists variables across steps
597
+ - **Min instances**: 0 dev/staging, 1 prod
598
+ - **Machine type**: `E2_HIGHCPU_8` for faster builds
599
+ - **Startup flags**: `--cpu-boost --no-cpu-throttling --timeout=300` for slow-starting containers
600
+ - **Entrypoint**: Always fail fast on unknown commands (see Rules)
601
+
602
+ For VPC, Secrets, and IAM patterns, see [google-cloud](../google-cloud/SKILL.md) and its reference files.
603
+
604
+ ## Debug
605
+
606
+ ```bash
607
+ # List recent builds
608
+ gcloud builds list --region=$LOCATION --limit=5
609
+
610
+ # Find builds for a specific branch
611
+ gcloud builds list --filter="trigger.branchName=YOUR_BRANCH" --region=$LOCATION
612
+
613
+ # Builds on main branch that failed
614
+ gcloud builds list --filter="trigger.branchName=main AND status=FAILURE" --region=$LOCATION
615
+
616
+ # Detailed output with branch and commit info
617
+ gcloud builds list --filter="trigger.branchName=dev" --region=$LOCATION --limit=10 \
618
+ --format="table(id,startTime,status,trigger.branchName,substitutions.SHORT_SHA)"
619
+
620
+ # View logs for a specific build
621
+ gcloud builds log BUILD_ID --region=$LOCATION
622
+
623
+ # Describe build status
624
+ gcloud builds describe BUILD_ID --region=$LOCATION
625
+
626
+ # Check Cloud Run service status
627
+ gcloud run services describe {svc}-{env} --region=$LOCATION
628
+ ```
629
+
630
+ ## Best Practices
631
+
632
+ ### Enable IAP Protection on Cloud Run
633
+
634
+ See [google-cloud/iam.md](../google-cloud/references/iam.md#cloud-run-native-iap) for:
635
+ - Enabling IAP on Cloud Run with `--no-allow-unauthenticated` and `--iap`
636
+ - Granting access to domain users, individual users, and service accounts
637
+ - IAP in Cloud Build pipelines
638
+
639
+ For programmatic access to IAP-protected resources, see [google-cloud/iam.md#service-account-authentication-jwt-pattern](../google-cloud/references/iam.md#service-account-authentication-jwt-pattern) for:
640
+ - Service account JWT authentication pattern for E2E tests, CI/CD runners, and inter-service calls
641
+
642
+ ## Closed-Loop Execution (Monitor → Debug → Fix → Monitor)
643
+
644
+ **Goal:** Never stop after `gcloud builds log --stream`. Always declare the next step and continue until DONE criteria are met or escalated.
645
+
646
+ ### DONE / Exit Criteria
647
+ - **Cloud Build:** Build status is `SUCCESS` and all steps complete without errors.
648
+ - **Cloud Run Deploy:** Service revision is updated and `Ready` with desired traffic.
649
+ - **Verification:** Basic smoke check passes (health endpoint or minimal request) and no new errors in service logs for a short window.
650
+
651
+ ### Timeboxed Monitoring
652
+ 1. **Stream build logs** for 5-10 minutes:
653
+ ```bash
654
+ gcloud builds log BUILD_ID --region=$LOCATION --stream
655
+ ```
656
+ 2. **If still running**, describe build to pinpoint the current step:
657
+ ```bash
658
+ gcloud builds describe BUILD_ID --region=$LOCATION
659
+ ```
660
+ 3. **If failing**, identify the failing step (by step name/ID), then drill into its logs or related service/job logs.
661
+
662
+ ### FAILURE vs SUCCESS (Next Commands)
663
+
664
+ **On FAILURE:**
665
+ - Declare next step: "Next step: inspect failing step `<step-name>` logs and related Cloud Run/Job logs."
666
+ - Run:
667
+ ```bash
668
+ gcloud builds describe BUILD_ID --region=$LOCATION
669
+ gcloud builds log BUILD_ID --region=$LOCATION
670
+ gcloud run services describe {svc}-{env} --region=$LOCATION
671
+ ```
672
+ - Apply fix (config/code), then **re-run build**, and loop back to monitoring.
673
+
674
+ **On SUCCESS:**
675
+ - Declare next step: "Next step: verify deployment and check service logs."
676
+ - Run:
677
+ ```bash
678
+ gcloud run services describe {svc}-{env} --region=$LOCATION
679
+ gcloud run services logs read {svc}-{env} --region=$LOCATION --limit=50
680
+ ```
681
+ - Perform a minimal verification (health endpoint or basic request). If clean, declare DONE.
682
+
683
+ ### Next Step Declaration Rule
684
+ After any log stream or describe command, **explicitly state the next step** before taking it. This prevents stalls after log streaming.
685
+
686
+ ### Escalation / Ask-Confirmation Boundary (Risky Ops)
687
+ Ask for confirmation **before** any of the following:
688
+ - Database migrations or seeds in prod
689
+ - Rolling back to a prior revision
690
+ - Changing IAM, VPC, or secrets
691
+ - Deleting resources or data
692
+
693
+ ### Incident Checklist (Copy/Paste)
694
+
695
+ ```
696
+ [ ] Identify build ID and region
697
+ [ ] Stream build logs (5-10 min)
698
+ [ ] Describe build to find current/failing step
699
+ [ ] If failing: capture step name and error
700
+ [ ] Inspect related Cloud Run service/job logs
701
+ [ ] Declare next step explicitly
702
+ [ ] Apply fix and re-run build
703
+ [ ] Verify Cloud Run revision is Ready + traffic
704
+ [ ] Smoke check endpoint
705
+ [ ] Confirm no new errors in logs (short window)
706
+ [ ] Declare DONE or escalate with reason
707
+ ```