gentle-pi 2.3.0 → 2.4.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 (59) hide show
  1. package/README.md +30 -4
  2. package/assets/agents/sdd-explore.md +1 -0
  3. package/assets/orchestrator-delegation.md +2 -1
  4. package/assets/orchestrator.md +6 -10
  5. package/contracts/review-provider-contract-mirror/provider-contract.lock.json +8 -7
  6. package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/README.md +10 -0
  7. package/contracts/review-provider-contract-mirror/v1.2.0/bundle/manifest.json +74 -0
  8. package/contracts/review-provider-contract-mirror/v1.2.0/bundle/orchestration/pi.md +53 -0
  9. package/contracts/review-provider-contract-mirror/v1.2.0/bundle/schemas/targeted-validator.schema.json +1 -0
  10. package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/generated/provider-capabilities.baseline.json +9 -2
  11. package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/generated/provider-roles.baseline.json +2 -2
  12. package/docs/review-integration.md +1 -1
  13. package/extensions/gentle-ai.ts +530 -71
  14. package/lib/agent-home.ts +8 -0
  15. package/lib/native-review-cli.ts +15 -0
  16. package/lib/provider-contract-bundle.ts +88 -6
  17. package/lib/review-host-relay.ts +146 -60
  18. package/lib/review-integration-v2.ts +34 -5
  19. package/lib/sdd-preflight.ts +2 -2
  20. package/package.json +1 -1
  21. package/runtime/native-review-cli.mjs +15 -0
  22. package/runtime/review-integration-v2.mjs +34 -5
  23. package/scripts/gentle-ai-installer.mjs +10 -10
  24. package/scripts/verify-package-files.mjs +14 -13
  25. package/skills/_shared/review-ledger-contract.md +6 -0
  26. package/skills/issue-creation/SKILL.md +53 -93
  27. package/tests/fixtures/provider-contract-bundle/v1.2.0/README.md +22 -0
  28. package/{contracts/review-provider-contract-mirror/v1.1.0/bundle → tests/fixtures/provider-contract-bundle/v1.2.0}/manifest.json +11 -2
  29. package/tests/fixtures/provider-contract-bundle/v1.2.0/orchestration/pi.md +97 -0
  30. package/tests/fixtures/provider-contract-bundle/v1.2.0/schemas/lens.schema.json +16 -0
  31. package/tests/fixtures/provider-contract-bundle/v1.2.0/schemas/refuter.schema.json +1 -0
  32. package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/lens.json +1 -0
  33. package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/refuter.json +1 -0
  34. package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/targeted-validator.json +1 -0
  35. package/tests/gentle-ai-binary.test.ts +1 -1
  36. package/tests/gentle-ai-installer.test.ts +46 -46
  37. package/tests/gentle-ai.test.ts +3 -2
  38. package/tests/issue-creation-skill.test.ts +103 -0
  39. package/tests/native-review-capability-contract.test.ts +18 -1
  40. package/tests/orchestrator-budget.test.ts +2 -2
  41. package/tests/orchestrator-rdd-ownership.test.ts +1 -1
  42. package/tests/package-manifest.test.ts +123 -9
  43. package/tests/provider-contract-bundle.test.ts +76 -0
  44. package/tests/provider-contract-mirror.test.ts +19 -0
  45. package/tests/review-agent-end-preflight.test.ts +408 -0
  46. package/tests/review-contract-prompt.test.ts +139 -0
  47. package/tests/review-controller.test.ts +1 -1
  48. package/tests/review-host-relay-routing.test.ts +211 -9
  49. package/tests/review-host-relay.test.ts +195 -7
  50. package/tests/review-integration-v2-forward.test.ts +47 -0
  51. package/tests/review-ledger-contract.test.ts +1 -1
  52. package/tests/runtime-harness.mjs +1 -0
  53. package/tests/writer-edit-surface-scope.test.ts +153 -17
  54. /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/schemas/lens.schema.json +0 -0
  55. /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/schemas/refuter.schema.json +0 -0
  56. /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/lens.json +0 -0
  57. /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/refuter.json +0 -0
  58. /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/targeted-validator.json +0 -0
  59. /package/{contracts/review-provider-contract-mirror/v1.1.0/bundle → tests/fixtures/provider-contract-bundle/v1.2.0}/schemas/targeted-validator.schema.json +0 -0
@@ -184,6 +184,19 @@ const CAPABILITIES_SCHEMA_IDENTITIES
184
184
  requiredMandatoryFeatures: REQUIRED_MANDATORY_FEATURES_V23,
185
185
  optionalFeatureFloor: 14,
186
186
  }),
187
+ // Ground-truthed against the published v2.6.0 binary: capabilities/v2.5
188
+ // advertises the same required surface as v2.4 (status/v6 is still
189
+ // advertised for compatibility) plus the new status/v7 schema, which is a
190
+ // superset-checked addition, not a requirement -- decodeReviewStatusV3
191
+ // accepts v7 as an additive extension of v6, so the required-schema floor
192
+ // stays unchanged. The v2.6.0 binary advertised 15 optional features
193
+ // (floor stays at 14, its established minimum).
194
+ "gentle-ai.review-integration.capabilities/v2.5": Object.freeze({
195
+ protocolMinor: 5,
196
+ requiredSchemas: Object.freeze([...REQUIRED_SCHEMAS_COMMON_V23, "gentle-ai.review-integration.capabilities/v2.5", "gentle-ai.review-integration.consent/v3", "gentle-ai.review-integration.start/v4", "gentle-ai.review-integration.status/v6", "gentle-ai.review-intended-untracked-selection/v1"]),
197
+ requiredMandatoryFeatures: REQUIRED_MANDATORY_FEATURES_V23,
198
+ optionalFeatureFloor: 14,
199
+ }),
187
200
  });
188
201
  const OPTIONAL_FEATURE_NAMES = Object.freeze([
189
202
  "base_ref_workspace_overlay",
@@ -597,6 +610,8 @@ export const REVIEW_PROVIDER_ROLE_CAPTURE_OPERATIONS = Object.freeze(Object.valu
597
610
 
598
611
 
599
612
 
613
+
614
+
600
615
 
601
616
 
602
617
 
@@ -1762,15 +1777,19 @@ export function decodeReviewStatusV3(value ) {
1762
1777
  // Additive forward acceptance: status/v5 (gentle-ai main; ground-truthed
1763
1778
  // against a live capture and the vendored status-v5.schema.json) is the v3
1764
1779
  // key set plus the optional forecast and the v5-only next_transition
1765
- // surfaces. status/v6 adds the intended-untracked selection; v3 keeps
1766
- // rejecting every v5/v6-only field.
1780
+ // surfaces. status/v6 adds the intended-untracked selection; status/v7
1781
+ // (gentle-ai v2.6.0, advertised through capabilities/v2.5 alongside v6)
1782
+ // adds only the top-level optional `eligible_untracked_inventory` digest,
1783
+ // so it is decoded on the v6 surface. v3 keeps rejecting every v5/v6/v7-only
1784
+ // field.
1767
1785
  const schema = typeof value === "object" && value !== null ? (value ).schema : undefined;
1768
- const v6 = schema === "gentle-ai.review-integration.status/v6";
1786
+ const v7 = schema === "gentle-ai.review-integration.status/v7";
1787
+ const v6 = v7 || schema === "gentle-ai.review-integration.status/v6";
1769
1788
  const v5 = v6 || schema === "gentle-ai.review-integration.status/v5";
1770
1789
  const body = exactRecord(value, "status", [
1771
1790
  "schema", "contract", "operation", "applicability", "action", "replayability", "target_identity", "projection", "repair", "candidates",
1772
- ], ["authority", "frozen", "action_disposition", "eligibility", "next_transition", "authority_target_identity", ...(v5 ? ["receipt", "forecast", "repository_context", "validation_request"] : [])]);
1773
- requireIdentity(body, v6 ? "gentle-ai.review-integration.status/v6" : v5 ? "gentle-ai.review-integration.status/v5" : "gentle-ai.review-integration.status/v3", REVIEW_INTEGRATION_OPERATION.STATUS);
1791
+ ], ["authority", "frozen", "action_disposition", "eligibility", "next_transition", "authority_target_identity", ...(v5 ? ["receipt", "forecast", "repository_context", "validation_request"] : []), ...(v7 ? ["eligible_untracked_inventory"] : [])]);
1792
+ requireIdentity(body, v7 ? "gentle-ai.review-integration.status/v7" : v6 ? "gentle-ai.review-integration.status/v6" : v5 ? "gentle-ai.review-integration.status/v5" : "gentle-ai.review-integration.status/v3", REVIEW_INTEGRATION_OPERATION.STATUS);
1774
1793
 
1775
1794
  const applicability = enumeration(body.applicability, ["current_target", "unrelated", "ambiguous", "corrupted"] , "status.applicability");
1776
1795
  let receipt ;
@@ -1852,6 +1871,15 @@ export function decodeReviewStatusV3(value ) {
1852
1871
  };
1853
1872
  }
1854
1873
 
1874
+ // status/v7 top-level optional digest (gentle-ai v2.6.0): resolves #4066's
1875
+ // closed loop where `sdd-attempt finish` named a digest status never
1876
+ // published. Absent on the `staged` projection, which never resolves an
1877
+ // inventory, so it stays structurally optional rather than a required v7
1878
+ // field.
1879
+ const eligibleUntrackedInventory = v7 && body.eligible_untracked_inventory !== undefined
1880
+ ? sha256(body.eligible_untracked_inventory, "status.eligible_untracked_inventory")
1881
+ : undefined;
1882
+
1855
1883
  return {
1856
1884
  contract: REVIEW_INTEGRATION_CONTRACT,
1857
1885
  applicability,
@@ -1870,6 +1898,7 @@ export function decodeReviewStatusV3(value ) {
1870
1898
  ...(forecast === undefined ? {} : { forecast }),
1871
1899
  ...(repositoryContext === undefined ? {} : { repositoryContext }),
1872
1900
  ...(validationRequest === undefined ? {} : { validationRequest }),
1901
+ ...(eligibleUntrackedInventory === undefined ? {} : { eligibleUntrackedInventory }),
1873
1902
  raw: body,
1874
1903
  };
1875
1904
  }
@@ -36,7 +36,7 @@ const WINDOWS_SYSTEM_ROOT = "C:\\Windows";
36
36
  // version check below) derives from this constant instead of repeating the
37
37
  // literal, so a pin bump cannot leave a stale copy behind. See
38
38
  // scripts/install-gentle-ai.mjs for the incident that motivated this.
39
- export const INSTALLER_VERSION = "2.5.0";
39
+ export const INSTALLER_VERSION = "2.6.0";
40
40
  export const RELEASE_BASE_URL = `https://github.com/Gentleman-Programming/gentle-ai/releases/download/v${INSTALLER_VERSION}/`;
41
41
  export const GENTLE_AI_INSTALL_METHOD = Object.freeze({
42
42
  SIGNED_RELEASE_ASSET: "signed-release-asset",
@@ -45,10 +45,10 @@ export const GENTLE_AI_INSTALL_METHOD = Object.freeze({
45
45
  export const GENTLE_AI_WINDOWS_SOURCE_PACKAGE_PATH = "github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai";
46
46
  export const GENTLE_AI_WINDOWS_SOURCE_MODULE = "github.com/gentleman-programming/gentle-ai/v2";
47
47
  export const GENTLE_AI_WINDOWS_SOURCE_TAG = `v${INSTALLER_VERSION}`;
48
- // `go mod download -json github.com/gentleman-programming/gentle-ai/v2@v2.5.0`
48
+ // `go mod download -json github.com/gentleman-programming/gentle-ai/v2@v2.6.0`
49
49
  // with GOSUMDB=sum.golang.org reports this exact module SumDB checksum, and the
50
- // tag resolves to commit f5dd1a6c, the published v2.5.0 release head.
51
- export const GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:0nvTLJFAf9ruBDwTvi+aDrWt/dt/GKvUP2cFVB6c2DI=";
50
+ // tag resolves to commit c24a724a, the published v2.6.0 release head.
51
+ export const GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:scGoZYnPHh4oCVqlcfQAOSpm22Ii5lmB0kBbiBKvNZk=";
52
52
  export const GENTLE_AI_WINDOWS_SOURCE_PACKAGE = `${GENTLE_AI_WINDOWS_SOURCE_PACKAGE_PATH}@${GENTLE_AI_WINDOWS_SOURCE_TAG}`;
53
53
  export const GENTLE_AI_WINDOWS_MINIMUM_GO_VERSION = "1.25.10";
54
54
  export const GENTLE_AI_GO_TOOLCHAIN_UNAVAILABLE_CODE = "GENTLE_AI_GO_TOOLCHAIN_UNAVAILABLE";
@@ -67,7 +67,7 @@ export class GentleAiInstallerError extends Error {
67
67
  // Sentinel used while a re-pinned gentle-ai release is not yet published. A
68
68
  // sentinel digest can never match a real SHA-256, so installation fails closed,
69
69
  // and verify-package-files.mjs refuses to pack/publish while any digest below
70
- // still holds it. The v2.5.0 digests are pinned from the published release:
70
+ // still holds it. The v2.6.0 digests are pinned from the published release:
71
71
  // archive sha256 values verified against the minisign-signed checksums.txt and
72
72
  // freshly computed hashes; binary sha256 values computed from the extracted
73
73
  // executables.
@@ -109,15 +109,15 @@ async function downloadPinnedGentleAiAsset(asset, destination, options) {
109
109
  }
110
110
 
111
111
  // Windows is absent from signed release archives on purpose. gentle-ai stopped
112
- // distributing unsigned Windows builds in c4b764d0, so v2.5.0 publishes signed
112
+ // distributing unsigned Windows builds in c4b764d0, so v2.6.0 publishes signed
113
113
  // Darwin/Linux archives only. Windows x64/arm64 uses the separately verified
114
114
  // exact-tag Go SumDB source-build path below; restore archive rows only when
115
115
  // upstream ships signed Windows assets.
116
116
  export const GENTLE_AI_RELEASE_ASSETS = Object.freeze({
117
- "darwin/amd64": asset("gentle-ai_2.5.0_darwin_amd64.tar.gz", "8204ed692d7ff16fae2eb8bd7b3132b5e4e4dd7b9ea40e93bfced57394da27c0", "929817d320e94ad62be7ed546ad8746e62bd63ab97e3f38c94456f221f163eca", "gentle-ai"),
118
- "darwin/arm64": asset("gentle-ai_2.5.0_darwin_arm64.tar.gz", "ce06831cea9fd2ac7b2b36d9e98e63988246e0fbafbbd2cc7c003ec2f1463a23", "c859cd88138eb41e83ef9b75309697aaff2acb9f720c9a029b432095f66aea02", "gentle-ai"),
119
- "linux/amd64": asset("gentle-ai_2.5.0_linux_amd64.tar.gz", "2ba84a3a7ba2b1193019bde2acb05b02cbf222b667568c919686352b3caab113", "5acedd14b7927a7665636bf728c14a614597ce85dd91313bc50cbc96881c6cab", "gentle-ai"),
120
- "linux/arm64": asset("gentle-ai_2.5.0_linux_arm64.tar.gz", "16a6243d17c146e3fc0024f6f005c5bd141fbb2dda4b56e269318e499ddc170b", "ce75ba1174955813ef462f4e7a50dd59a8e8167575033f6e17aa8d8488630cb8", "gentle-ai"),
117
+ "darwin/amd64": asset("gentle-ai_2.6.0_darwin_amd64.tar.gz", "e09389a4fa2de6a1999cf44bb7850d1f8bc166f330010b64c20aaab32bc68cb7", "a142e166a7638b1d9920ec01be2417a0257c52074395ed829bf5b989199b3f03", "gentle-ai"),
118
+ "darwin/arm64": asset("gentle-ai_2.6.0_darwin_arm64.tar.gz", "9999842e0ccb769101d51454b714f599535c551cde73411a1f72936ff635c13e", "ddc9ffb6aa64268f8de8ffe80056b58b97e3cf480dea849c38d97d7c2b2618f4", "gentle-ai"),
119
+ "linux/amd64": asset("gentle-ai_2.6.0_linux_amd64.tar.gz", "1dbf4e4ebc2b0d0e0f3f003a77ca2cf0fedc7b4d3e5f85939abeb877694630f0", "37e4ef32e869fa181b77346be160dfef35ff6fa40f26723d6dcd705ffb6d385d", "gentle-ai"),
120
+ "linux/arm64": asset("gentle-ai_2.6.0_linux_arm64.tar.gz", "9fc43679476486fb234c302c91f8e15fd7d878e43de1104c2ebdddd68baaa95b", "7ff61e615fe861fd1175bb9750b4c15c23dcdfeaa4a7ed0a96d5ec2bdf39e72f", "gentle-ai"),
121
121
  });
122
122
 
123
123
  // A pinned asset is either a signed archive or, for a prerelease pin only,
@@ -80,16 +80,17 @@ const requiredPaths = [
80
80
  // exact bytes are pinned by the lock-driven scripts/check-provider-contract.mjs
81
81
  // drift check, which runs in the same pnpm test flow.
82
82
  "contracts/review-provider-contract-mirror/provider-contract.lock.json",
83
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/README.md",
84
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/manifest.json",
85
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/lens.schema.json",
86
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/refuter.schema.json",
87
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/schemas/targeted-validator.schema.json",
88
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/lens.json",
89
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/refuter.json",
90
- "contracts/review-provider-contract-mirror/v1.1.0/bundle/vectors/targeted-validator.json",
91
- "contracts/review-provider-contract-mirror/v1.1.0/generated/provider-capabilities.baseline.json",
92
- "contracts/review-provider-contract-mirror/v1.1.0/generated/provider-roles.baseline.json",
83
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/README.md",
84
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/manifest.json",
85
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/orchestration/pi.md",
86
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/schemas/lens.schema.json",
87
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/schemas/refuter.schema.json",
88
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/schemas/targeted-validator.schema.json",
89
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/vectors/lens.json",
90
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/vectors/refuter.json",
91
+ "contracts/review-provider-contract-mirror/v1.2.0/bundle/vectors/targeted-validator.json",
92
+ "contracts/review-provider-contract-mirror/v1.2.0/generated/provider-capabilities.baseline.json",
93
+ "contracts/review-provider-contract-mirror/v1.2.0/generated/provider-roles.baseline.json",
93
94
  "prompts/skill-creation.md",
94
95
  "skills/_shared/review-ledger-contract.md",
95
96
  "skills/branch-pr/SKILL.md",
@@ -175,7 +176,7 @@ const contractHashes = {
175
176
  "contracts/review-integration/v2/schemas/repair.schema.json": "98a85fd45a8ae7f6211ffeeb3f9c478fa1dd1c17f385751f15f2111e6c3ab167",
176
177
  "contracts/review-integration/v2/schemas/start.schema.json": "2991e3fcca672d9257d61b6a336fb34e58b15a8e03f8a09a7adf892cae6a8085",
177
178
  "contracts/review-integration/v2/schemas/status.schema.json": "c4dcc736cfc6300560a3c4262d2d982368529d5c49d58d499552a3b0beef9212",
178
- "docs/review-integration.md": "0a2a415e8bd24be61f5c6090bd0efccde0ed1b4561261be11bba197aa081f336",
179
+ "docs/review-integration.md": "95a3df92785bc4d9f3b99e702aaf817ae0440bd16c83218d2c3f2aca67c280fb",
179
180
  };
180
181
 
181
182
  requiredPaths.push(...Object.keys(contractHashes));
@@ -333,7 +334,7 @@ async function main() {
333
334
  });
334
335
 
335
336
  if (driftedContracts.length > 0) {
336
- console.error("gentle-pi packaged review-integration/v1 and review-integration/v2 contract bytes drifted from the pinned v2.5.0 runtime's vendored Gentle AI contract artifacts:");
337
+ console.error("gentle-pi packaged review-integration/v1 and review-integration/v2 contract bytes drifted from the pinned v2.6.0 runtime's vendored Gentle AI contract artifacts:");
337
338
  for (const drift of driftedContracts) console.error(`- ${drift.relativePath}: expected ${drift.expected}, got ${drift.actual}`);
338
339
  process.exit(1);
339
340
  }
@@ -378,7 +379,7 @@ async function main() {
378
379
  process.exit(1);
379
380
  }
380
381
 
381
- console.log(`gentle-pi package resource check passed (${requiredPaths.length} files; ${Object.keys(contractHashes).length} exact byte-pinned contract artifacts for the v2.5.0 runtime).`);
382
+ console.log(`gentle-pi package resource check passed (${requiredPaths.length} files; ${Object.keys(contractHashes).length} exact byte-pinned contract artifacts for the v2.6.0 runtime).`);
382
383
  }
383
384
 
384
385
  const isMainModule = process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href;
@@ -24,6 +24,12 @@ Before status/START, consult effective review mode. `off` creates no authority o
24
24
 
25
25
  Reviewer, refuter, and validator verdicts are admitted natively, never Pi-authored. `finalize` follows the provider's negotiated `next_transition` and supplies only the negotiated collection answers: a lens `review.capture-result` collect input rendered with `--agent=pi --materialize=true` is satisfied by the gentle-pi host relay, which prints the exact Go-materialized opaque prompt, launches a fresh locked-down print-mode `pi` subprocess in an empty scratch directory with every discovery surface disabled, and submits the untouched raw output bytes through the provider-owned submission form. The adversarial roles do not go through that relay: `review.capture-refuter` and `review.capture-validation` collect inputs render as self-contained authority-advancing vectors (binding tokens plus `--agent=pi --execute=true`, no submission descriptor); executing the exact rendered invocation makes Go materialize the role prompt, spawn its own locked-down `pi` process, and admit the raw verdict. Native Go owns validation, canonicalization, missing lens/finding ID assignment, persistence, and hashing, and performs only the legal transition from the current compact state. The five states are `reviewing`, `correction_required`, `validating`, `approved`, and `escalated`.
26
26
 
27
+ ### Concurrent Reviewer Group (MANDATORY)
28
+
29
+ When one fresh `collect.inputs` set contains multiple distinct independent `review.capture-result` reviewer slots, call `gentle_review_capture_group` once with the complete ordered provider bindings and its forecast acknowledgement. Before any materialization it validates the whole current group, its common binding fields, unique slot identities, and every provider submission descriptor; then it starts all reviewers before waiting. For canonical 4R, preserve `review-risk`, `review-resilience`, `review-readability`, `review-reliability` order.
30
+
31
+ Each grouped launch runs only its own provider-issued `review.capture-result` binding, and admission remains in provider order. A typed terminal or nonterminal closure returns directly; a later stop after earlier admission reports bounded partial progress and never claims no mutation. If every submission returns without closure, reconcile fresh bound STATUS and return its declared action rather than inferring group success. On `correction_required`, continue only through exact bound STATUS and the provider-issued `review.capture-correction-plan` binding.
32
+
27
33
  `validate` is informational and runs with zero actors. It never mutates compact authority or controls delivery.
28
34
 
29
35
  ## Causal findings
@@ -4,18 +4,14 @@ description: "Create and triage GitHub issues from repository evidence. Trigger:
4
4
  license: Apache-2.0
5
5
  metadata:
6
6
  author: gentleman-programming
7
- version: "1.2"
7
+ version: "1.3"
8
8
  ---
9
9
 
10
10
  # Issue Creation
11
11
 
12
- ## When To Use
13
-
14
- Use this skill when creating, drafting, triaging, or approving an issue in the current GitHub repository.
15
-
16
12
  ## Core Rule
17
13
 
18
- Discover the repository's actual contribution workflow before proposing or publishing an issue. Templates, labels, approval gates, and Discussions support are repository policy, not universal GitHub behavior.
14
+ Discover the target repository's contribution workflow before proposing or publishing. YAML Issue Forms are the format authority for the default automated path: materialize reviewed answers into a private `BODY_FILE` and publish with `--body-file`.
19
15
 
20
16
  ## Safe Discovery
21
17
 
@@ -27,123 +23,87 @@ REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
27
23
  REPO_URL="$(gh repo view --json url -q .url)"
28
24
  HOST="${REPO_URL#*://}"
29
25
  HOST="${HOST%%/*}"
26
+ TARGET="$HOST/$REPO"
30
27
  gh repo view --json nameWithOwner,url,hasDiscussionsEnabled,hasIssuesEnabled,isBlankIssuesEnabled
31
- git ls-files CONTRIBUTING.md CONTRIBUTING.* .github/CONTRIBUTING.md .github/ISSUE_TEMPLATE
28
+ git ls-files README.md CONTRIBUTING.md CONTRIBUTING.* .github/CONTRIBUTING.md .github/ISSUE_TEMPLATE .github/ISSUE_TEMPLATE/config.yml
32
29
  gh api --hostname "$HOST" --paginate "repos/$REPO/labels?per_page=100" --jq '.[].name'
33
30
  ```
34
31
 
35
- Also inspect:
36
-
37
- - repository instructions such as `CONTRIBUTING.md` and `README.md`;
38
- - files under `.github/ISSUE_TEMPLATE`;
39
- - `.github/ISSUE_TEMPLATE/config.yml` when present;
40
- - issue forms, required fields, and labels declared by each template;
41
- - existing open and closed issues for duplicates and established wording.
32
+ Inspect `README.md`, contribution instructions, `.github/ISSUE_TEMPLATE/config.yml` contact links, forms, labels, and open and closed issues. For questions/support, follow repository-prescribed Discussions/contact routing when available; otherwise ask or stop. Complete target verification for `REPO`, `HOST`, and `TARGET`. Fail closed before mutation when authentication, target verification, issue availability, policy, form selection, or required metadata is missing or ambiguous. A blank fallback is allowed only when `isBlankIssuesEnabled` is explicitly true.
42
33
 
43
- Stop and ask for repository context if authentication, repository resolution, verification that REPO and HOST are non-empty, required metadata is unavailable, hasIssuesEnabled is false, or policy discovery fails. Never continue from failed discovery into issue publication.
44
-
45
- A no-template fallback is allowed only when isBlankIssuesEnabled is explicitly true. Otherwise follow discovered contact links or stop and ask; never publish.
46
-
47
- After discovery and review, build optional label arguments using only labels that exist and repository policy permits the actor to apply:
34
+ Build `LABEL_ARGS` only from reviewed labels that exist and policy permits the actor to apply:
48
35
 
49
36
  ```bash
50
37
  LABEL_ARGS=()
51
- # Repeat for each reviewed, permitted discovered label.
52
- LABEL_ARGS+=(--label "$LABEL")
38
+ LABEL_ARGS+=(--label "$LABEL") # Repeat only for each permitted discovered label.
53
39
  ```
54
40
 
55
- An empty array applies no label; do not invent labels.
56
-
57
- ## Workflow
41
+ ## Duplicate And Form Decision
58
42
 
59
- 1. Describe the problem or request in one sentence and derive a short search query.
60
- 2. Search open and closed issues:
43
+ 1. Describe the report in one sentence, derive `QUERY`, then complete one duplicate search across open and closed issues:
61
44
 
62
45
  ```bash
63
- gh issue list --repo "$HOST/$REPO" --state all --search "$QUERY" --limit 1000
46
+ gh issue list --repo "$TARGET" --state all --search "$QUERY" --limit 1000
64
47
  ```
65
48
 
66
- If 1000 results are returned or completeness remains uncertain, narrow the search, use read-only API discovery, or stop and ask before publishing.
67
-
68
- 3. If an issue already covers the same behavior, comment there instead of creating a duplicate.
69
- 4. Choose a repository-provided template only when its purpose matches the report.
70
- 5. Fill every required template field from known evidence. Ask for missing facts rather than inventing them.
71
- 6. Apply labels only when they exist and repository guidance establishes who should apply them.
72
- 7. Publish only after the title, body, target repository, and selected template or fallback have been reviewed, and the pre-submission privacy review below has passed.
73
-
74
- ## Pre-submission Privacy Review
75
-
76
- Pre-submission privacy review is mandatory. Scan every issue body immediately before `gh issue create`. The scan replaces — never deletes — environment-specific data with explicit placeholders so the reproduction still teaches:
77
-
78
- | Category | Replace with | Example (before → after) |
79
- |----------|---------------|---------------------------|
80
- | Private project names | `<project-name>` | `my-private-project-b` → `<project-name>` |
81
- | Usernames | `<user>` | `C:\Users\my-real-username\go\bin` → `C:\Users\<user>\go\bin` |
82
- | Hostnames | `<hostname>` | `devbox-macbook.local` → `<hostname>` |
83
- | Home paths | `/home/<user>` or `C:\Users\<user>` | (covered above) |
84
- | API keys, tokens, passwords | `<token>` / `<password>` | `ghp_abc123...` → `<token>` |
85
- | Internal ports / hostnames | `<host>:<port>` | `10.0.0.42:5432` → `<host>:<port>` |
86
-
87
- Do NOT redact intentionally public identifiers: tool names (`gentle-ai`, `engram`, `go`, `node`, `python`), package names, public documentation URLs, generic example domains (`example.com`, `localhost`). Keep reproduction structure with placeholders — never redact an example into nothingness.
88
-
89
- **Rule of thumb:** if the reader can run the reproduction step after you replace every identifier with its placeholder, the sanitization is correct. If a step becomes impossible (because the placeholder consumed a needed value), that step needs the value — and you should mark it `<value-required>` and explain in the body what the user should fill in.
49
+ If results are saturated or completeness is uncertain, narrow the read-only search or stop. Comment on a confirmed duplicate instead of creating one. Before commenting on a confirmed duplicate, perform the same privacy scan/redaction on the exact comment body as for publication.
50
+ 2. Select one repository-provided form only when its declared purpose matches. If multiple forms match and policy does not distinguish them, stop and request that decision.
51
+ 3. For a YAML form, read its schema and establish controls in declared order. Support only `input`, `textarea`, `dropdown`, and `checkboxes`. Markdown controls are non-answer guidance: honor their visible instructions when collecting and materializing adjacent answers, but do not render them as response sections. Fail closed before mutation on malformed, unsupported, missing, or ambiguous required structure or answers. A malformed schema, or missing or ambiguous required answers, fail closed: do not open a browser or mutate. A browser handoff is available only when the user explicitly requests browser completion or a syntactically valid selected form cannot safely/faithfully be represented by the automated path; otherwise report why automation is unsafe and stop.
90
52
 
91
- ## Template Paths
53
+ | Control | Required handling |
54
+ | --- | --- |
55
+ | `input` / `textarea` | Preserve the visible label. Require an answer when `validations.required` is true; otherwise render `_No response_`. |
56
+ | `dropdown` | Preserve visible labels and options. Require exact selected option text; single-select has one selection, and multi-select preserves selections in declared options order. A required dropdown needs at least one valid selection; an optional dropdown with no selection renders `_No response_`. |
57
+ | `checkboxes` | Preserve the visible label and every option as `- [x]` or `- [ ]` in declared order. Enforce individually required checkboxes and require explicit first-person affirmation for first-person option text. |
92
58
 
93
- Do not guess a template filename. If multiple templates could apply and repository guidance does not distinguish them, stop and ask which one to use.
59
+ For each answer, render `### <visible label>` followed by its materialized value. For `textarea.attributes.render`, fence the answer with the declared language and a fence long enough for its content. Never invent answers, selections, confirmations, or labels.
94
60
 
95
- - .yml and .yaml files are GitHub Issue Forms. Do not parse or render their schema. Open the web issue chooser and stop for human completion:
61
+ A Markdown template may be completed only from known evidence into the same private `BODY_FILE`. If no matching template exists, use the reviewed structured blank fallback only when blank issues are explicitly enabled; otherwise stop without publishing.
96
62
 
97
- ```bash
98
- gh issue create --repo "$HOST/$REPO" --web "${LABEL_ARGS[@]}"
99
- ```
63
+ ## Review And Publication
100
64
 
101
- - .md files are Markdown templates. Read the matching template, complete it from known evidence into a reviewed BODY_FILE, then publish it:
65
+ Before the single create attempt, review the target, title, selected form or permitted fallback, exact body, and permitted labels. Perform a privacy scan immediately before publication: replace private project names, usernames, hostnames, home paths, credentials, and private network addresses with useful placeholders without removing reproduction structure.
102
66
 
103
- ```bash
104
- gh issue create --repo "$HOST/$REPO" --title "$TITLE" --body-file "$BODY_FILE" "${LABEL_ARGS[@]}"
105
- ```
106
-
107
- ## No-Template Fallback
108
-
109
- When the repository permits issue creation, provides no matching template, and isBlankIssuesEnabled is explicitly true, prepare a structured body with these sections:
110
-
111
- - problem or requested outcome;
112
- - reproduction or motivating example;
113
- - expected behavior;
114
- - actual behavior or current limitation;
115
- - environment and relevant evidence;
116
- - alternatives or workarounds, when applicable.
117
-
118
- Publish the reviewed fallback explicitly:
67
+ Create one owner-only temporary directory outside the repository for both private files; restrict it to the current user and clean up both files on every exit/outcome:
119
68
 
120
69
  ```bash
121
- gh issue create --repo "$HOST/$REPO" --title "$TITLE" --body "$BODY" "${LABEL_ARGS[@]}"
70
+ umask 077
71
+ REPO_ROOT="$(git rev-parse --show-toplevel)" || exit 1
72
+ REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)" || exit 1
73
+ if [ "$REPO_ROOT" = "/" ]; then
74
+ printf '%s\n' "Temporary directory is inside the repository" >&2; exit 1
75
+ fi
76
+ TMP_DIR="$(TMPDIR=/tmp mktemp -d /tmp/gentle-ai-issue.XXXXXXXX)" || exit 1
77
+ trap 'rm -rf -- "$TMP_DIR"' EXIT
78
+ TMP_DIR_REAL="$(cd "$TMP_DIR" && pwd -P)" || exit 1
79
+ case "$TMP_DIR_REAL/" in
80
+ "$REPO_ROOT/"*) printf '%s\n' "Temporary directory is inside the repository" >&2; exit 1 ;;
81
+ esac
82
+ chmod 700 "$TMP_DIR_REAL"
83
+ BODY_FILE="$TMP_DIR_REAL/body.md"
84
+ READBACK_FILE="$TMP_DIR_REAL/readback.json"
122
85
  ```
123
86
 
124
- If blank issues are not explicitly enabled, follow discovered contact links or stop and ask. Never publish a no-template fallback.
125
-
126
- ## Labels And Approval
87
+ Make one mutation attempt through the automated path and publish exactly once:
127
88
 
128
- Treat labels and approval gates as conditional:
89
+ ```bash
90
+ gh issue create --repo "$TARGET" --title "$TITLE" --body-file "$BODY_FILE" "${LABEL_ARGS[@]}"
91
+ ```
129
92
 
130
- - use only labels returned by repository discovery;
131
- - follow contribution guidance for who may apply each label;
132
- - wait when repository policy requires maintainer approval before implementation;
133
- - do not invent a status or priority taxonomy when none is documented.
93
+ When browser completion is available under the form decision above, an optional, separate browser handoff may open the repository form. It is never proof of publication and is never a response to malformed schemas or missing/ambiguous required answers:
134
94
 
135
- ## Questions And Discussions
95
+ ```bash
96
+ gh issue create --repo "$TARGET" --web
97
+ ```
136
98
 
137
- Use Discussions only when `hasDiscussionsEnabled` is true and repository guidance routes the question there. Otherwise follow documented support/contact links or ask the user where the question belongs. Never link to another repository's Discussions page.
99
+ Do not retry a timeout, network failure, missing identity, or other uncertain result. Capture the returned issue number, then read it back from the verified target host before reporting success:
138
100
 
139
- ## Triage Decision
101
+ ```bash
102
+ gh issue view "$NUMBER" --repo "$TARGET" --json number,url,title,body,state,labels >"$READBACK_FILE"
103
+ ```
140
104
 
141
- Before approving or closing an issue, verify:
105
+ Confirm that read-back identifies the target-host issue and that title and body match after only CRLF-to-LF and trailing-final-newline normalization. Report `confirmed` only after this target-host read-back. Otherwise report `no_write` when an authoritative rejection proves no issue was created, or `unknown` and stop all later mutations.
142
106
 
143
- - it describes a concrete bug or scoped improvement rather than an unsupported question;
144
- - it is not a duplicate;
145
- - the report contains enough evidence for an implementation decision;
146
- - the requested behavior is in repository scope;
147
- - labels and status changes follow the current repository's policy.
107
+ ## Triage
148
108
 
149
- If any point is uncertain, keep the issue in the repository's review state and request the smallest missing evidence.
109
+ Before approving or closing an issue, verify it is concrete, non-duplicate, sufficiently evidenced, in scope, and consistent with repository label/status policy. If any point is uncertain, retain the repository review state and request the smallest missing evidence.
@@ -0,0 +1,22 @@
1
+ # Gentle AI review provider contract
2
+
3
+ This data-only bundle describes the provider result contracts admitted by Gentle AI.
4
+
5
+ ## Activation
6
+
7
+ 1. Verify the signed release checksum manifest before using this archive.
8
+ 2. Verify every listed file hash and the transport capability before activation.
9
+ 3. Confirm your runtime identity appears in the manifest's registered runtimes before trusting the layout.
10
+ 4. Pass the Go-materialized opaque prompt to the provider and return only raw output or an error.
11
+
12
+ ## Orchestration
13
+
14
+ manifest.json's orchestration array lists, for closed runtimes only, one
15
+ orchestration/<runtime>.md file: the exact review execution contract text
16
+ Gentle AI's own installer would have spliced into that runtime's system
17
+ prompt, for a runtime whose adapter has no system prompt to splice it into.
18
+ It carries no executable content, same as every other file in this bundle: a
19
+ runtime mirrors and delivers the text as-is and still relies on Go for every
20
+ review decision, prompt, receipt, and delivery gate.
21
+
22
+ Go remains the admission authority for prompts, results, receipts, and delivery gates.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "gentle-ai.review-provider-contract-bundle/v1",
3
- "contract_semver": "1.1.0",
3
+ "contract_semver": "1.2.0",
4
4
  "transport_capability": "gentle-ai.provider-transport/v1",
5
5
  "runtimes": [
6
6
  "claude-code",
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "readme": {
12
12
  "path": "README.md",
13
- "sha256": "d14647c8753bd85e18b8a593bef9dfcb4c9d8ea01e32ecd36847dc4304027b1d"
13
+ "sha256": "18baab5ee79aefd0bc62a28da0dadcf2162544f57a940c5b859cd6bc4932a085"
14
14
  },
15
15
  "roles": [
16
16
  {
@@ -61,5 +61,14 @@
61
61
  "sha256": "7b5a5165e3a913863fb98d2ba5387811860c21333b5c37e6ed3b4e0d121cf2fa"
62
62
  }
63
63
  }
64
+ ],
65
+ "orchestration": [
66
+ {
67
+ "runtime": "pi",
68
+ "file": {
69
+ "path": "orchestration/pi.md",
70
+ "sha256": "54fba57b11b280f56f7f15e91ddad3d844c70e0127e5c1adeff0a9d1b7a98e64"
71
+ }
72
+ }
64
73
  ]
65
74
  }
@@ -0,0 +1,97 @@
1
+ # Native Compact Review Orchestration
2
+
3
+ **When a final capture returns `status_continuation`, execute its operation and ordered argument tokens unchanged. Do not reconstruct lifecycle selectors from retained prose or transcript state.**
4
+
5
+ The parent orchestrator coordinates one native transaction; reviewers, refuters, correction actors, and validators receive only their provider-issued role input. Prompt prose never creates authority or decides delivery.
6
+
7
+ ## Entry rule
8
+
9
+ Enter this lifecycle once per candidate, after an authorized source-mutating implementation is complete and normalized and before reporting it complete, whenever the user-owned review switch is enabled (`gentle-ai review mode status` reads it without changing it). Run the selectorless STATUS in step 1 and route only from its returned `next_transition`; the START consent envelope lets the human decide this candidate, so never skip the preflight because the user did not ask for a review. Skip it only for a trivial passive documentation-only edit, when the user explicitly left this candidate unreviewed, or while a transaction is already bound to it. A runtime that runs this preflight itself hands the agent the exact returned START tokens and never runs START.
10
+
11
+ ## Atomic lifecycle
12
+
13
+ 1. **Preflight only.** Selectorless STATUS only preflights the current worktree candidate and returns one exact START invocation. It never discovers, resumes, recovers, or evaluates ambient authority from another lineage or worktree: `gentle-ai review status --cwd <repo> --contract gentle-ai.review-integration/v2 --agent pi --next-transition`.
14
+
15
+ 2. **Freeze once.** Invoke only the returned START operation and its ordered tokens unchanged. START freezes one compact atomic transaction with an explicit lineage, worktree, and target binding. It ignores every other lineage and worktree. Capture the returned lineage, revision, and target tokens. An exact replay of an active START may return `replayed`; a genuinely new START is independent.
16
+
17
+ 3. **Stay bound.** A reviewing START carries `next_transition.execute(review.status)` — the provider-issued re-entry for its frozen binding: run that provider-issued command verbatim, with the repository as process cwd, and satisfy every later STATUS and collection call only with the exact tokens each returned transition names. Route only from that transaction's returned `next_transition`; the root `action` field is informational. Never infer a command from prose, ambient state, a gate, or a stale reply. Do not start another lineage, reuse an acknowledged-and-burned lineage, or perform ambient recovery. For `execute`, run the exact operation and ordered arguments. For `collect`, satisfy only the named inputs and their exact capture operations, then ask STATUS again with the same binding. For `stop`, run no lifecycle operation.
18
+
19
+ 4. **Acknowledge exactly.** Native Go owns frozen lenses, provider context and admission, refutation, one bounded correction, repository evidence, targeted validation, and approved closure. A final approved capture commits one pending acknowledgement token and returns `review.acknowledge-approved`; restarted STATUS returns the same operation, ordered arguments, token, and live revision. Only that exact invocation burns authority and artifacts, and on success it prints one `gentle-ai.review-acknowledged/v1` envelope; report the burn from that envelope, never from a later STATUS. Wrong, stale, or replayed acknowledgement refuses without creating a receipt, tombstone, witness, mirror, sidecar, or delivery authority. Unrelated transactions survive unchanged.
20
+
21
+ The final reviewer, refuter, or targeted-validator capture owns closure. A malformed, incomplete, or unavailable capture never reaches acknowledgement: issue one retained target-bound read-only STATUS and relaunch only when it reoffers the same bound slot. Never invent a binding or retry from prose.
22
+
23
+ When v2 returns `forecast`, relay it losslessly in the user's language: preserve every step's order and fields (`step`, `kind`, `reason_code`, `description`) and the horizon. Forecast is informational; route only from `next_transition`.
24
+
25
+ ### Cross-repository lifecycle root
26
+
27
+ A session in repository A may review an explicitly selected nested target in unrelated repository B only after explicit user authorization. Native Go resolves the requested path to the canonical B worktree root; adapters never parse authorization or roots.
28
+
29
+ - After B is selected, retain canonical B as the lifecycle working root from selectorless STATUS through consent, collection, correction, targeted validation, acknowledgement, and burn. Do not fall back to A.
30
+ - Run provider-issued command tokens exactly. Never append, remove, or rebuild provider-issued command tokens. When a command omits `--cwd`, run it with process cwd B.
31
+ - Opaque `repository_context` can capture or materialize from any process cwd, but the host still retains B for lifecycle continuity. Go owns repository binding; adapters never parse authorization or roots.
32
+ - The same lineage text in A and B is independent. Approval awaits acknowledgement in B; exact acknowledgement burns B only, and A remains untouched.
33
+
34
+ This lifecycle is rendered for exactly Claude Code, Codex, OpenCode, and Pi. Unsupported runtimes remain unavailable before repository or authority mutation.
35
+
36
+ ## Capture and correction
37
+
38
+ For each returned `review.capture-result` input, run the exact capture operation once. The reviewer prompt begins with the exact literal prefix `GENTLE_AI_REVIEW_BINDING ` (trailing space, never `=`), followed by one-line JSON assembled only from that input: `lineage`, `target`, `lens`, `order`, `revision` from `expected-revision`, `repository_context`, and `subject_hash` from `artifact_subject.subject_hash`; omit only provider-omitted fields. Return one JSON object that echoes `subject_hash`, reports completed inspection of every manifest path in order, and contains findings/evidence with severe evidence class and causality. Access failure is incomplete inspection, never completion.
39
+
40
+ After an empty, malformed, schema-invalid, access/provider-failed, or incomplete capture, query the same exact-lineage STATUS. Relaunch only if its fresh `next_transition` reoffers the same bound slot. Never infer a retry from transcript text. A relayed capture passes its result through `--input <path|->`, one per lens in lens order; BOM-less UTF-8 is required on Windows PowerShell 5.1. Tokens carrying `--agent` capture in process with no `--input`.
41
+
42
+ Only candidate-caused severe findings block. Pre-existing/base-only findings are follow-ups; unknown causality escalates. A deterministic blocker needs no refuter; inferential blockers share one read-only refuter batch. A four-lens review is long work: before its first lens, give one forecast covering four reviewer runs, the frozen correction budget, and the at-most-one bounded correction.
43
+
44
+ A correction is native-scoped. When the final reviewer or refuter capture opens `correction_required`, its `status_continuation` is the only re-entry: run its `review.status` operation and ordered tokens unchanged before acting again. Native Go maps edits only to corroborated frozen findings, owns repository evidence and the targeted validator, and permits at most one bounded correction. A validator that cannot inspect the immutable trees produced no verdict: surface one blocked human decision and submit nothing. Do not route it to a refuter or another actor without read-only immutable-tree access. Independent requirements/runtime verification never starts another reviewer, refuter, correction, or validator.
45
+
46
+ ## Consent and immutable inspection
47
+
48
+ If exact provider-returned START returns the typed `gentle-ai.review-integration.consent/v3` envelope, relay it as a Lossless Blocking Prompt. Global RDD enabled permits review; it never grants consent for this candidate. For medium/high candidates, faithfully translate the headline, reason, `value`, risk evidence, choice labels, every choice `effect`, and the off-path note while preserving original groups/order, selection mode, allowed-answer domain, answer tokens, commands, target IDs, and invocations. Project `value` as benefits and every `effect` as consequences. Do not translate machine answer tokens (`granted`, `declined`). Run exactly the invocation selected by the human; a decline is candidate-scoped and is not the kill switch.
49
+
50
+ Claude Code, OpenCode, Codex, and Pi use the shared Go provider contract. Go owns frozen evidence, binding, schema, byte bounds, validation, admission, and capture; runtime adapters transport opaque provider output. Claude uses a tool-free fresh reviewer; OpenCode relays one host Task through its live Go transport; Codex uses its provider-bound subprocess; Pi uses its gentle-pi-owned relay. Compiled capability is authoritative before repository, target, authority, collection, or process work.
51
+
52
+ Reviewers inspect only the provider-bound immutable trees. Never hand candidate bytes through `/tmp`, an external file, a repository scratch file, or `GENTLE_AI_FROZEN_CANDIDATE_CONTEXT`. Use the provider-issued inspection path, never the live worktree, index, `HEAD`, or an unbound revision. Never pass `--binary`, change checkout, or substitute live files.
53
+
54
+ <!-- authority-first-terminal-procedure:start -->
55
+ ### Authority-First Terminal Procedure
56
+
57
+ | Order | Operation | Required result |
58
+ | --- | --- | --- |
59
+ | 01 | canonical initial STATUS above | exactly one current-worktree START preflight; no authority discovery |
60
+ | 02 | exact returned START | one compact lineage/worktree/target binding; retain lineage, revision, and target |
61
+ | 03 | exact-lineage STATUS and collect | only returned transaction actions; no ambient resume, reuse, or delivery gate |
62
+ | 04 | final admitted capture | native readback, approved authority, and one exact acknowledgement continuation |
63
+ | 05 | STATUS restart + exact acknowledgement | replayed operation/token/revision; only exact acknowledgement burns authority |
64
+ | 06 | terminal lifecycle stop | ordinary repository policy owns any later delivery decision |
65
+
66
+ <!-- authority-first-terminal-procedure:end -->
67
+
68
+ ### Continue after a stop reason code
69
+
70
+ A `stop` ends its transition, never approves delivery. Complete atomic inventory: B stays target root; gates stay unmanaged. `D` means `gentle-ai review mode disable --scope clone --cwd <B>`; B ordinary policy decides delivery. `S` means re-query the exact captured target-root STATUS command with lineage and target.
71
+
72
+ | Reason codes | Continuation |
73
+ | --- | --- |
74
+ | `captured_artifacts_unverifiable` | Terminal — maintainer inspects B authority, or `D`. |
75
+ | `captured_result_selection_unavailable` | Terminal — maintainer inspects lineage, or `D`. |
76
+ | `missing_authority_binding` | Terminal — file a bounded defect with lineage, or `D`. |
77
+ | `corrupted_or_unverifiable_authority`, `manual_intervention_required`, `native_stop_required` | Terminal — maintainer inspects authority/lineage, or `D`. |
78
+ | `empty_base_diff_bootstrap_required` | Terminal — authorized empty-root bootstrap for a new target, or `D`. |
79
+ | `lens_context_budget_exceeded` | Terminal — reduce B scope and start a new transaction, or `D`. |
80
+ | `staged_workspace_overlay_recovery_unavailable` | Terminal — pass `--lineage <id>` to recover, or drop `--workspace-overlay` and start fresh; otherwise `D`. |
81
+ | `corrected_candidate_unavailable` | Change B correction candidate, then `S`; do not reuse the pre-correction target. |
82
+ | `recovery_scope_unchanged` | Change B target identity, then retry the exact returned `gentle-ai review recover`. |
83
+ | `rdd_disabled` | `--scope clone` only clears a clone-local off; `gentle-ai review mode enable --scope global`, then `S`. |
84
+
85
+ ## Delivery follows ordinary repository policy
86
+
87
+ Shipped `review validate` and gate commands are compatibility/informational only. They never discover authority or decide delivery: enabled gates return `invalidated/unmanaged`; disabled gates return `disabled/unmanaged`. They never allow, approve, block, commit, push, open a PR, or govern release.
88
+
89
+ After exact acknowledgement burns terminal `approved` authority, the review lifecycle stops. Commit, push, PR, and release remain separate human decisions under ordinary repository policy. A review outcome is informational and never authorizes delivery, including when the selected repository is B.
90
+
91
+ Historical compatibility commands may read older artifacts manually, but they are never the ordinary lifecycle and never restore delivery authority.
92
+
93
+ ### Concurrent Reviewer Group (MANDATORY)
94
+
95
+ When one fresh `collect.inputs` set contains multiple distinct independent `review.capture-result` reviewer slots, launch every returned capture operation concurrently in provider order: start all without waiting between launches, then wait for every result. For canonical 4R, preserve `review-risk`, `review-resilience`, `review-readability`, `review-reliability` order.
96
+
97
+ Each launch runs only its own provider-issued `review.capture-result` argument tokens exactly as returned. Completion order is not authority: shared Go admission/election owns reduction and semantics. The final admitted capture owns reduction and closure. On `approved`, authority is already burned: do not FINALIZE or issue a trailing STATUS. On `correction_required`, continue only through exact bound STATUS and the provider-issued `review.capture-correction-plan` binding. After a malformed or nonterminal capture, reconcile through exact bound STATUS and retry only an identically reoffered slot.
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://gentle-ai.dev/schema/review/reviewer/v1",
4
+ "title": "Gentle AI reviewer result",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["subject_hash", "inspection", "findings", "evidence"],
8
+ "properties": {
9
+ "subject_hash": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
10
+ "inspection": {"type": "object", "additionalProperties": false, "required": ["status", "paths"], "properties": {"status": {"const": "completed"}, "paths": {"type": "array", "description": "Complete unique unordered set of every changed_path_manifest.path.", "uniqueItems": true, "items": {"type": "string", "minLength": 1}}}},
11
+ "lens": {"type": "string", "description": "Optional selected lens binding. Omission canonicalizes to the selected subject lens.", "enum": ["risk", "resilience", "readability", "reliability", "review-risk", "review-resilience", "review-readability", "review-reliability"]},
12
+ "findings": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["location", "severity", "claim", "proof_refs"], "allOf": [{"if": {"properties": {"severity": {"enum": ["BLOCKER", "CRITICAL"]}}, "required": ["severity"]}, "then": {"required": ["evidence_class", "causal_disposition"]}}], "properties": {"id": {"type": "string", "pattern": "^R[1-4]-[A-Za-z0-9][A-Za-z0-9._-]*$", "description": "Optional explicit ID; omit it to receive a native-assigned ID. When present it must carry the prefix bound to the selected lens, not the selection order: review-risk=R1-, review-readability=R2-, review-reliability=R3-, review-resilience=R4-."}, "lens": {"type": "string", "enum": ["risk", "resilience", "readability", "reliability", "review-risk", "review-resilience", "review-readability", "review-reliability"]}, "location": {"type": "string", "description": "One canonical repository-relative path:line or inclusive path:start-end span.", "pattern": "^.+:[1-9][0-9]*(?:-[1-9][0-9]*)?$"}, "severity": {"type": "string", "enum": ["BLOCKER", "CRITICAL", "WARNING", "SUGGESTION"]}, "claim": {"type": "string", "minLength": 1}, "proof_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "pattern": "\\S", "not": {"pattern": "^\\s*(?:[nN]/[aA]|[nN][aA]|[nN][oO][nN][eE]|[tT][oO][dD][oO]|[tT][bB][dD]|[pP][aA][sS][sS]|[pP][aA][sS][sS][eE][dD]|[sS][uU][cC][cC][eE][sS][sS]|[pP][lL][aA][cC][eE][hH][oO][lL][dD][eE][rR])\\s*$"}}}, "evidence_class": {"type": "string", "enum": ["deterministic", "inferential", "insufficient"]}, "causal_disposition": {"type": "string", "enum": ["introduced", "behavior-activated", "worsened", "pre-existing", "base-only", "unknown"]}}}},
13
+ "evidence": {"type": "array", "minItems": 1, "items": {"type": "string", "pattern": "\\S", "not": {"pattern": "^\\s*(?:[nN]/[aA]|[nN][aA]|[nN][oO][nN][eE]|[tT][oO][dD][oO]|[tT][bB][dD]|[pP][aA][sS][sS]|[pP][aA][sS][sS][eE][dD]|[sS][uU][cC][cC][eE][sS][sS]|[pP][lL][aA][cC][eE][hH][oO][lL][dD][eE][rR])\\s*$"}}}
14
+ },
15
+ "examples": [{"subject_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "inspection": {"status": "completed", "paths": ["internal/example.go"]}, "findings": [], "evidence": ["reviewed the complete candidate scope"]}]
16
+ }
@@ -0,0 +1 @@
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://gentle-ai.dev/schema/review/refuter/v1","title":"Gentle AI refuter result","type":"object","additionalProperties":false,"required":["refuter_request_hash","results"],"properties":{"refuter_request_hash":{"$ref":"#/$defs/sha256"},"results":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["finding_id","outcome","proof_refs"],"properties":{"finding_id":{"type":"string"},"outcome":{"type":"string","enum":["corroborated","refuted","inconclusive"]},"proof_refs":{"type":"array","minItems":1,"items":{"type":"string","pattern":"\\S"}}}}}},"$defs":{"sha256":{"type":"string","pattern":"^sha256:[0-9a-f]{64}$"}},"examples":[{"refuter_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","results":[]}]}
@@ -0,0 +1 @@
1
+ {"subject_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","inspection":{"status":"completed","paths":["internal/example.go"]},"findings":[],"evidence":["reviewed the complete candidate scope"]}
@@ -0,0 +1 @@
1
+ {"refuter_request_hash":"sha256:0000000000000000000000000000000000000000000000000000000000000000","results":[]}