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.
- package/README.md +30 -4
- package/assets/agents/sdd-explore.md +1 -0
- package/assets/orchestrator-delegation.md +2 -1
- package/assets/orchestrator.md +6 -10
- package/contracts/review-provider-contract-mirror/provider-contract.lock.json +8 -7
- package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/README.md +10 -0
- package/contracts/review-provider-contract-mirror/v1.2.0/bundle/manifest.json +74 -0
- package/contracts/review-provider-contract-mirror/v1.2.0/bundle/orchestration/pi.md +53 -0
- package/contracts/review-provider-contract-mirror/v1.2.0/bundle/schemas/targeted-validator.schema.json +1 -0
- package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/generated/provider-capabilities.baseline.json +9 -2
- package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/generated/provider-roles.baseline.json +2 -2
- package/docs/review-integration.md +1 -1
- package/extensions/gentle-ai.ts +530 -71
- package/lib/agent-home.ts +8 -0
- package/lib/native-review-cli.ts +15 -0
- package/lib/provider-contract-bundle.ts +88 -6
- package/lib/review-host-relay.ts +146 -60
- package/lib/review-integration-v2.ts +34 -5
- package/lib/sdd-preflight.ts +2 -2
- package/package.json +1 -1
- package/runtime/native-review-cli.mjs +15 -0
- package/runtime/review-integration-v2.mjs +34 -5
- package/scripts/gentle-ai-installer.mjs +10 -10
- package/scripts/verify-package-files.mjs +14 -13
- package/skills/_shared/review-ledger-contract.md +6 -0
- package/skills/issue-creation/SKILL.md +53 -93
- package/tests/fixtures/provider-contract-bundle/v1.2.0/README.md +22 -0
- package/{contracts/review-provider-contract-mirror/v1.1.0/bundle → tests/fixtures/provider-contract-bundle/v1.2.0}/manifest.json +11 -2
- package/tests/fixtures/provider-contract-bundle/v1.2.0/orchestration/pi.md +97 -0
- package/tests/fixtures/provider-contract-bundle/v1.2.0/schemas/lens.schema.json +16 -0
- package/tests/fixtures/provider-contract-bundle/v1.2.0/schemas/refuter.schema.json +1 -0
- package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/lens.json +1 -0
- package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/refuter.json +1 -0
- package/tests/fixtures/provider-contract-bundle/v1.2.0/vectors/targeted-validator.json +1 -0
- package/tests/gentle-ai-binary.test.ts +1 -1
- package/tests/gentle-ai-installer.test.ts +46 -46
- package/tests/gentle-ai.test.ts +3 -2
- package/tests/issue-creation-skill.test.ts +103 -0
- package/tests/native-review-capability-contract.test.ts +18 -1
- package/tests/orchestrator-budget.test.ts +2 -2
- package/tests/orchestrator-rdd-ownership.test.ts +1 -1
- package/tests/package-manifest.test.ts +123 -9
- package/tests/provider-contract-bundle.test.ts +76 -0
- package/tests/provider-contract-mirror.test.ts +19 -0
- package/tests/review-agent-end-preflight.test.ts +408 -0
- package/tests/review-contract-prompt.test.ts +139 -0
- package/tests/review-controller.test.ts +1 -1
- package/tests/review-host-relay-routing.test.ts +211 -9
- package/tests/review-host-relay.test.ts +195 -7
- package/tests/review-integration-v2-forward.test.ts +47 -0
- package/tests/review-ledger-contract.test.ts +1 -1
- package/tests/runtime-harness.mjs +1 -0
- package/tests/writer-edit-surface-scope.test.ts +153 -17
- /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/schemas/lens.schema.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/schemas/refuter.schema.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/lens.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/refuter.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.1.0 → v1.2.0}/bundle/vectors/targeted-validator.json +0 -0
- /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;
|
|
1766
|
-
//
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
51
|
-
export const GENTLE_AI_WINDOWS_SOURCE_MODULE_CHECKSUM = "h1:
|
|
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.
|
|
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.
|
|
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.
|
|
118
|
-
"darwin/arm64": asset("gentle-ai_2.
|
|
119
|
-
"linux/amd64": asset("gentle-ai_2.
|
|
120
|
-
"linux/arm64": asset("gentle-ai_2.
|
|
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.
|
|
84
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
85
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
86
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
87
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
88
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
89
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
90
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
91
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
92
|
-
"contracts/review-provider-contract-mirror/v1.
|
|
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": "
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
52
|
-
LABEL_ARGS+=(--label "$LABEL")
|
|
38
|
+
LABEL_ARGS+=(--label "$LABEL") # Repeat only for each permitted discovered label.
|
|
53
39
|
```
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
## Workflow
|
|
41
|
+
## Duplicate And Form Decision
|
|
58
42
|
|
|
59
|
-
1. Describe the
|
|
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 "$
|
|
46
|
+
gh issue list --repo "$TARGET" --state all --search "$QUERY" --limit 1000
|
|
64
47
|
```
|
|
65
48
|
|
|
66
|
-
If
|
|
67
|
-
|
|
68
|
-
3.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
gh issue create --repo "$HOST/$REPO" --web "${LABEL_ARGS[@]}"
|
|
99
|
-
```
|
|
63
|
+
## Review And Publication
|
|
100
64
|
|
|
101
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
## Labels And Approval
|
|
87
|
+
Make one mutation attempt through the automated path and publish exactly once:
|
|
127
88
|
|
|
128
|
-
|
|
89
|
+
```bash
|
|
90
|
+
gh issue create --repo "$TARGET" --title "$TITLE" --body-file "$BODY_FILE" "${LABEL_ARGS[@]}"
|
|
91
|
+
```
|
|
129
92
|
|
|
130
|
-
|
|
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
|
-
|
|
95
|
+
```bash
|
|
96
|
+
gh issue create --repo "$TARGET" --web
|
|
97
|
+
```
|
|
136
98
|
|
|
137
|
-
|
|
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
|
-
|
|
101
|
+
```bash
|
|
102
|
+
gh issue view "$NUMBER" --repo "$TARGET" --json number,url,title,body,state,labels >"$READBACK_FILE"
|
|
103
|
+
```
|
|
140
104
|
|
|
141
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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": "
|
|
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":[]}
|