axstack 0.48.0 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/axstack/references/automations.md +10 -1
- package/skills/axstack/references/contracts.md +1 -0
- package/skills/axstack/references/pr-shape.md +17 -0
- package/skills/axstack/scripts/pr-shape.js +40 -6
- package/skills/axstack-review/SKILL.md +6 -1
- package/skills/axstack-review/references/peer-mode.md +48 -0
- package/skills/axstack-review/references/review-candidate.md +5 -2
- package/skills/axstack-watch/references/escalation.md +12 -5
- package/skills/axstack-watch/references/readiness.md +13 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axstack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.1",
|
|
4
4
|
"description": "Axstack installer and setup CLI: installs owned chat skills and role data, configures supported harness settings, and checks T3 Code capabilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -149,6 +149,14 @@ all scanned; those ten occupy zero slots.
|
|
|
149
149
|
|
|
150
150
|
## Admission and fairness
|
|
151
151
|
|
|
152
|
+
Before admission, check sync eligibility against the user-recorded pair in the
|
|
153
|
+
durable record under [PR shape](pr-shape.md#peer-sync-proof).
|
|
154
|
+
On sync pass, use no reviewer dispatch and submit nothing, record `sync skip`
|
|
155
|
+
with event identity for dedupe, and leave the PR for the user.
|
|
156
|
+
Sync fail or unknown follows ordinary review.
|
|
157
|
+
Each bounded PR job follows [Peer mode](../../axstack-review/references/peer-mode.md#sync-admission-and-round-freshness)
|
|
158
|
+
stale-round discard before each dispatch, before reconcile and before submission.
|
|
159
|
+
|
|
152
160
|
The review manager admits all eligible actionable PR events
|
|
153
161
|
that measured host capacity can support across ticks. Before each admission,
|
|
154
162
|
inspect available memory, CPU load, and active worker trees across the host;
|
|
@@ -289,8 +297,9 @@ existing bot `verdict head=` marker, five-request cap and independent adviser
|
|
|
289
297
|
panel, and compact output limits. Complete review may publish the
|
|
290
298
|
ordinary binding `APPROVE` or `REQUEST_CHANGES` verdict after a final head,
|
|
291
299
|
base, request, open-state, and existing-review readback. Incomplete review,
|
|
292
|
-
unknown GitHub state
|
|
300
|
+
unknown GitHub state or unavailable required models
|
|
293
301
|
publishes nothing.
|
|
302
|
+
Resolve peer unresolved disagreement through the verifier route under corroboration.
|
|
294
303
|
|
|
295
304
|
A new event that changes the disposition can change a peer verdict at an
|
|
296
305
|
unchanged head under `axstack-review`'s Automation exception; its identical
|
|
@@ -121,6 +121,7 @@ Never advise spec approval, npm stage approval or collaborator approval.
|
|
|
121
121
|
Never advise access or credentials.
|
|
122
122
|
Never advise forge merges by the user.
|
|
123
123
|
Never advise `Auto-merge: off`.
|
|
124
|
+
Never advise risky-path holds.
|
|
124
125
|
Never advise work-promotion, deploying-base or unknown-base report cards.
|
|
125
126
|
Never advise the report-only comment-rating card.
|
|
126
127
|
Never advise model unavailability or substitution.
|
|
@@ -18,6 +18,23 @@ Never automatically subtract bulk from the full total; silent exclusion is forbi
|
|
|
18
18
|
Disclose each bulk bucket with a reproducible recorded command.
|
|
19
19
|
There is no universal safe LOC limit or fixed token percentage.
|
|
20
20
|
|
|
21
|
+
## Peer sync proof
|
|
22
|
+
|
|
23
|
+
Run `pr-shape.js --base <base> --head <head> --source <source>`.
|
|
24
|
+
The sync term grants no authority.
|
|
25
|
+
Sync is eligible only for a user-recorded pair `<repo>: <source> -> <base>`
|
|
26
|
+
in the manager durable record, or user-named for manual review.
|
|
27
|
+
The head repo must equal the base repo.
|
|
28
|
+
Source S is a fetched base-repo ref with its SHA recorded.
|
|
29
|
+
Resolve B/H/S to base/head/source commit SHAs.
|
|
30
|
+
Pass requires B <= H and either H <= S or both B <= S and equal H/S trees.
|
|
31
|
+
Use `git merge-base --is-ancestor` for <= and `git rev-parse <sha>^{tree}` for trees.
|
|
32
|
+
Ancestor exit 1 means fail, other Git errors or missing objects mean unknown,
|
|
33
|
+
and absent `--source` means n/a. Preserve the helper's commands and SHAs.
|
|
34
|
+
On sync pass, use no reviewer dispatch and submit nothing, record `sync skip`
|
|
35
|
+
with event identity for dedupe, and leave the PR for the user.
|
|
36
|
+
Sync fail or unknown takes ordinary review.
|
|
37
|
+
|
|
21
38
|
## Theme
|
|
22
39
|
One behavior or component may include the callers, tests, types, docs, and
|
|
23
40
|
migrations that must change together to stay green and reviewable.
|
|
@@ -6,6 +6,7 @@ Example: bun scripts/pr-shape.js --base main --head HEAD
|
|
|
6
6
|
|
|
7
7
|
--base Required actual PR base (parent branch for a stacked child)
|
|
8
8
|
--head Required candidate commit or branch
|
|
9
|
+
--source Optional source ref for the read-only sync term; no source means n/a
|
|
9
10
|
--help Show flags, example, bucket definitions and exit codes
|
|
10
11
|
|
|
11
12
|
Read-only Git; writes nothing, retains no state. Prints a bounded JSON summary:
|
|
@@ -17,15 +18,18 @@ Generated means linguist-generated set or true in .gitattributes at the head;
|
|
|
17
18
|
uses the destination path for renames. Unset, false and unspecified are excluded.
|
|
18
19
|
Ignores system/global attributes; local info/attributes causes an unknown bucket.
|
|
19
20
|
Never subtract buckets; formatter-only changes require manual disclosure.
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
Sync reports B <= H AND (H <= S OR (B <= S AND H tree == S tree)).
|
|
22
|
+
Ancestor exit 1 means fail; other Git errors or missing source objects mean unknown.
|
|
23
|
+
No term grants authority. No cohesion or approval verdict.
|
|
24
|
+
Exit codes: 0 measured (including failed terms), 1 input/Git error,
|
|
25
|
+
2 incomplete (unknown sync, no merge-base or unavailable committed-attribute evidence).
|
|
22
26
|
`;
|
|
23
27
|
|
|
24
28
|
function optionsFrom(argv) {
|
|
25
29
|
const options = {};
|
|
26
30
|
for (let i = 0; i < argv.length; i += 2) {
|
|
27
31
|
const flag = argv[i];
|
|
28
|
-
if (!['--base', '--head'].includes(flag)) throw new Error(`unexpected argument ${flag}; use --help`);
|
|
32
|
+
if (!['--base', '--head', '--source'].includes(flag)) throw new Error(`unexpected argument ${flag}; use --help`);
|
|
29
33
|
const value = argv[i + 1];
|
|
30
34
|
if (!value || value.startsWith('-')) throw new Error(`missing ref; pass ${flag} <commit-or-branch>`);
|
|
31
35
|
if (flag in options) throw new Error(`duplicate ${flag}; pass it once`);
|
|
@@ -44,6 +48,34 @@ function run(argv, input) {
|
|
|
44
48
|
return { code: result.exitCode, stdout: result.stdout.toString(), stderr: result.stderr.toString() };
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
function syncTerm(inputs, gitCommand) {
|
|
52
|
+
const evidence = { base: inputs.base, head: inputs.head, source: null, commands: [] };
|
|
53
|
+
if (!inputs.sourceRef) return { status: 'n/a', evidence: { ...evidence, reason: 'no --source supplied' } };
|
|
54
|
+
const query = (...args) => {
|
|
55
|
+
const argv = gitCommand(...args);
|
|
56
|
+
evidence.commands.push(argv);
|
|
57
|
+
return run(argv);
|
|
58
|
+
};
|
|
59
|
+
const result = (status, reason) => ({ status, evidence: { ...evidence, reason } });
|
|
60
|
+
const source = query('rev-parse', '--verify', '--end-of-options', `${inputs.sourceRef}^{commit}`);
|
|
61
|
+
if (source.code) return result('unknown', source.stderr.trim());
|
|
62
|
+
inputs.source = evidence.source = source.stdout.trim();
|
|
63
|
+
const ancestor = (a, b) => query('merge-base', '--is-ancestor', a, b).code;
|
|
64
|
+
const baseHead = ancestor(inputs.base, inputs.head);
|
|
65
|
+
if (baseHead !== 0) return result(baseHead === 1 ? 'fail' : 'unknown', 'base ancestor of head');
|
|
66
|
+
const headSource = ancestor(inputs.head, inputs.source);
|
|
67
|
+
if (headSource === 0) return result('pass', 'base <= head <= source');
|
|
68
|
+
if (headSource !== 1) return result('unknown', 'head/source ancestry unavailable');
|
|
69
|
+
const baseSource = ancestor(inputs.base, inputs.source);
|
|
70
|
+
if (baseSource !== 0) return result(baseSource === 1 ? 'fail' : 'unknown', 'base ancestor of source');
|
|
71
|
+
const headTree = query('rev-parse', '--verify', `${inputs.head}^{tree}`);
|
|
72
|
+
const sourceTree = query('rev-parse', '--verify', `${inputs.source}^{tree}`);
|
|
73
|
+
if (headTree.code || sourceTree.code) return result('unknown', 'tree objects unavailable');
|
|
74
|
+
evidence.headTree = headTree.stdout.trim();
|
|
75
|
+
evidence.sourceTree = sourceTree.stdout.trim();
|
|
76
|
+
return result(evidence.headTree === evidence.sourceTree ? 'pass' : 'fail', 'base <= source and equal head/source trees');
|
|
77
|
+
}
|
|
78
|
+
|
|
47
79
|
function numstat(text) {
|
|
48
80
|
const tokens = text.split('\0');
|
|
49
81
|
const rows = [];
|
|
@@ -87,11 +119,13 @@ export function main(argv, io = { stdout: (text) => process.stdout.write(text),
|
|
|
87
119
|
return result.stdout.trim();
|
|
88
120
|
};
|
|
89
121
|
const inputs = { repo, baseRef: options['--base'], headRef: options['--head'], base: resolve('--base'), head: resolve('--head') };
|
|
122
|
+
if (options['--source']) inputs.sourceRef = options['--source'];
|
|
123
|
+
const sync = syncTerm(inputs, gitCommand);
|
|
90
124
|
const mergeCommand = gitCommand('merge-base', inputs.base, inputs.head);
|
|
91
125
|
const merge = run(mergeCommand);
|
|
92
126
|
if (merge.code) {
|
|
93
127
|
const unknown = { status: 'unknown', evidence: { commands: [mergeCommand], reason: merge.stderr.trim() || 'no common ancestor' } };
|
|
94
|
-
io.stdout(`${JSON.stringify({ inputs, mergeBase: { ...unknown, value: null }, totals: unknown,
|
|
128
|
+
io.stdout(`${JSON.stringify({ inputs, sync, mergeBase: { ...unknown, value: null }, totals: unknown,
|
|
95
129
|
buckets: { lockfiles: unknown, generated: unknown } })}\n`);
|
|
96
130
|
return 2;
|
|
97
131
|
}
|
|
@@ -118,13 +152,13 @@ export function main(argv, io = { stdout: (text) => process.stdout.write(text),
|
|
|
118
152
|
}
|
|
119
153
|
generated = summarize(rows.filter((row) => paths.has(row.path)), attrEvidence);
|
|
120
154
|
}
|
|
121
|
-
io.stdout(`${JSON.stringify({ inputs, mergeBase: { status: 'pass', value: mergeBase, evidence: { commands: [mergeCommand] } },
|
|
155
|
+
io.stdout(`${JSON.stringify({ inputs, sync, mergeBase: { status: 'pass', value: mergeBase, evidence: { commands: [mergeCommand] } },
|
|
122
156
|
totals: summarize(rows, { commands: [diffCommand], select: 'all records; no exclusions' }),
|
|
123
157
|
buckets: { lockfiles: summarize(rows.filter((row) => lockfiles.includes(row.path.split('/').at(-1))),
|
|
124
158
|
{ commands: [diffCommand], select: 'destination basename is exactly one of lockfileNames', lockfileNames: lockfiles }), generated },
|
|
125
159
|
disclosures: 'Buckets may overlap. Never subtract them from totals. Formatter-only changes require manual disclosure; cohesion is a manual judgment.',
|
|
126
160
|
})}\n`);
|
|
127
|
-
return generated.status === 'unknown' ? 2 : 0;
|
|
161
|
+
return generated.status === 'unknown' || sync.status === 'unknown' ? 2 : 0;
|
|
128
162
|
} catch (error) {
|
|
129
163
|
io.stderr(`pr-shape error: ${error.message}\n`);
|
|
130
164
|
return 1;
|
|
@@ -37,6 +37,8 @@ When the caller is a bounded review-manager PR job, load
|
|
|
37
37
|
[Native PR managers](../axstack/references/automations.md): its reviewer briefs
|
|
38
38
|
carry the required escalation field and every eligible peer PR takes a binding
|
|
39
39
|
`APPROVE` or `REQUEST_CHANGES` verdict under the automation exception below.
|
|
40
|
+
Sync skips are exempt from binding-verdict requirements under Peer mode.
|
|
41
|
+
For a sync skip, never fabricate an internal verdict.
|
|
40
42
|
|
|
41
43
|
For performance claims only, load [Performance checklist](../axstack/references/performance-checklist.md).
|
|
42
44
|
|
|
@@ -161,6 +163,7 @@ These verdicts apply only to PR modes. Codebase findings use coverage status.
|
|
|
161
163
|
exact candidate SHA and current base, covering the identical full brief;
|
|
162
164
|
follow-up has one current receipt covering the bounded Peer mode brief.
|
|
163
165
|
Peer review requires no diligence receipt.
|
|
166
|
+
Peer complete also requires verifier receipts when dispatched.
|
|
164
167
|
- **Authored complete:** the one required eligible non-author/non-owner reviewer has
|
|
165
168
|
a current verified receipt for the exact candidate SHA and current base,
|
|
166
169
|
covering the whole brief, all six angles, and applicable acceptance.
|
|
@@ -271,7 +274,9 @@ existing bot verdict markers across heads before publishing `REQUEST_CHANGES`;
|
|
|
271
274
|
a would-be sixth takes the panel path before submission. A serious-risk escalation holds
|
|
272
275
|
submission at its durable decision location. Otherwise `APPROVE` requires
|
|
273
276
|
no validated blocker and `REQUEST_CHANGES` requires at least one evidenced
|
|
274
|
-
validated blocker
|
|
277
|
+
validated blocker under Peer mode's corroboration bar.
|
|
278
|
+
Under the Automation exception, route unresolved disagreement through the peer verifier route.
|
|
279
|
+
`INCOMPLETE`, unavailable inputs,
|
|
275
280
|
or unknown GitHub state submits nothing.
|
|
276
281
|
|
|
277
282
|
Immediately before `gh pr review`, re-read self's reviews at the head.
|
|
@@ -11,6 +11,26 @@ That decision is not a finding. Peer review needs no Axstack-created approved
|
|
|
11
11
|
spec. Peer code stays readonly; the reviewer never edits it. Record exact head,
|
|
12
12
|
current base, context and authority before dispatch.
|
|
13
13
|
|
|
14
|
+
### Sync admission and round freshness
|
|
15
|
+
|
|
16
|
+
Sync admission requires the user-recorded pair, matching head repo and base repo,
|
|
17
|
+
and fetched source SHA under [PR shape](../../axstack/references/pr-shape.md#peer-sync-proof).
|
|
18
|
+
On sync pass, use no reviewer dispatch and submit nothing, record `sync skip`
|
|
19
|
+
with event identity, and leave the PR for the user.
|
|
20
|
+
Sync fail or unknown enters ordinary review.
|
|
21
|
+
|
|
22
|
+
Before each dispatch, before reconcile and before submission, re-read PR state,
|
|
23
|
+
head, base branch, base SHA and draft against the pinned event.
|
|
24
|
+
Discard if merged or closed, head or base SHA moved, base retargeted, or draft.
|
|
25
|
+
On discard, cancel owned tasks, verify settlement under
|
|
26
|
+
[Held job settlement](../../axstack/references/automations.md#held-job-settlement),
|
|
27
|
+
preserve evidence and record `discarded: <reason>`.
|
|
28
|
+
On discard, submit nothing.
|
|
29
|
+
For merged or closed PRs, run existing cleanup.
|
|
30
|
+
A new head is a new event, never a restart inside the job.
|
|
31
|
+
Unknown GitHub state holds, never discards.
|
|
32
|
+
Add no polling loop or watcher.
|
|
33
|
+
|
|
14
34
|
A missing bot verdict marker selects the first review. An existing bot verdict
|
|
15
35
|
marker selects follow-up from its `verdict head=` to the current head.
|
|
16
36
|
|
|
@@ -29,6 +49,34 @@ Every published peer verdict is binding `APPROVE` or `REQUEST_CHANGES`.
|
|
|
29
49
|
Never publish a COMMENT review. APPROVE when no blocker remains open, with
|
|
30
50
|
notes in the body. The bot never merges peer PRs.
|
|
31
51
|
|
|
52
|
+
### Corroboration
|
|
53
|
+
|
|
54
|
+
The owner can refute an allegation first with evidence.
|
|
55
|
+
Send surviving single-source blockers to a fresh session of the other peer-pair
|
|
56
|
+
role, batched per direction (primary's allegations to peer and peer's to primary).
|
|
57
|
+
Use at most two verifiers per first review and one per follow-up.
|
|
58
|
+
The verifier brief contains the allegation, relevant author replies and context,
|
|
59
|
+
pinned head and base, and code. Never include reviewer verdicts in the verifier brief.
|
|
60
|
+
For each blocker return CONFIRMED, REFUTED or UNSETTLED with the verifier's own evidence.
|
|
61
|
+
Single-provider presets use the other model of the pair and disclose session/model
|
|
62
|
+
independence instead of cross-family independence.
|
|
63
|
+
A verifier receipt never replaces a reviewer receipt or counts toward the five-request cap.
|
|
64
|
+
|
|
65
|
+
A blocker stands only when both first-pass reviewers raised the same concrete
|
|
66
|
+
defect with behavioural evidence, or a verifier CONFIRMED it.
|
|
67
|
+
Match the defect at any rating, treating an ambiguous match as single-source.
|
|
68
|
+
REFUTED allegations are dropped and recorded privately as rejected with evidence.
|
|
69
|
+
REFUTED allegations are never posted.
|
|
70
|
+
UNSETTLED becomes a non-blocking note plus `Not verified:` within the five-note limit.
|
|
71
|
+
Verifier unavailable or failed means INCOMPLETE.
|
|
72
|
+
When the verifier unavailable or failed outcome holds, submit nothing.
|
|
73
|
+
Pre-existing disputes settle before corroboration.
|
|
74
|
+
This bar preserves the serious-risk hold path and the adviser panel below.
|
|
75
|
+
|
|
76
|
+
On follow-up, prior open blockers and rejected rebuttals skip the verifier.
|
|
77
|
+
New or reopened blockers, including the full-diff fallback, require verification.
|
|
78
|
+
Downgraded notes never re-block unless the delta changes them or there is serious risk.
|
|
79
|
+
|
|
32
80
|
First review dispatches `axstack-reviewer-primary` and `axstack-reviewer-peer`
|
|
33
81
|
on the full diff and all six angles, independently with the identical brief
|
|
34
82
|
and an isolated first pass. Never dispatch diligence in peer mode.
|
|
@@ -27,6 +27,8 @@ This section applies to peer and authored PR modes.
|
|
|
27
27
|
The mixed peer pair is cross-provider (Sol high + Opus medium), with independence
|
|
28
28
|
still from separate sessions, the identical brief and an isolated first pass.
|
|
29
29
|
Follow-up instead uses the one reviewer and bounded brief in [Peer mode](../SKILL.md#peer-mode-colleague-pr).
|
|
30
|
+
Peer verifiers use fresh other-role sessions with the same checkout isolation.
|
|
31
|
+
Apply Peer mode's corroboration brief and per-direction batching after first-pass receipts.
|
|
30
32
|
- **Authored:** exactly one eligible independent reviewer from this complete
|
|
31
33
|
mapping:
|
|
32
34
|
|
|
@@ -156,8 +158,9 @@ This section applies to peer and authored PR modes.
|
|
|
156
158
|
handler returns 200 and creates a session. Consequence: expired links remain
|
|
157
159
|
usable.`
|
|
158
160
|
4. **Reconcile findings without voting.** The owner verifies findings and uses
|
|
159
|
-
focused checks to resolve contradictions.
|
|
160
|
-
|
|
161
|
+
focused checks to resolve contradictions. For peer unresolved disagreement,
|
|
162
|
+
use the verifier route under [corroboration](peer-mode.md#corroboration).
|
|
163
|
+
Reviewer votes never settle correctness.
|
|
161
164
|
Accepted fixes return to the actual author. Account for each finding as
|
|
162
165
|
validated, rejected with evidence, fixed, or explicitly unresolved.
|
|
163
166
|
5. **Bind the current revision and base.** Peer follow-ups apply Peer mode,
|
|
@@ -8,7 +8,8 @@ and a counted collaborator approval exists, on an `integration` base.
|
|
|
8
8
|
Work promotion PRs and `deploying` or unknown bases are merged by the user on
|
|
9
9
|
the forge. The existing serious-risk hold applies at once to both personal and
|
|
10
10
|
work PRs.
|
|
11
|
-
Personal and work PRs remain eligible whatever files they change,
|
|
11
|
+
Personal and work PRs remain eligible whatever files they change, subject to the
|
|
12
|
+
[risky-path hold](readiness.md#5-state-readiness-precisely), including
|
|
12
13
|
`.github/`, workflow-invoked files, package.json, lockfiles, test-runner config,
|
|
13
14
|
branch-protection or ruleset config, `CODEOWNERS`, `AGENTS.md`, and non-clean
|
|
14
15
|
revert lines such as `Revert: steps`.
|
|
@@ -30,15 +31,18 @@ at line start in the PR description.
|
|
|
30
31
|
A quoted format inside a bullet never counts as the declaration.
|
|
31
32
|
`--admin` and rule bypass are never used.
|
|
32
33
|
`Auto-merge: off` for a run or PR makes the merge card wait, and it waits for the user.
|
|
34
|
+
A risky-path hold blocks automatic merge.
|
|
33
35
|
|
|
34
|
-
Post a merge card for every nonqualifying approval, base, verification,
|
|
36
|
+
Post a merge card for every nonqualifying approval, base, verification, off,
|
|
37
|
+
or risky-path case.
|
|
35
38
|
Follow [Advised holds](../../axstack/references/contracts.md#advised-holds) for eligible merge-card causes.
|
|
36
39
|
Bind it to the PR head and base SHA; list CI, authored review and diligence at
|
|
37
40
|
those SHAs, counted collaborator approvals and bot votes with each vote's SHA
|
|
38
41
|
and stale flag, and the causes holding this merge.
|
|
39
|
-
A card that needs the user's decision (work promotion or work deploying/unknown
|
|
40
|
-
`Auto-merge: off`, provenance, or an unclosable verification gap)
|
|
41
|
-
hold raised in the T3 driver thread
|
|
42
|
+
A card that needs the user's decision (work promotion or work deploying/unknown
|
|
43
|
+
base, `Auto-merge: off`, risky-path, provenance, or an unclosable verification gap)
|
|
44
|
+
is a decision hold raised in the T3 driver thread, and the driver ends its turn
|
|
45
|
+
parked on the decision.
|
|
42
46
|
Revalidate the current head and base; the reply clears only its bound cause.
|
|
43
47
|
Person-wait cards follow the clock below.
|
|
44
48
|
A changed head or base requires a refreshed card.
|
|
@@ -46,6 +50,9 @@ For an own PR on an `integration` base, the user's reply to the card authorizes
|
|
|
46
50
|
the merge actor to merge under the guarded path, subject to the exceptions below.
|
|
47
51
|
In `solo` mode the user's merge-card reply authorizes the guarded merge of
|
|
48
52
|
user-written PRs or PRs with unknown or mixed provenance.
|
|
53
|
+
Only an explicit user "merge this" for this PR at the exact head and base SHA
|
|
54
|
+
clears the risky-path hold and authorizes the merge actor under the guarded path.
|
|
55
|
+
A new head or base re-applies the hold.
|
|
49
56
|
In `team` mode a reply never replaces counted collaborator approval.
|
|
50
57
|
A reply can clear auto-merge turned off; verification acceptance follows the
|
|
51
58
|
head-and-base-bound rule above. It never clears an ineligible work base or a
|
|
@@ -47,8 +47,14 @@ For each current head and base SHA, every merge-ready term must hold:
|
|
|
47
47
|
Reviews carrying an Axstack automation marker never count.
|
|
48
48
|
A later `CHANGES_REQUESTED` blocks until resolved; a stale or dismissed
|
|
49
49
|
approval does not count.
|
|
50
|
-
A collaborator approval carries over only across a rebase, base-update merge or
|
|
51
|
-
patch-id recorded for both heads
|
|
50
|
+
A collaborator approval carries over only across a rebase, base-update merge or
|
|
51
|
+
base-only retarget with unchanged patch-id recorded for both heads, or to a new
|
|
52
|
+
head made by repairs addressing review feedback (that reviewer's comments,
|
|
53
|
+
other review threads, authored-review or diligence findings, or CI fixes),
|
|
54
|
+
while the forge still counts it.
|
|
55
|
+
Carryover requires an undismissed approval, no later `CHANGES_REQUESTED` from
|
|
56
|
+
that reviewer, and repository rules that require neither last-push approval
|
|
57
|
+
nor stale-review dismissal.
|
|
52
58
|
Require fresh authored review, diligence, and CI on every new head.
|
|
53
59
|
Refresh authored review, diligence and CI evidence at the current head and base after every head or base change; base updates return to the same author under the existing repair route.
|
|
54
60
|
Text carrying a visible machine marker never counts as a user reply:
|
|
@@ -77,6 +83,11 @@ For each current head and base SHA, every merge-ready term must hold:
|
|
|
77
83
|
evidence instead.
|
|
78
84
|
- Proven verification: apply every receipt and acceptance term below, or its
|
|
79
85
|
head-and-base-bound user acceptance, while every other gate still holds.
|
|
86
|
+
- Risky paths: `merge-base..head` touches none of database migrations,
|
|
87
|
+
auth/authentication code, secrets or credential config, money/funds-moving
|
|
88
|
+
paths, or production deploy config, or a head-and-base-bound user clearance
|
|
89
|
+
under [Escalation](escalation.md) applies.
|
|
90
|
+
An uncertain risky-path classification holds automatic merge.
|
|
80
91
|
- Veto: no `do-not-merge` label and no chat `hold` applies.
|
|
81
92
|
|
|
82
93
|
Only comments and threads whose IDs are recorded in an agent receipt count as agent-authored.
|