safeword 0.83.0 → 0.83.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 (167) hide show
  1. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  2. package/codex-plugin/package.json +1 -1
  3. package/codex-plugin/runtime/cli.js +141 -32
  4. package/codex-plugin/skills/audit/SKILL.md +5 -5
  5. package/codex-plugin/skills/bdd/references/PLAN_IMPLEMENTATION.md +3 -3
  6. package/codex-plugin/skills/bdd/references/TDD.md +2 -2
  7. package/codex-plugin/skills/explain/SKILL.md +1 -1
  8. package/codex-plugin/skills/quality-review/SKILL.md +8 -3
  9. package/codex-plugin/skills/retro-filer/SKILL.md +2 -2
  10. package/codex-plugin/skills/review-spec/SKILL.md +8 -3
  11. package/codex-plugin/skills/self-review/SKILL.md +1 -1
  12. package/dist/{architecture-LWLD7J73.js → architecture-W2Y3OIZE.js} +2 -2
  13. package/dist/{architecture-document-PQIEEEJP.js → architecture-document-5JE4A5YC.js} +2 -2
  14. package/dist/{architecture-monorepo-A7P46EKD.js → architecture-monorepo-MVN2ZNPY.js} +2 -2
  15. package/dist/{boundary-JRZJEXKI.js → boundary-64E3GDJN.js} +2 -2
  16. package/dist/{chunk-NZ3Z44QO.js → chunk-2VCJDG7J.js} +2 -2
  17. package/dist/{chunk-HLK7ETBK.js → chunk-3ZP5CZZM.js} +4 -4
  18. package/dist/{chunk-MOAY247K.js → chunk-7GQD36Z3.js} +4 -4
  19. package/dist/{chunk-ORX6RO7S.js → chunk-AAMACAOP.js} +2 -2
  20. package/dist/{chunk-BYAVCH3S.js → chunk-DDIU6BJ6.js} +3 -3
  21. package/dist/{chunk-4TF354OI.js → chunk-GTQAYQZI.js} +2 -2
  22. package/dist/{chunk-4TF354OI.js.map → chunk-GTQAYQZI.js.map} +1 -1
  23. package/dist/{chunk-ZLXV6BCL.js → chunk-JUA53LN3.js} +3 -3
  24. package/dist/{chunk-KG43DUOS.js → chunk-LPHKC4DN.js} +16 -16
  25. package/dist/{chunk-KQM4O5UM.js → chunk-MKKEQQ6V.js} +3 -3
  26. package/dist/{chunk-2NCYSTA5.js → chunk-NK4XRPJT.js} +5 -5
  27. package/dist/{chunk-2NCYSTA5.js.map → chunk-NK4XRPJT.js.map} +1 -1
  28. package/dist/{chunk-O43FBLFX.js → chunk-OTFRUEUN.js} +2 -2
  29. package/dist/{chunk-NJHCONMJ.js → chunk-PDKJANJQ.js} +2 -2
  30. package/dist/{chunk-XCL5F6DS.js → chunk-TUJ3WLVP.js} +2 -2
  31. package/dist/{chunk-7MV6MWJS.js → chunk-VKQCMIV5.js} +2 -2
  32. package/dist/{chunk-OZOLJOAT.js → chunk-WZUQB6VZ.js} +3 -3
  33. package/dist/{cleanup-KCRRSKLP.js → cleanup-JEKEHA4T.js} +5 -5
  34. package/dist/{cleanup-command-S2463KNY.js → cleanup-command-FKUSOWSX.js} +6 -6
  35. package/dist/cli.js +76 -76
  36. package/dist/{clients-J75OMVDD.js → clients-WKXOPHXJ.js} +2 -2
  37. package/dist/{codex-bootstrap-6T6HRF5I.js → codex-bootstrap-4RQTIV2J.js} +7 -7
  38. package/dist/{codex-hook-2OL7P2XK.js → codex-hook-DLUGZPFE.js} +6 -6
  39. package/dist/{codify-WRL5E52Y.js → codify-3S2BRET6.js} +2 -2
  40. package/dist/{commands-4PATZUHM.js → commands-7YDJPQ6A.js} +11 -11
  41. package/dist/{config-43GRBDWO.js → config-HXROEMGR.js} +2 -2
  42. package/dist/{configured-paths-FYCUZEHT.js → configured-paths-5FTU3GSG.js} +2 -2
  43. package/dist/{conformance-TCPHRH2U.js → conformance-DDF5WCPF.js} +2 -2
  44. package/dist/{contract-PV2XLRM6.js → contract-OFC7MFNK.js} +2 -2
  45. package/dist/{coordinator-2FQX7SD4.js → coordinator-53GT3BLG.js} +143 -28
  46. package/dist/coordinator-53GT3BLG.js.map +1 -0
  47. package/dist/{corpus-COOOW3SU.js → corpus-6O6IHTL2.js} +2 -2
  48. package/dist/{cursor-VYZVDCEF.js → cursor-ZZB4RXET.js} +7 -7
  49. package/dist/{doctor-7HNE6SCR.js → doctor-V4DSPCEL.js} +9 -9
  50. package/dist/{drain-retro-spool-S3DMIVKK.js → drain-retro-spool-7EU4HGMN.js} +2 -2
  51. package/dist/{feature-directories-JR25FLSU.js → feature-directories-H5DARJDQ.js} +2 -2
  52. package/dist/{finalization-F4HPIATI.js → finalization-X7LF6IWC.js} +2 -2
  53. package/dist/{gh-cli-CVGMYRVR.js → gh-cli-ROGQKFJ2.js} +2 -2
  54. package/dist/{github-rest-4IEJPY6V.js → github-rest-LKGXNB6U.js} +2 -2
  55. package/dist/index.js +1 -1
  56. package/dist/{job-WVPYOH34.js → job-CQJZVJOV.js} +2 -2
  57. package/dist/{learning-sync-32DSXWRE.js → learning-sync-XH2A4S7Z.js} +2 -2
  58. package/dist/{legacy-global-guidance-LUEOAXCD.js → legacy-global-guidance-G4WIFTE2.js} +2 -2
  59. package/dist/{lint-gherkin-RHQG2Q4A.js → lint-gherkin-L77VBAUH.js} +2 -2
  60. package/dist/{namespace-root-6LVMRVEC.js → namespace-root-ZCT4INBF.js} +2 -2
  61. package/dist/opencode/dispatcher.js +5 -5
  62. package/dist/{operations-ROA62SVD.js → operations-5F7LD2KM.js} +7 -7
  63. package/dist/{output-ME47TZGM.js → output-6ENN5SZI.js} +2 -2
  64. package/dist/{packet-MYJ5MPSF.js → packet-DTPLVVCF.js} +2 -2
  65. package/dist/presets/typescript/index.js +1 -1
  66. package/dist/{profile-7LYUXWOL.js → profile-L6LEUOOH.js} +2 -2
  67. package/dist/{profile-DKERSHNC.js → profile-OMZZ3V2Q.js} +2 -2
  68. package/dist/{prompt-XQWDTHOS.js → prompt-QXAPVMHR.js} +2 -2
  69. package/dist/{public-retros-JMZ4WPE5.js → public-retros-B4EWXUNE.js} +2 -2
  70. package/dist/{remove-NZ5S5GOV.js → remove-BN7V63QN.js} +5 -5
  71. package/dist/{retro-3O7TZZQ3.js → retro-7ZCL7D3B.js} +8 -8
  72. package/dist/{retro-draft-spool-KONZUUS3.js → retro-draft-spool-VEMURUTR.js} +2 -2
  73. package/dist/{retro-drain-JMZ6GIRE.js → retro-drain-X6UT3WID.js} +3 -3
  74. package/dist/{retro-extract-ANJRLC3V.js → retro-extract-Z626476N.js} +2 -2
  75. package/dist/{review-knowledge-QYEITGQP.js → review-knowledge-IFVHQB7R.js} +2 -2
  76. package/dist/{review-pr-6JDIFWUM.js → review-pr-LBSK62SW.js} +2 -2
  77. package/dist/{review-pr-publication-ZN5QKVNE.js → review-pr-publication-2QX3ZMH4.js} +2 -2
  78. package/dist/{run-M7BPQJCX.js → run-UNXPZX36.js} +2 -2
  79. package/dist/{schema-EY7YJZRB.js → schema-ODMXOON6.js} +6 -6
  80. package/dist/{self-report-T32NZCY3.js → self-report-KPT424TQ.js} +2 -2
  81. package/dist/{status-4MTQAKBX.js → status-Q72KJZXF.js} +5 -5
  82. package/dist/{status-WEM436OF.js → status-TQPVBHDB.js} +9 -9
  83. package/dist/{sync-config-3W6B3CWW.js → sync-config-4Z7RHHH6.js} +2 -2
  84. package/dist/{sync-tracker-T5YQNNVO.js → sync-tracker-MOSO42HD.js} +2 -2
  85. package/dist/{test-execution-FQ2SUH7K.js → test-execution-W6HKJJBN.js} +2 -2
  86. package/dist/{test-plan-KDDI3G7A.js → test-plan-OOJIRKJU.js} +2 -2
  87. package/dist/{ticket-new-V4UB45SF.js → ticket-new-5TDDJFOC.js} +2 -2
  88. package/dist/{ticket-reconcile-parent-VHERO5MA.js → ticket-reconcile-parent-32LBP57K.js} +2 -2
  89. package/dist/{ticket-sync-TALYYBSN.js → ticket-sync-VGKQIJVJ.js} +2 -2
  90. package/dist/{tracker-map-AAIVR3LQ.js → tracker-map-NEHJ4Y5Q.js} +2 -2
  91. package/dist/{tracker-sync-VDEHHIOM.js → tracker-sync-FT6HLFES.js} +2 -2
  92. package/package.json +1 -1
  93. package/templates/skills/bdd/PLAN_IMPLEMENTATION.md +1 -1
  94. package/templates/skills/bdd/TDD.md +2 -2
  95. package/templates/skills/quality-review/SKILL.md +6 -1
  96. package/templates/skills/review-spec/SKILL.md +6 -1
  97. package/dist/coordinator-2FQX7SD4.js.map +0 -1
  98. /package/dist/{architecture-LWLD7J73.js.map → architecture-W2Y3OIZE.js.map} +0 -0
  99. /package/dist/{architecture-document-PQIEEEJP.js.map → architecture-document-5JE4A5YC.js.map} +0 -0
  100. /package/dist/{architecture-monorepo-A7P46EKD.js.map → architecture-monorepo-MVN2ZNPY.js.map} +0 -0
  101. /package/dist/{boundary-JRZJEXKI.js.map → boundary-64E3GDJN.js.map} +0 -0
  102. /package/dist/{chunk-NZ3Z44QO.js.map → chunk-2VCJDG7J.js.map} +0 -0
  103. /package/dist/{chunk-HLK7ETBK.js.map → chunk-3ZP5CZZM.js.map} +0 -0
  104. /package/dist/{chunk-MOAY247K.js.map → chunk-7GQD36Z3.js.map} +0 -0
  105. /package/dist/{chunk-ORX6RO7S.js.map → chunk-AAMACAOP.js.map} +0 -0
  106. /package/dist/{chunk-BYAVCH3S.js.map → chunk-DDIU6BJ6.js.map} +0 -0
  107. /package/dist/{chunk-ZLXV6BCL.js.map → chunk-JUA53LN3.js.map} +0 -0
  108. /package/dist/{chunk-KG43DUOS.js.map → chunk-LPHKC4DN.js.map} +0 -0
  109. /package/dist/{chunk-KQM4O5UM.js.map → chunk-MKKEQQ6V.js.map} +0 -0
  110. /package/dist/{chunk-O43FBLFX.js.map → chunk-OTFRUEUN.js.map} +0 -0
  111. /package/dist/{chunk-NJHCONMJ.js.map → chunk-PDKJANJQ.js.map} +0 -0
  112. /package/dist/{chunk-XCL5F6DS.js.map → chunk-TUJ3WLVP.js.map} +0 -0
  113. /package/dist/{chunk-7MV6MWJS.js.map → chunk-VKQCMIV5.js.map} +0 -0
  114. /package/dist/{chunk-OZOLJOAT.js.map → chunk-WZUQB6VZ.js.map} +0 -0
  115. /package/dist/{cleanup-KCRRSKLP.js.map → cleanup-JEKEHA4T.js.map} +0 -0
  116. /package/dist/{cleanup-command-S2463KNY.js.map → cleanup-command-FKUSOWSX.js.map} +0 -0
  117. /package/dist/{clients-J75OMVDD.js.map → clients-WKXOPHXJ.js.map} +0 -0
  118. /package/dist/{codex-bootstrap-6T6HRF5I.js.map → codex-bootstrap-4RQTIV2J.js.map} +0 -0
  119. /package/dist/{codex-hook-2OL7P2XK.js.map → codex-hook-DLUGZPFE.js.map} +0 -0
  120. /package/dist/{codify-WRL5E52Y.js.map → codify-3S2BRET6.js.map} +0 -0
  121. /package/dist/{commands-4PATZUHM.js.map → commands-7YDJPQ6A.js.map} +0 -0
  122. /package/dist/{config-43GRBDWO.js.map → config-HXROEMGR.js.map} +0 -0
  123. /package/dist/{configured-paths-FYCUZEHT.js.map → configured-paths-5FTU3GSG.js.map} +0 -0
  124. /package/dist/{conformance-TCPHRH2U.js.map → conformance-DDF5WCPF.js.map} +0 -0
  125. /package/dist/{contract-PV2XLRM6.js.map → contract-OFC7MFNK.js.map} +0 -0
  126. /package/dist/{corpus-COOOW3SU.js.map → corpus-6O6IHTL2.js.map} +0 -0
  127. /package/dist/{cursor-VYZVDCEF.js.map → cursor-ZZB4RXET.js.map} +0 -0
  128. /package/dist/{doctor-7HNE6SCR.js.map → doctor-V4DSPCEL.js.map} +0 -0
  129. /package/dist/{drain-retro-spool-S3DMIVKK.js.map → drain-retro-spool-7EU4HGMN.js.map} +0 -0
  130. /package/dist/{feature-directories-JR25FLSU.js.map → feature-directories-H5DARJDQ.js.map} +0 -0
  131. /package/dist/{finalization-F4HPIATI.js.map → finalization-X7LF6IWC.js.map} +0 -0
  132. /package/dist/{gh-cli-CVGMYRVR.js.map → gh-cli-ROGQKFJ2.js.map} +0 -0
  133. /package/dist/{github-rest-4IEJPY6V.js.map → github-rest-LKGXNB6U.js.map} +0 -0
  134. /package/dist/{job-WVPYOH34.js.map → job-CQJZVJOV.js.map} +0 -0
  135. /package/dist/{learning-sync-32DSXWRE.js.map → learning-sync-XH2A4S7Z.js.map} +0 -0
  136. /package/dist/{legacy-global-guidance-LUEOAXCD.js.map → legacy-global-guidance-G4WIFTE2.js.map} +0 -0
  137. /package/dist/{lint-gherkin-RHQG2Q4A.js.map → lint-gherkin-L77VBAUH.js.map} +0 -0
  138. /package/dist/{namespace-root-6LVMRVEC.js.map → namespace-root-ZCT4INBF.js.map} +0 -0
  139. /package/dist/{operations-ROA62SVD.js.map → operations-5F7LD2KM.js.map} +0 -0
  140. /package/dist/{output-ME47TZGM.js.map → output-6ENN5SZI.js.map} +0 -0
  141. /package/dist/{packet-MYJ5MPSF.js.map → packet-DTPLVVCF.js.map} +0 -0
  142. /package/dist/{profile-7LYUXWOL.js.map → profile-L6LEUOOH.js.map} +0 -0
  143. /package/dist/{profile-DKERSHNC.js.map → profile-OMZZ3V2Q.js.map} +0 -0
  144. /package/dist/{prompt-XQWDTHOS.js.map → prompt-QXAPVMHR.js.map} +0 -0
  145. /package/dist/{public-retros-JMZ4WPE5.js.map → public-retros-B4EWXUNE.js.map} +0 -0
  146. /package/dist/{remove-NZ5S5GOV.js.map → remove-BN7V63QN.js.map} +0 -0
  147. /package/dist/{retro-3O7TZZQ3.js.map → retro-7ZCL7D3B.js.map} +0 -0
  148. /package/dist/{retro-draft-spool-KONZUUS3.js.map → retro-draft-spool-VEMURUTR.js.map} +0 -0
  149. /package/dist/{retro-drain-JMZ6GIRE.js.map → retro-drain-X6UT3WID.js.map} +0 -0
  150. /package/dist/{retro-extract-ANJRLC3V.js.map → retro-extract-Z626476N.js.map} +0 -0
  151. /package/dist/{review-knowledge-QYEITGQP.js.map → review-knowledge-IFVHQB7R.js.map} +0 -0
  152. /package/dist/{review-pr-6JDIFWUM.js.map → review-pr-LBSK62SW.js.map} +0 -0
  153. /package/dist/{review-pr-publication-ZN5QKVNE.js.map → review-pr-publication-2QX3ZMH4.js.map} +0 -0
  154. /package/dist/{run-M7BPQJCX.js.map → run-UNXPZX36.js.map} +0 -0
  155. /package/dist/{schema-EY7YJZRB.js.map → schema-ODMXOON6.js.map} +0 -0
  156. /package/dist/{self-report-T32NZCY3.js.map → self-report-KPT424TQ.js.map} +0 -0
  157. /package/dist/{status-4MTQAKBX.js.map → status-Q72KJZXF.js.map} +0 -0
  158. /package/dist/{status-WEM436OF.js.map → status-TQPVBHDB.js.map} +0 -0
  159. /package/dist/{sync-config-3W6B3CWW.js.map → sync-config-4Z7RHHH6.js.map} +0 -0
  160. /package/dist/{sync-tracker-T5YQNNVO.js.map → sync-tracker-MOSO42HD.js.map} +0 -0
  161. /package/dist/{test-execution-FQ2SUH7K.js.map → test-execution-W6HKJJBN.js.map} +0 -0
  162. /package/dist/{test-plan-KDDI3G7A.js.map → test-plan-OOJIRKJU.js.map} +0 -0
  163. /package/dist/{ticket-new-V4UB45SF.js.map → ticket-new-5TDDJFOC.js.map} +0 -0
  164. /package/dist/{ticket-reconcile-parent-VHERO5MA.js.map → ticket-reconcile-parent-32LBP57K.js.map} +0 -0
  165. /package/dist/{ticket-sync-TALYYBSN.js.map → ticket-sync-VGKQIJVJ.js.map} +0 -0
  166. /package/dist/{tracker-map-AAIVR3LQ.js.map → tracker-map-NEHJ4Y5Q.js.map} +0 -0
  167. /package/dist/{tracker-sync-VDEHHIOM.js.map → tracker-sync-FT6HLFES.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safeword",
3
- "version": "0.83.0",
3
+ "version": "0.83.1",
4
4
  "description": "Safeword workflow guidance and gates for Codex.",
5
5
  "author": {
6
6
  "name": "Arcade AI"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "safeword-codex-plugin",
3
- "version": "0.83.0",
3
+ "version": "0.83.1",
4
4
  "type": "module"
5
5
  }
@@ -581,11 +581,11 @@ var init_historical_catalogue_generated = __esm(() => {
581
581
  ".claude/skills/audit/SKILL.md": "64afc92c419a8354c015f18ffe0cc581cfce48cb3fee3db8e3c39d75844fb2d3",
582
582
  ".claude/skills/bdd/DISCOVERY.md": "ac8f221691aeffaa16ca6a15a7930a462bdf64aeaf2fe9600903a9dbb417f992",
583
583
  ".claude/skills/bdd/DONE.md": "e9f22430341cf225eaf58ef6335720c5033cb8f6779425d5740adc0ff80a5f60",
584
- ".claude/skills/bdd/PLAN_IMPLEMENTATION.md": "bf7610ab88b4b89a55a233b408ef848b2e4bd413bb65a3b7a7a780a8c02f5d49",
584
+ ".claude/skills/bdd/PLAN_IMPLEMENTATION.md": "0d1c9103c9e6c00b4fb43d3c90a5118f90b9feb964b15daf12340a06d53e4f9a",
585
585
  ".claude/skills/bdd/SCENARIOS.md": "a79590a8dcd8c6377f92e2ec0c26d5479f28e16e53291348f86f59b73381a19e",
586
586
  ".claude/skills/bdd/SKILL.md": "970d5af3af22e599126b5a15f75ec9c9478fd0ca810b31ec33d2dbd94ec83516",
587
587
  ".claude/skills/bdd/SPLITTING.md": "e232a37a4d76f0dfc51e65965c1e1b7f1572e0dedce0fb8c031e75bd6544a708",
588
- ".claude/skills/bdd/TDD.md": "2865c9efa57682eb211cc101f9db15f529bd605c3a2bebb57131e2a6d3aec79d",
588
+ ".claude/skills/bdd/TDD.md": "ed311cb035ab485577319ed21866b40a8406e3551989e4e5ae8b414cbb165eb9",
589
589
  ".claude/skills/bdd/VERIFY.md": "85abadfe756a3f391779fe500cd5c66597a33e0cab7fcef55f6b633b30818f31",
590
590
  ".claude/skills/brainstorm/SKILL.md": "fe99638bd1621cbd5fe3780a8d39023d4b175e3be2aef2e60d0ebe7558848f2e",
591
591
  ".claude/skills/cleanup-zombies/SKILL.md": "e0af9635774767cf36eb69726e11c642ec1dad42839c11407ea8ef60f89fc289",
@@ -599,11 +599,11 @@ var init_historical_catalogue_generated = __esm(() => {
599
599
  ".claude/skills/finish-review/SKILL.md": "fdb8800d140467f1747f7b0ee067137386026003126ff17c00758940766dd07a",
600
600
  ".claude/skills/lint/SKILL.md": "f8bc868fb10a06ca46a22236309b9f0c3ffbd70eecc024d3c79de8ef0e42fd14",
601
601
  ".claude/skills/pr-readiness/SKILL.md": "b23b1bb565f0a4551defa0641b52254133807b1c79495641d82bba9102fd19ff",
602
- ".claude/skills/quality-review/SKILL.md": "6c356d37a4894d9456639236b9d305e2b9a42491119e55cb437a246e0096500d",
602
+ ".claude/skills/quality-review/SKILL.md": "9c7b0a5065d184fed0fd19e449c7a304eee35e376d052409163c3a83501ece27",
603
603
  ".claude/skills/refactor/SKILL.md": "a51a858fb13b50cbc86789edbde8a39e364b5cdd7d5d3b025d555d90b221760e",
604
604
  ".claude/skills/retro-filer/SKILL.md": "ea126f3805a2befefb4db2011439f075ebfd6eca31b78bd5f284ac11d667b4f0",
605
605
  ".claude/skills/retro/SKILL.md": "d01abb281a1c941024f304709c8727769383eb76d0ccc7da53f73776c4a0122d",
606
- ".claude/skills/review-spec/SKILL.md": "d8c5d225ea2fdb723ad9b54bbc17f8f9b566373d04504ee1a466eed50784c7d8",
606
+ ".claude/skills/review-spec/SKILL.md": "1003829012f8134a805f26635782b1e14a5165caa28d6747e7cb9cabfc78bec0",
607
607
  ".claude/skills/self-review/SKILL.md": "e5ff994ec84573e6f129127bad89617f0a67b67c5cf792cedac558b6e419ac3b",
608
608
  ".claude/skills/spike/SKILL.md": "905aab56037ad5a258bafa91cb2ebf05cff1acffbc9e1fd6f7a1f27230672f37",
609
609
  ".claude/skills/tdd-review/SKILL.md": "4b945f122a90d23462845d7bdbbd0b736aa69d423a2d7e99ebf646bf118faa4f",
@@ -48995,6 +48995,9 @@ function independentReviewResult(input) {
48995
48995
  actual_reviewer: input.output.reviewer_agent,
48996
48996
  ...input.model !== undefined && { reviewer_model: input.model },
48997
48997
  ...input.preferredModel !== undefined && { preferred_model: input.preferredModel },
48998
+ ...input.preferredModelFailure !== undefined && {
48999
+ preferred_model_failure: input.preferredModelFailure
49000
+ },
48998
49001
  ...input.preferredFailure !== undefined && { preferred_failure: input.preferredFailure },
48999
49002
  independence: "cross-agent",
49000
49003
  reviewer_output: input.output
@@ -49044,7 +49047,7 @@ async function executeReview(reviewer, prepared, model, runDeadline) {
49044
49047
  prepared.cleanup();
49045
49048
  }
49046
49049
  }
49047
- function assessFallback(outcome, reviewer, dispatchId) {
49050
+ function assessReviewOutcome(outcome, reviewer, dispatchId) {
49048
49051
  if (outcome.kind === "failed")
49049
49052
  return outcome;
49050
49053
  const provenance = verifyProvenance(outcome.output, reviewer, dispatchId);
@@ -49053,6 +49056,9 @@ function assessFallback(outcome, reviewer, dispatchId) {
49053
49056
  function agentName(agent) {
49054
49057
  return agent === "codex" ? "Codex" : "Claude";
49055
49058
  }
49059
+ function reviewerLoginCommand(agent) {
49060
+ return agent === "codex" ? "codex login" : "claude auth login";
49061
+ }
49056
49062
  function causePhrase(failure) {
49057
49063
  return FAILURE_CAUSES[failure] ?? "could not be run";
49058
49064
  }
@@ -49063,6 +49069,31 @@ function exhaustedExplanation(routes) {
49063
49069
  });
49064
49070
  return [...sentences, "No independent check was recorded."].join(" ");
49065
49071
  }
49072
+ function primaryFailureRoutes(input) {
49073
+ if (input.preferredModelFailure === undefined) {
49074
+ return [
49075
+ {
49076
+ agent: input.assignedReviewer,
49077
+ role: "independent reviewer",
49078
+ model: input.preferredModel,
49079
+ failure: input.preferredFailure
49080
+ }
49081
+ ];
49082
+ }
49083
+ return [
49084
+ {
49085
+ agent: input.assignedReviewer,
49086
+ role: "independent reviewer on its configured model",
49087
+ model: input.preferredModel,
49088
+ failure: input.preferredModelFailure
49089
+ },
49090
+ {
49091
+ agent: input.assignedReviewer,
49092
+ role: "independent reviewer on its default model",
49093
+ failure: input.preferredFailure
49094
+ }
49095
+ ];
49096
+ }
49066
49097
  function nextStepFor(reviewer, failure) {
49067
49098
  const name = agentName(reviewer);
49068
49099
  if (failure === "not_installed")
@@ -49075,8 +49106,6 @@ function nextStepFor(reviewer, failure) {
49075
49106
  return `Run ${name} --help to diagnose it, then retry review.`;
49076
49107
  if (failure === "launch_failed")
49077
49108
  return `Run ${name} --help and fix its launch failure, then retry review.`;
49078
- if (failure === "not_authenticated")
49079
- return `Sign in to ${name}, then run the review again.`;
49080
49109
  return "Run the review again.";
49081
49110
  }
49082
49111
  function degradedDescription(assignedReviewer, actualReviewer, failure) {
@@ -49174,6 +49203,9 @@ function changedReviewResult(input) {
49174
49203
  function routeFailureData(input) {
49175
49204
  return {
49176
49205
  ...input.preferredModel !== undefined && { preferred_model: input.preferredModel },
49206
+ ...input.preferredModelFailure !== undefined && {
49207
+ preferred_model_failure: input.preferredModelFailure
49208
+ },
49177
49209
  preferred_failure: input.preferredFailure,
49178
49210
  ...input.alternateFailure !== undefined && {
49179
49211
  alternate_model_failure: input.alternateFailure,
@@ -49181,6 +49213,41 @@ function routeFailureData(input) {
49181
49213
  }
49182
49214
  };
49183
49215
  }
49216
+ function authenticationRequiredResult(input) {
49217
+ const reviewer = agentName(input.assignedReviewer);
49218
+ return createResult({
49219
+ state: "action_required",
49220
+ findings: [
49221
+ {
49222
+ code: "REVIEW_AUTHENTICATION_REQUIRED",
49223
+ message: `The independent ${reviewer} review needs authentication. Reauthenticate ${reviewer}, then retry the same review; no fallback or review evidence was recorded.`,
49224
+ severity: "warning"
49225
+ }
49226
+ ],
49227
+ effects: {
49228
+ network: [
49229
+ ...networkEffectsForFailure(input.assignedReviewer, input.preferredFailure),
49230
+ ...networkEffectsForFailure(input.assignedReviewer, input.alternateFailure)
49231
+ ]
49232
+ },
49233
+ recovery: [
49234
+ {
49235
+ command: reviewerLoginCommand(input.assignedReviewer),
49236
+ description: `Reauthenticate ${reviewer}, then retry the original independent review.`,
49237
+ requiresHuman: true
49238
+ }
49239
+ ],
49240
+ data: {
49241
+ command: "review run",
49242
+ status: "blocked",
49243
+ author_agent: input.author,
49244
+ assigned_reviewer: input.assignedReviewer,
49245
+ ...routeFailureData(input),
49246
+ review_policy: input.policy,
49247
+ independence: "none"
49248
+ }
49249
+ });
49250
+ }
49184
49251
  function reviewRequest(reviewer) {
49185
49252
  return { kind: "review", target: reviewer, operation: "request" };
49186
49253
  }
@@ -49206,7 +49273,11 @@ async function executePrimaryReview(input, reviewer, primaryModel, runDeadline)
49206
49273
  let execution = await executeReview(reviewer, prepared, primaryModel, runDeadline);
49207
49274
  let model = primaryModel;
49208
49275
  let dispatchId = prepared.packet.dispatch_id;
49276
+ let rejectedModel;
49277
+ let rejectedModelFailure;
49209
49278
  if (primaryModel !== undefined && execution.outcome.kind === "failed" && execution.outcome.failure === "unsupported" && !execution.outcome.terminal && canFundRoute(runDeadline)) {
49279
+ rejectedModel = primaryModel;
49280
+ rejectedModelFailure = execution.outcome.failure;
49210
49281
  const defaultPrepared = preparePrimaryReview(input, reviewer);
49211
49282
  const retried = await executeReview(reviewer, defaultPrepared, undefined, runDeadline);
49212
49283
  execution = {
@@ -49217,7 +49288,13 @@ async function executePrimaryReview(input, reviewer, primaryModel, runDeadline)
49217
49288
  model = undefined;
49218
49289
  dispatchId = defaultPrepared.packet.dispatch_id;
49219
49290
  }
49220
- return { ...execution, model, dispatchId };
49291
+ return {
49292
+ ...execution,
49293
+ model,
49294
+ dispatchId,
49295
+ preferredModel: rejectedModel,
49296
+ preferredModelFailure: rejectedModelFailure
49297
+ };
49221
49298
  }
49222
49299
  function prepareFallbackReview(input, assignedReviewer, author) {
49223
49300
  const fallbackName = agentName(author);
@@ -49249,7 +49326,7 @@ async function runDegradedFallback(input) {
49249
49326
  });
49250
49327
  if (changedResult !== undefined)
49251
49328
  return changedResult;
49252
- const assessment = assessFallback(outcome, input.author, prepared.packet.dispatch_id);
49329
+ const assessment = assessReviewOutcome(outcome, input.author, prepared.packet.dispatch_id);
49253
49330
  if (assessment.kind === "failed") {
49254
49331
  return createResult({
49255
49332
  state: "action_required",
@@ -49257,12 +49334,7 @@ async function runDegradedFallback(input) {
49257
49334
  {
49258
49335
  code: "REVIEW_ROUTES_EXHAUSTED",
49259
49336
  message: exhaustedExplanation([
49260
- {
49261
- agent: input.assignedReviewer,
49262
- role: "independent reviewer",
49263
- model: input.preferredModel,
49264
- failure: input.preferredFailure
49265
- },
49337
+ ...primaryFailureRoutes(input),
49266
49338
  ...input.alternateFailure === undefined ? [] : [
49267
49339
  {
49268
49340
  agent: input.assignedReviewer,
@@ -49288,7 +49360,7 @@ async function runDegradedFallback(input) {
49288
49360
  recovery: [
49289
49361
  {
49290
49362
  command: retryCommand(input.kind, input.targets, input.context),
49291
- description: nextStepFor(input.assignedReviewer, input.preferredFailure),
49363
+ description: nextStepFor(input.assignedReviewer, input.preferredModelFailure ?? input.preferredFailure),
49292
49364
  requiresHuman: true
49293
49365
  }
49294
49366
  ],
@@ -49400,11 +49472,9 @@ async function runAlternateModelRoute(input) {
49400
49472
  });
49401
49473
  if (changedResult !== undefined)
49402
49474
  return { kind: "completed", result: changedResult };
49403
- const assessment = assessFallback(outcome, input.reviewer, prepared.packet.dispatch_id);
49475
+ const assessment = assessReviewOutcome(outcome, input.reviewer, prepared.packet.dispatch_id);
49404
49476
  if (assessment.kind === "failed") {
49405
- if (ALTERNATE_MODEL_SKIP_FAILURES.has(assessment.failure))
49406
- return { kind: "skipped" };
49407
- return { ...assessment, model };
49477
+ return resolveAlternateModelFailure(input, model, assessment);
49408
49478
  }
49409
49479
  const output = assessment.output;
49410
49480
  const result = independentReviewResult({
@@ -49413,10 +49483,30 @@ async function runAlternateModelRoute(input) {
49413
49483
  output,
49414
49484
  model,
49415
49485
  preferredModel: input.preferredModel,
49486
+ preferredModelFailure: input.preferredModelFailure,
49416
49487
  preferredFailure: input.preferredFailure
49417
49488
  });
49418
49489
  return { kind: "completed", result };
49419
49490
  }
49491
+ function resolveAlternateModelFailure(input, model, assessment) {
49492
+ if (ALTERNATE_MODEL_SKIP_FAILURES.has(assessment.failure))
49493
+ return { kind: "skipped" };
49494
+ if (assessment.failure !== "not_authenticated")
49495
+ return { ...assessment, model };
49496
+ return {
49497
+ kind: "completed",
49498
+ result: authenticationRequiredResult({
49499
+ author: input.author,
49500
+ assignedReviewer: input.reviewer,
49501
+ preferredModel: input.preferredModel,
49502
+ preferredModelFailure: input.preferredModelFailure,
49503
+ preferredFailure: input.preferredFailure,
49504
+ alternateModel: model,
49505
+ alternateFailure: assessment.failure,
49506
+ policy: input.policy
49507
+ })
49508
+ };
49509
+ }
49420
49510
  async function runRemainingRoutes(input) {
49421
49511
  const alternate = await runAlternateModelRoute({
49422
49512
  cwd: input.cwd,
@@ -49427,6 +49517,7 @@ async function runRemainingRoutes(input) {
49427
49517
  author: input.author,
49428
49518
  reviewer: input.assignedReviewer,
49429
49519
  preferredModel: input.preferredModel,
49520
+ preferredModelFailure: input.preferredModelFailure,
49430
49521
  preferredFailure: input.preferredFailure,
49431
49522
  policy: input.policy,
49432
49523
  runDeadline: input.runDeadline
@@ -49450,12 +49541,7 @@ function exhaustedRunResult(input) {
49450
49541
  {
49451
49542
  code: "REVIEW_ROUTES_EXHAUSTED",
49452
49543
  message: exhaustedExplanation([
49453
- {
49454
- agent: input.assignedReviewer,
49455
- role: "independent reviewer",
49456
- model: input.preferredModel,
49457
- failure: input.preferredFailure
49458
- },
49544
+ ...primaryFailureRoutes(input),
49459
49545
  ...input.alternateFailure === undefined ? [] : [
49460
49546
  {
49461
49547
  agent: input.assignedReviewer,
@@ -49477,7 +49563,7 @@ function exhaustedRunResult(input) {
49477
49563
  recovery: [
49478
49564
  {
49479
49565
  command: retryCommand(input.kind, input.targets, input.context),
49480
- description: nextStepFor(input.assignedReviewer, input.preferredFailure),
49566
+ description: nextStepFor(input.assignedReviewer, input.preferredModelFailure ?? input.preferredFailure),
49481
49567
  requiresHuman: true
49482
49568
  }
49483
49569
  ],
@@ -49532,8 +49618,11 @@ async function runReview(input) {
49532
49618
  sourceChanged,
49533
49619
  snapshotChanged,
49534
49620
  model: completedModel,
49535
- dispatchId
49621
+ dispatchId,
49622
+ preferredModel,
49623
+ preferredModelFailure
49536
49624
  } = await executePrimaryReview(input, reviewer, primaryModel, runDeadline);
49625
+ const reportedPreferredModel = preferredModel ?? completedModel;
49537
49626
  const changedResult = changedReviewResult({
49538
49627
  author: pair.author,
49539
49628
  reviewer,
@@ -49548,12 +49637,23 @@ async function runReview(input) {
49548
49637
  if (changedResult !== undefined)
49549
49638
  return changedResult;
49550
49639
  if (outcome.kind === "failed") {
49640
+ if (outcome.failure === "not_authenticated") {
49641
+ return authenticationRequiredResult({
49642
+ author: pair.author,
49643
+ assignedReviewer: reviewer,
49644
+ preferredModel: reportedPreferredModel,
49645
+ preferredModelFailure,
49646
+ preferredFailure: outcome.failure,
49647
+ policy
49648
+ });
49649
+ }
49551
49650
  if (outcome.terminal) {
49552
49651
  return exhaustedRunResult({
49553
49652
  ...input,
49554
49653
  author: pair.author,
49555
49654
  assignedReviewer: reviewer,
49556
- preferredModel: completedModel,
49655
+ preferredModel: reportedPreferredModel,
49656
+ preferredModelFailure,
49557
49657
  preferredFailure: outcome.failure,
49558
49658
  policy
49559
49659
  });
@@ -49562,7 +49662,8 @@ async function runReview(input) {
49562
49662
  ...input,
49563
49663
  author: pair.author,
49564
49664
  assignedReviewer: reviewer,
49565
- preferredModel: completedModel,
49665
+ preferredModel: reportedPreferredModel,
49666
+ preferredModelFailure,
49566
49667
  preferredFailure: outcome.failure,
49567
49668
  policy,
49568
49669
  runDeadline
@@ -49574,14 +49675,22 @@ async function runReview(input) {
49574
49675
  ...input,
49575
49676
  author: pair.author,
49576
49677
  assignedReviewer: reviewer,
49577
- preferredModel: completedModel,
49678
+ preferredModel: reportedPreferredModel,
49679
+ preferredModelFailure,
49578
49680
  preferredFailure: provenance.code,
49579
49681
  policy,
49580
49682
  runDeadline
49581
49683
  });
49582
49684
  }
49583
49685
  const output = provenance.output;
49584
- return independentReviewResult({ author: pair.author, reviewer, output, model: completedModel });
49686
+ return independentReviewResult({
49687
+ author: pair.author,
49688
+ reviewer,
49689
+ output,
49690
+ model: completedModel,
49691
+ preferredModel,
49692
+ preferredModelFailure
49693
+ });
49585
49694
  }
49586
49695
  var MAX_TERMINAL_REVIEWER_TEXT_LENGTH = 2000, FAILURE_CAUSES, NON_ATTEMPT_FAILURES, ALTERNATE_MODEL_SKIP_FAILURES;
49587
49696
  var init_coordinator = __esm(() => {
@@ -561,7 +561,7 @@ Changed project learnings in the resolved namespace root's `learnings/*.md` must
561
561
  PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2> /dev/null || pwd)}"
562
562
  source "$PROJECT_DIR/.safeword/hooks/lib/audit-scope.sh"
563
563
  audit_scope_initialize "$PROJECT_DIR" || exit $?
564
- NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR")"
564
+ NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR")"
565
565
 
566
566
  learning_is_in_audit_scope() {
567
567
  [ "$AUDIT_SCOPE_MODE" = "repository" ] && return 0
@@ -721,13 +721,13 @@ audit_scope_initialize "$PROJECT_DIR" || exit $?
721
721
 
722
722
  # Resolve the namespace root (honors config paths.projectRoot in real runs).
723
723
  # Fall back on directory existence — robust when the resolver hook is absent.
724
- NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" 2> /dev/null)"
724
+ NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" 2> /dev/null)"
725
725
  [ -d "$NS_ROOT" ] || {
726
726
  if [ -d "$PROJECT_DIR/.project" ]; then NS_ROOT="$PROJECT_DIR/.project"; else NS_ROOT="$PROJECT_DIR/.safeword-project"; fi
727
727
  }
728
- PERSONAS_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key personas 2> /dev/null)"
729
- SURFACES_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key surfaces 2> /dev/null)"
730
- GLOSSARY_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key glossary 2> /dev/null)"
728
+ PERSONAS_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key personas 2> /dev/null)"
729
+ SURFACES_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key surfaces 2> /dev/null)"
730
+ GLOSSARY_FILE="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR" --key glossary 2> /dev/null)"
731
731
  [ -n "$PERSONAS_FILE" ] || PERSONAS_FILE="$NS_ROOT/personas.md"
732
732
  [ -n "$SURFACES_FILE" ] || SURFACES_FILE="$NS_ROOT/surfaces.md"
733
733
  [ -n "$GLOSSARY_FILE" ] || GLOSSARY_FILE="$NS_ROOT/glossary.md"
@@ -159,13 +159,13 @@ findings remain. Return findings through the typed reviewer result contract.
159
159
 
160
160
  ## Exit: review, then (optionally) the user
161
161
 
162
- 1. **Independent review first.** At review time, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project review-knowledge --json`. Resolve a review-capable Safeword CLI, then invoke the coordinator with the current files identified by the resolver:
162
+ 1. **Independent review first.** At review time, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project review-knowledge --json`. Resolve a review-capable Safeword CLI, then invoke the coordinator with the current files identified by the resolver:
163
163
 
164
164
  ```bash
165
- SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" review run plan-implementation --agent-handoff --json --context spec.md ticket.md feature-file principles-file personas-file surfaces-file architecture-records -- impl-plan.md
165
+ SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" review run plan-implementation --agent-handoff --json --context spec.md ticket.md feature-file principles-file personas-file surfaces-file architecture-records -- impl-plan.md
166
166
  ```
167
167
 
168
- The shared coordinator sends that bounded packet to the opposite headless agent when available; its typed verdict, failure classification, and independence level are authoritative. `impl-plan.md` is the work under review; all resolved feature and project artifacts are bounded context. Only when that typed result is `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` immediately with the original result and the same accepted targets; return every other result unchanged and do not substitute another private subagent. Fix findings, re-resolve the sources, re-review, then stamp the exit with the returned agent provenance (`write-review-stamp.ts --author-agent "author-agent" --reviewer-agent "actual-reviewer" --independence "independence" --phase plan-implementation`, where the review gate is enabled). Add `--model` only when the executed reviewer reports a verifiable model identifier; the coordinator never invents one. Human handoff happens **only after** this review passes — raw planning output is never presented for approval. Exception, any time: information only the user has (intent, priorities, constraints not in code or docs) routes to the user the moment the gap appears — `$safeword:elicit`.
168
+ The shared coordinator sends that bounded packet to the opposite headless agent when available; its typed verdict, failure classification, and independence level are authoritative. `impl-plan.md` is the work under review; all resolved feature and project artifacts are bounded context. If the typed result is `REVIEW_AUTHENTICATION_REQUIRED`, execute its exact recovery command; the user's browser or device flow may need to complete. After successful authentication, rerun the same coordinator command once. Do not invoke `$safeword:finish-review`, accept degraded coverage, or loop on another auth denial; report an unsuccessful reauthentication as the blocker. Only when that typed result is `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` immediately with the original result and the same accepted targets; return every other result unchanged and do not substitute another private subagent. Fix findings, re-resolve the sources, re-review, then stamp the exit with the returned agent provenance (`write-review-stamp.ts --author-agent "author-agent" --reviewer-agent "actual-reviewer" --independence "independence" --phase plan-implementation`, where the review gate is enabled). Add `--model` only when the executed reviewer reports a verifiable model identifier; the coordinator never invents one. Human handoff happens **only after** this review passes — raw planning output is never presented for approval. Exception, any time: information only the user has (intent, priorities, constraints not in code or docs) routes to the user the moment the gap appears — `$safeword:elicit`.
169
169
 
170
170
  2. **`designApprovalGate`** (in `.safeword/config.json`): **absent or off** — the reviewed plan advances autonomously; do not ask. **Enabled** — present the reviewed plan (riskiest assumption, build order, decisions) and wait for user approval before `implement`.
171
171
  3. **Sessions without an interactive user** (cloud/headless — Claude Code on the Web, Codex Cloud, Cursor Cloud Agents): an enabled approval gate must not stall the container. Record the auto-decision as pending approval in the ticket work log and surface the reviewed plan in the session's reviewable output (PR description / session summary) — approval lands at PR review. Note: Cursor Cloud Agents run `preToolUse` hooks but not stop hooks, so enforcement rides the transition gate there, not stop-time nudges.
@@ -196,10 +196,10 @@ Off by default. When `.safeword/config.json` sets `architectureReviewGate: true`
196
196
  2. **A fresh-context review.** Resolve a review-capable Safeword CLI, then run the shared coordinator with only the bounded design evidence:
197
197
 
198
198
  ```bash
199
- SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" review run plan-implementation impl-plan.md ticket-spec feature-file --agent-handoff --json
199
+ SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" review run plan-implementation --agent-handoff --json --context spec.md ticket.md feature-file principles-file personas-file surfaces-file architecture-records -- impl-plan.md
200
200
  ```
201
201
 
202
- The shared coordinator prefers the opposite headless agent. Only when its typed result is `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` with the original result and the same accepted targets; return every other result unchanged. Degraded findings cannot satisfy a required independent-review gate. On an independent pass, stamp it:
202
+ The shared coordinator prefers the opposite headless agent. If the typed result is `REVIEW_AUTHENTICATION_REQUIRED`, execute its exact recovery command; the user's browser or device flow may need to complete. After successful authentication, rerun the same coordinator command once. Do not invoke `$safeword:finish-review`, accept degraded coverage, or loop on another auth denial; report an unsuccessful reauthentication as the blocker. Only when its typed result is `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` with the original result and the same accepted targets; return every other result unchanged. Degraded findings cannot satisfy a required independent-review gate. On an independent pass, stamp it:
203
203
 
204
204
  ```bash
205
205
  bun .safeword/hooks/write-review-stamp.ts --author-agent "author-agent" --reviewer-agent "actual-reviewer" --independence "independence" impl-plan
@@ -39,7 +39,7 @@ Gather the durable trail safeword already keeps, then narrate it. Run:
39
39
 
40
40
  ```bash
41
41
  PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2> /dev/null || pwd)}"
42
- NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR")"
42
+ NS_ROOT="$(bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project namespace-root --cwd "$PROJECT_DIR")"
43
43
  # What you're on now: the last re-entry line names the current ticket + Next
44
44
  tail -3 "$NS_ROOT/re-entry.md" 2> /dev/null
45
45
  # Fallback when re-entry is empty: in_progress tickets (not epics)
@@ -59,7 +59,7 @@ If in a BDD workflow, read the current ticket from `<namespace-root>/tickets/` a
59
59
 
60
60
  ### Project-principle challenge
61
61
 
62
- For a BDD ticket, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project review-knowledge --json` at the
62
+ For a BDD ticket, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project review-knowledge --json` at the
63
63
  start of each pass and read the current `principles`, `personas`, and `surfaces`
64
64
  paths and content it returns (including overrides such as `paths.principles`).
65
65
  Do not substitute labels or intake-era content.
@@ -221,7 +221,7 @@ Each pass:
221
221
  guarantee a bare `safeword` on `PATH`:
222
222
 
223
223
  ```bash
224
- SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" review run quality-review [--context path/to/evidence] --agent-handoff --json -- changed-file [more-changed-files...]
224
+ SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" review run quality-review [--context path/to/evidence] --agent-handoff --json -- changed-file [more-changed-files...]
225
225
  ```
226
226
 
227
227
  A healthy deep review may return `REVIEW_PENDING` after its foreground
@@ -236,7 +236,12 @@ Each pass:
236
236
  headless Claude. The coordinator uses a neutral snapshot, checks reviewer
237
237
  provenance, preserves the exact preferred-route failure, and records any
238
238
  permitted same-agent fallback as `independence: degraded`. Treat its typed
239
- result as the review verdict. Only when the typed result is
239
+ result as the review verdict. If the typed result is
240
+ `REVIEW_AUTHENTICATION_REQUIRED`, execute its exact recovery command; the
241
+ user's browser or device flow may need to complete. After successful
242
+ authentication, rerun the same coordinator command once. Do not invoke
243
+ `$safeword:finish-review`, accept degraded coverage, or loop on another auth denial;
244
+ report an unsuccessful reauthentication as the blocker. Only when the typed result is
240
245
  `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` immediately with the
241
246
  original result and the same accepted targets. For every other result,
242
247
  return it unchanged. The canonical fallback may use one host-native
@@ -17,7 +17,7 @@ a caller-nominated path. The spool contains sanitized safeword findings for
17
17
  ## Procedure
18
18
 
19
19
  1. Before reading or making any tracker call, run
20
- `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project retro-drain "<spool-path>" --validated-jsonl`.
20
+ `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project retro-drain "<spool-path>" --validated-jsonl`.
21
21
  Use only its JSONL stdout as the filing input. A nonzero exit means validation
22
22
  failed: make no search, comment, or create call, leave the spool unchanged,
23
23
  and report `retro-filer: cannot file - draft validation failed`. If its output
@@ -60,7 +60,7 @@ a caller-nominated path. The spool contains sanitized safeword findings for
60
60
  the draft only when the append succeeded and the exact ack is visible. If the
61
61
  append or verification fails, leave the draft in place.
62
62
  5. Create at most five new issues per run. Drain only by running
63
- `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project retro-drain "<spool-path>"`; never rewrite or
63
+ `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project retro-drain "<spool-path>"`; never rewrite or
64
64
  delete the spool directly. The helper removes only drafts whose valid ack is
65
65
  reader-visible, so unfiled or unacknowledged drafts remain. If tracker write
66
66
  access is unavailable, leave the spool unchanged and report
@@ -35,7 +35,7 @@ Adversarially review a ticket's scenarios: treat them as if you're trying to bre
35
35
  - **Manual re-run** — invoke `$safeword:review-spec` anytime after `define-behavior` (e.g., scenarios changed during implement and you want to re-validate). Allowed on a closed ticket too — a post-hoc audit is still readable.
36
36
 
37
37
  Read the active ticket's `.feature` source first. At review time, run
38
- `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project review-knowledge --json` and read the current
38
+ `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project review-knowledge --json` and read the current
39
39
  `principles`, `personas`, and `surfaces` source paths and content it returns, so
40
40
  the review is grounded in project knowledge rather than labels or stale intake
41
41
  context. The resolver honors `paths.principles`, `paths.personas`, and
@@ -58,11 +58,16 @@ Resolve a review-capable Safeword CLI first; source checkouts do not guarantee
58
58
  a bare `safeword` on `PATH`:
59
59
 
60
60
  ```bash
61
- SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" review run scenario-gate feature-file [legacy-test-definitions] --context ticket-spec [dimensions-file] principles-file personas-file surfaces-file --agent-handoff --json
61
+ SAFEWORD_REVIEW_PROGRESS=1 bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" review run scenario-gate feature-file [legacy-test-definitions] --context ticket-spec [dimensions-file] principles-file personas-file surfaces-file --agent-handoff --json
62
62
  ```
63
63
 
64
64
  The coordinator's assigned/actual reviewer, failure classification, and
65
- independence level are authoritative. Only when the typed result is
65
+ independence level are authoritative. If the typed result is
66
+ `REVIEW_AUTHENTICATION_REQUIRED`, execute its exact recovery command; the
67
+ user's browser or device flow may need to complete. After successful
68
+ authentication, rerun the same coordinator command once. Do not invoke
69
+ `$safeword:finish-review`, accept degraded coverage, or loop on another auth denial;
70
+ report an unsuccessful reauthentication as the blocker. Only when the typed result is
66
71
  `REVIEW_ROUTES_EXHAUSTED`, invoke `$safeword:finish-review` immediately with the original
67
72
  result and the same accepted targets. For every other result, return it
68
73
  unchanged. Never substitute another surface-private reviewer or hand-written
@@ -45,7 +45,7 @@ installed helper — report it to the user and resolve before retrying.
45
45
  ## Review the spec (do this now, with the stamp written)
46
46
 
47
47
  The stamp records that a review was invoked; the actual scrutiny is yours. At
48
- review time, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.0/runtime/cli.js" project review-knowledge --json` and use its
48
+ review time, run `bun "${CODEX_HOME:-$HOME/.codex}/plugins/cache/safeword/safeword/0.83.1/runtime/cli.js" project review-knowledge --json` and use its
49
49
  current `principles`, `personas`, and `surfaces` source paths and content—not
50
50
  labels remembered from intake. These resolve from `paths.principles`,
51
51
  `paths.personas`, and `paths.surfaces` when configured. Read those sources with the active ticket's
@@ -25,7 +25,7 @@ import {
25
25
  readJson,
26
26
  writeJson
27
27
  } from "./chunk-HF3DXZEA.js";
28
- import "./chunk-4TF354OI.js";
28
+ import "./chunk-GTQAYQZI.js";
29
29
 
30
30
  // src/commands/architecture.ts
31
31
  import { execFileSync } from "child_process";
@@ -650,4 +650,4 @@ export {
650
650
  architectureStage,
651
651
  architectureStaged
652
652
  };
653
- //# sourceMappingURL=architecture-LWLD7J73.js.map
653
+ //# sourceMappingURL=architecture-W2Y3OIZE.js.map
@@ -11,7 +11,7 @@ import {
11
11
  import "./chunk-NEOV7ZY3.js";
12
12
  import "./chunk-VZ5B2SIO.js";
13
13
  import "./chunk-HF3DXZEA.js";
14
- import "./chunk-4TF354OI.js";
14
+ import "./chunk-GTQAYQZI.js";
15
15
  export {
16
16
  isSafewordOwned,
17
17
  isWouldChangeAction,
@@ -22,4 +22,4 @@ export {
22
22
  selfHealProject,
23
23
  selfHealProjectPreservingProse
24
24
  };
25
- //# sourceMappingURL=architecture-document-PQIEEEJP.js.map
25
+ //# sourceMappingURL=architecture-document-5JE4A5YC.js.map
@@ -5,11 +5,11 @@ import {
5
5
  monorepoFingerprintOf
6
6
  } from "./chunk-VZ5B2SIO.js";
7
7
  import "./chunk-HF3DXZEA.js";
8
- import "./chunk-4TF354OI.js";
8
+ import "./chunk-GTQAYQZI.js";
9
9
  export {
10
10
  discoverUnreadableWorkspaces,
11
11
  discoverWorkspaces,
12
12
  extractMonorepoArchitectureSnapshot,
13
13
  monorepoFingerprintOf
14
14
  };
15
- //# sourceMappingURL=architecture-monorepo-A7P46EKD.js.map
15
+ //# sourceMappingURL=architecture-monorepo-MVN2ZNPY.js.map
@@ -27,7 +27,7 @@ import {
27
27
  import {
28
28
  readFileSafe
29
29
  } from "./chunk-HF3DXZEA.js";
30
- import "./chunk-4TF354OI.js";
30
+ import "./chunk-GTQAYQZI.js";
31
31
 
32
32
  // src/commands/boundary.ts
33
33
  import { execFileSync as execFileSync2 } from "child_process";
@@ -651,4 +651,4 @@ function boundary(options) {
651
651
  export {
652
652
  boundary
653
653
  };
654
- //# sourceMappingURL=boundary-JRZJEXKI.js.map
654
+ //# sourceMappingURL=boundary-64E3GDJN.js.map
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-FOYGZ4MK.js";
18
18
  import {
19
19
  SAFEWORD_SCHEMA
20
- } from "./chunk-ORX6RO7S.js";
20
+ } from "./chunk-AAMACAOP.js";
21
21
  import {
22
22
  uninstallDependencies
23
23
  } from "./chunk-DQVGWAEO.js";
@@ -363,4 +363,4 @@ export {
363
363
  diffFileSnapshots,
364
364
  removeProject
365
365
  };
366
- //# sourceMappingURL=chunk-NZ3Z44QO.js.map
366
+ //# sourceMappingURL=chunk-2VCJDG7J.js.map
@@ -2,10 +2,10 @@ import {
2
2
  PRODUCTION_INTEGRATIONS,
3
3
  checkHealth,
4
4
  coordinateSelectedIntegrations
5
- } from "./chunk-KG43DUOS.js";
5
+ } from "./chunk-LPHKC4DN.js";
6
6
  import {
7
7
  unselectedCursorFinding
8
- } from "./chunk-BYAVCH3S.js";
8
+ } from "./chunk-DDIU6BJ6.js";
9
9
  import {
10
10
  compareVersions,
11
11
  isSafePackageVersion
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-D5ENZR6N.js";
17
17
  import {
18
18
  projectLifecycleSchema
19
- } from "./chunk-OZOLJOAT.js";
19
+ } from "./chunk-WZUQB6VZ.js";
20
20
  import {
21
21
  DEFAULT_AGENT_INTEGRATIONS
22
22
  } from "./chunk-4L4NYOC3.js";
@@ -266,4 +266,4 @@ export {
266
266
  summarizeLifecycleStatus,
267
267
  observeLifecycleStatus
268
268
  };
269
- //# sourceMappingURL=chunk-HLK7ETBK.js.map
269
+ //# sourceMappingURL=chunk-3ZP5CZZM.js.map