Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .adv/specs/advance-workflow/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -5679,6 +5679,71 @@
}
]
},
{
"id": "rq-reviewerEvidenceAuthority01",
"title": "Reviewer Evidence Authority Partitioned by Evidence Policy",
"body": "The stage-v2 evidence authority MUST partition verification requirements by evidence policy. For a completed task with evidence_policy \"review\", a persisted same-task adv-reviewer report IS the authoritative completion evidence; its aggregate tests_run command list neither creates nor substitutes for durable adv_run_test execution evidence, and the consumer_warning emitter MUST NOT emit verification_missing for it. For evidence_policy \"test\" or \"static_check\", reviewer aggregate command evidence MUST NOT satisfy the verification requirement; durable adv_run_test execution evidence remains required.",
"priority": "must",
"tags": [
"workflow",
"verification",
"evidence",
"structural",
"review"
],
"scenarios": [
{
"id": "rq-reviewerEvidenceAuthority01.1",
"title": "Review-policy task with linked reviewer report — no verification block",
"given": [
"A completed stage-v2 task has evidence_policy \"review\"",
"A persisted same-task adv-reviewer report is linked as review_evidence_ref"
],
"when": "Acceptance or release readiness evaluates verification evidence",
"then": [
"No VERIFICATION_EVIDENCE_MISSING blocker is emitted for the reviewer's tests_run"
],
"warrant": "AC1"
},
{
"id": "rq-reviewerEvidenceAuthority01.2",
"title": "Test/static_check-policy task with only reviewer evidence — block remains",
"given": [
"A completed task has evidence_policy \"test\" or \"static_check\"",
"A persisted same-task adv-reviewer report carries aggregate tests_run",
"No durable adv_run_test run exists"
],
"when": "Acceptance or release readiness evaluates verification evidence",
"then": [
"A VERIFICATION_EVIDENCE_MISSING blocker is emitted"
],
"warrant": "AC2"
},
{
"id": "rq-reviewerEvidenceAuthority01.3",
"title": "Emitter policy-gates verification_missing for adv-reviewer reports",
"given": [
"A task has evidence_policy \"review\""
],
"when": "An adv-reviewer report is submitted with aggregate tests_run",
"then": [
"The consumer_warning emitter produces no verification_missing warnings"
],
"warrant": "AC5"
},
{
"id": "rq-reviewerEvidenceAuthority01.4",
"title": "Same-task ownership preserved — change-scoped reviewer report cannot satisfy task review_evidence_ref",
"given": [
"A change-scoped adv-reviewer report has no task_id anchor"
],
"when": "Task completion validation runs",
"then": [
"The report cannot satisfy the task's review_evidence_ref"
]
}
]
},
{
"id": "rq-reviewBadTestCleanup01",
"title": "Reviewer-Owned Safe Local Cleanup of Evidence-Backed Bad Tests",
Expand Down
2 changes: 2 additions & 0 deletions docs/cli-surface-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@
| `adv_epic_reorder` | `no-cli-dangerous` | Epic mutation |
| `adv_epic_retire` | `no-cli-dangerous` | Epic retirement mutation |
| `adv_launcher_projection_rebuild` | `keep-mcp-only` | Producer-only aggregate launcher-projection rebuild (drift recovery); plugin/MCP-only, never bin/adv |
| `adv_change_set_worker_bundle_impact` | `keep-mcp-only` | Workflow-bound planning declaration of worker-bundle impact classification; agent/orchestrator use only |
| `adv_worker_bundle_provenance_record` | `keep-mcp-only` | Execution-time worker-bundle build+replay provenance receipt; agent/orchestrator use only |

## Deferred

Expand Down
2 changes: 2 additions & 0 deletions docs/tool-ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class rather than operator-only.
| `adv_change_archive` | orchestrator | Release-gate archive workflow |
| `adv_change_update_issues` | orchestrator | Issue linkage update |
| `adv_change_reenter` | orchestrator | Gate re-entry |
| `adv_change_set_worker_bundle_impact` | orchestrator | Typed worker-bundle impact declaration at planning |

### Lightweight change profile

Expand Down Expand Up @@ -186,6 +187,7 @@ class rather than operator-only.
| `adv_tool_catalog` | orchestrator | Bounded read-only catalog of canonical ADV tools with descriptive visibility metadata |
| `adv_tool_describe` | orchestrator | Read-only single-tool schema/metadata projection; no handler invocation |
| `adv_tool_invoke` | orchestrator | Strict in-process dispatcher through the canonical wrapped `ToolDefinition.execute`; preserves ToolContext, validation, authorization, approvals, recovery restrictions, and timeouts. Recursion-exclusion (`adv_tool_invoke`, `adv_tool_catalog`, `adv_tool_describe`, `execute`) is enforced before any lookup or dispatch (`addProviderToolSearch` AC1–AC4) |
| `adv_worker_bundle_provenance_record` | orchestrator | Record worker-bundle build+replay provenance on a change after both runs pass; execution-time evidence receipt |

## Removed Tools and Replacements

Expand Down
98 changes: 98 additions & 0 deletions plugin/src/adv-autonomy-quality-assets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -748,3 +748,101 @@ describe("Opportunity scout phase and schema anchors", () => {
expect(ids).toContain("rq-designOpportunityScout01");
});
});

// =============================================================================
// 7. Reviewer Evidence Authority (rq-reviewerEvidenceAuthority01)
// =============================================================================

describe("Reviewer evidence authority requirement (rq-reviewerEvidenceAuthority01)", () => {
const specPath = join(REPO_ROOT, ".adv/specs/advance-workflow/spec.json");
const spec: {
requirements: Array<{
id: string;
title: string;
body: string;
priority: string;
tags: string[];
scenarios: Array<{
id: string;
title: string;
given: string[];
when: string;
then: string[];
warrant?: string;
}>;
}>;
} = JSON.parse(readAsset(specPath));
const req = spec.requirements.find(
(r) => r.id === "rq-reviewerEvidenceAuthority01",
);

test("requirement exists as a MUST", () => {
expect(req).toBeDefined();
expect(req?.priority).toBe("must");
});

test("tags include relevant neighboring tags", () => {
expect(req?.tags).toContain("workflow");
expect(req?.tags).toContain("verification");
expect(req?.tags).toContain("evidence");
expect(req?.tags).toContain("structural");
expect(req?.tags).toContain("review");
});

test("requirement has exactly four scenarios .1 through .4", () => {
const scenarioIds = req?.scenarios.map((s) => s.id);
expect(scenarioIds).toEqual([
"rq-reviewerEvidenceAuthority01.1",
"rq-reviewerEvidenceAuthority01.2",
"rq-reviewerEvidenceAuthority01.3",
"rq-reviewerEvidenceAuthority01.4",
]);
});

test("scenario .1 warrants AC1 and describes review-policy no-block", () => {
const s = req?.scenarios.find(
(x) => x.id === "rq-reviewerEvidenceAuthority01.1",
);
expect(s).toBeDefined();
expect(s?.warrant).toBe("AC1");
expect(s?.title).toMatch(/review/i);
expect(s?.title).toMatch(/linked reviewer report|review_evidence_ref/i);
expect(s?.then.join(" ")).toMatch(/no VERIFICATION_EVIDENCE_MISSING/i);
});

test("scenario .2 warrants AC2 and preserves block for test/static_check policies", () => {
const s = req?.scenarios.find(
(x) => x.id === "rq-reviewerEvidenceAuthority01.2",
);
expect(s).toBeDefined();
expect(s?.warrant).toBe("AC2");
expect(s?.title).toMatch(/test|static_check/i);
expect(s?.title).toMatch(
/reviewer evidence|only reviewer|aggregate tests_run/i,
);
expect(s?.then.join(" ")).toMatch(
/VERIFICATION_EVIDENCE_MISSING blocker is emitted/i,
);
});

test("scenario .3 warrants AC5 and gates verification_missing warnings", () => {
const s = req?.scenarios.find(
(x) => x.id === "rq-reviewerEvidenceAuthority01.3",
);
expect(s).toBeDefined();
expect(s?.warrant).toBe("AC5");
expect(s?.title).toMatch(/emitter/i);
expect(s?.title).toMatch(/verification_missing/i);
expect(s?.then.join(" ")).toMatch(/no verification_missing warnings/i);
});

test("scenario .4 preserves same-task ownership", () => {
const s = req?.scenarios.find(
(x) => x.id === "rq-reviewerEvidenceAuthority01.4",
);
expect(s).toBeDefined();
expect(s?.title).toMatch(/same-task/i);
expect(s?.title).toMatch(/ownership|review_evidence_ref/i);
expect(s?.then.join(" ")).toMatch(/cannot satisfy|not satisfy/i);
});
});
2 changes: 2 additions & 0 deletions plugin/src/cli-bridge-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ describe("REGISTRY NO-REMOVAL GUARD (AC6/DONT1)", () => {
"adv_change_update_issues",
"adv_change_repair_origin",
"adv_change_reenter",
"adv_change_set_worker_bundle_impact",
"adv_worker_bundle_provenance_record",
"adv_epic_create",
"adv_epic_show",
"adv_epic_list",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ function makeChangeInput(
gates: makeSeedGates(),
contract: fixtureContract,
reentry_history: [],
// Worker-bundle provenance is enforced for new release-gate completions;
// declare it not_applicable so the phase9 recovery path is not blocked.
worker_bundle_impact: {
kind: "not_applicable",
rationale: "Integration fixture bypasses worker-bundle provenance.",
},
},
};
}
Expand Down
Loading
Loading