From 8354fcbc4095a26663e8aeabef91a79039b1e4fc Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 19 Mar 2026 09:45:43 +0000 Subject: [PATCH] Promote lane expansion as active v6 target --- docs/release-control/control_plane.json | 8 +-- .../canonical_development_protocol_test.go | 9 ++- scripts/release_control/control_plane.py | 47 +++++++++++---- .../control_plane_audit_test.py | 10 ++++ scripts/release_control/status_lookup.py | 51 +++++++++++++++- scripts/release_control/status_lookup_test.py | 60 +++++++++++++++++++ .../release_control/subsystem_lookup_test.py | 2 +- 7 files changed, 168 insertions(+), 19 deletions(-) diff --git a/docs/release-control/control_plane.json b/docs/release-control/control_plane.json index 658435aa5..697b4c15f 100644 --- a/docs/release-control/control_plane.json +++ b/docs/release-control/control_plane.json @@ -6,7 +6,7 @@ "control_plane_doc": "docs/release-control/internal/CONTROL_PLANE.md", "control_plane_schema": "docs/release-control/control_plane.schema.json", "active_profile_id": "v6", - "active_target_id": "v6-rc-stabilization", + "active_target_id": "v6-product-lane-expansion", "profiles": [ { "id": "v6", @@ -38,7 +38,7 @@ "id": "v6-rc-stabilization", "profile_id": "v6", "kind": "stabilization", - "status": "active", + "status": "superseded", "summary": "Keep Pulse v6 in RC stabilization until remaining product/runtime concerns are resolved or normalized into governed proofs before GA promotion is resumed, while broader post-RC polish stays out of the release floor by default.", "completion_rule": "manual", "proof_scope": "none" @@ -55,8 +55,8 @@ "id": "v6-product-lane-expansion", "profile_id": "v6", "kind": "feature", - "status": "planned", - "summary": "Expand the governed lane taxonomy from the current RC-stabilization map toward the v6 bridge-release foundation by promoting resource-graph, policy-governance, action-governance, and fleet-governance gaps into explicit lanes, lane splits, or lane expansions.", + "status": "active", + "summary": "Default v6 engineering work to the bridge-release foundation by promoting and landing the known resource-graph, policy-governance, action-governance, and fleet-governance gaps ahead of further local RC cleanup.", "completion_rule": "manual", "proof_scope": "none" } diff --git a/internal/repoctl/canonical_development_protocol_test.go b/internal/repoctl/canonical_development_protocol_test.go index 6b712c8fc..40d41b62c 100644 --- a/internal/repoctl/canonical_development_protocol_test.go +++ b/internal/repoctl/canonical_development_protocol_test.go @@ -473,8 +473,10 @@ func TestReleaseControlPlaneFilesExist(t *testing.T) { "Direction changes must be normalized", "Do not wait for a special governance prompt", "stable or GA promotion readiness", + "v6-product-lane-expansion", "v6-ga-promotion", "v6-rc-stabilization", + "available_candidate_lane_queue", "should always be true", "Lane work must follow canonical v6 modernization rules", "These modernization rules are retrospective as well as forward-looking", @@ -508,7 +510,7 @@ func TestReleaseControlPlaneFilesExist(t *testing.T) { if !ok || activeTargetID == "" { t.Fatalf("%s missing active_target_id", jsonRel) } - if activeTargetID != "v6-rc-stabilization" && activeTargetID != "v6-ga-promotion" { + if activeTargetID != "v6-rc-stabilization" && activeTargetID != "v6-ga-promotion" && activeTargetID != "v6-product-lane-expansion" { t.Fatalf("%s has unexpected active_target_id %q", jsonRel, activeTargetID) } @@ -535,7 +537,7 @@ func TestReleaseControlPlaneFilesExist(t *testing.T) { } } - for _, requiredID := range []string{"v6-rc-cut", "v6-rc-stabilization", "v6-ga-promotion"} { + for _, requiredID := range []string{"v6-rc-cut", "v6-rc-stabilization", "v6-ga-promotion", "v6-product-lane-expansion"} { if _, ok := targetsByID[requiredID]; !ok { t.Fatalf("%s missing target %q", jsonRel, requiredID) } @@ -555,6 +557,9 @@ func TestReleaseControlPlaneFilesExist(t *testing.T) { if scope, _ := targetsByID["v6-rc-stabilization"]["proof_scope"].(string); scope != "none" { t.Fatalf("%s v6-rc-stabilization must keep proof_scope=none", jsonRel) } + if rule, _ := targetsByID["v6-product-lane-expansion"]["completion_rule"].(string); rule != "manual" { + t.Fatalf("%s v6-product-lane-expansion must keep completion_rule=manual", jsonRel) + } schemaRel := "docs/release-control/control_plane.schema.json" schemaContent := readRepoFile(t, schemaRel) diff --git a/scripts/release_control/control_plane.py b/scripts/release_control/control_plane.py index a92dda5a1..c5294d831 100644 --- a/scripts/release_control/control_plane.py +++ b/scripts/release_control/control_plane.py @@ -299,6 +299,7 @@ def active_control_plane(*, staged: bool = False) -> dict[str, Any]: def agent_entrypoint(*, staged: bool = False) -> dict[str, Any]: resolved = active_control_plane(staged=staged) + active_target_id = str(resolved["active_target_id"]) startup_files = [ resolved["agent_values_doc_rel"], resolved["control_plane_doc_rel"], @@ -315,17 +316,37 @@ def agent_entrypoint(*, staged: bool = False) -> dict[str, Any]: startup_commands = [ "python3 scripts/release_control/status_audit.py --pretty", ] - targeted_lookup_commands = [ - "python3 scripts/release_control/status_lookup.py --lane --pretty", - "python3 scripts/release_control/status_lookup.py --assertion --pretty", - "python3 scripts/release_control/status_lookup.py --release-gate --pretty", - "python3 scripts/release_control/status_lookup.py --followup --pretty", - "python3 scripts/release_control/status_lookup.py --work-claim --pretty", - "python3 scripts/release_control/subsystem_lookup.py [ ...] --pretty", - "python3 scripts/release_control/worktree_base.py --base-branch --pretty", - "python3 scripts/release_control/worktree_claim.py --kind --id --summary --agent-id --pretty", - "python3 scripts/release_control/worktree_finish.py --base-branch --pretty", - ] + targeted_lookup_commands = [] + if active_target_id == "v6-product-lane-expansion": + targeted_lookup_commands.extend( + [ + "python3 scripts/release_control/status_lookup.py --candidate-lane --pretty", + "python3 scripts/release_control/status_lookup.py --coverage-gap --pretty", + ] + ) + targeted_lookup_commands.extend( + [ + "python3 scripts/release_control/status_lookup.py --lane --pretty", + "python3 scripts/release_control/status_lookup.py --assertion --pretty", + "python3 scripts/release_control/status_lookup.py --release-gate --pretty", + "python3 scripts/release_control/status_lookup.py --followup --pretty", + "python3 scripts/release_control/status_lookup.py --work-claim --pretty", + "python3 scripts/release_control/subsystem_lookup.py [ ...] --pretty", + "python3 scripts/release_control/worktree_base.py --base-branch --pretty", + "python3 scripts/release_control/worktree_claim.py --kind --id --summary --agent-id --pretty", + "python3 scripts/release_control/worktree_finish.py --base-branch --pretty", + ] + ) + if active_target_id == "v6-product-lane-expansion": + default_pick_surface = "available_candidate_lane_queue" + selection_rule = ( + "Pick from available candidate lanes and linked coverage gaps before local RC cleanup unless the user overrides the priority or a release-blocking surface needs immediate containment." + ) + else: + default_pick_surface = "lanes" + selection_rule = ( + "Pick from the current lane map first unless the user overrides the priority or a narrower governed surface is already the explicit task." + ) return { "active_profile_id": resolved["active_profile_id"], "active_target_id": resolved["active_target_id"], @@ -337,6 +358,8 @@ def agent_entrypoint(*, staged: bool = False) -> dict[str, Any]: "ordered_files": startup_files + escalation_files, "startup_commands": startup_commands, "targeted_lookup_commands": targeted_lookup_commands, + "default_pick_surface": default_pick_surface, + "selection_rule": selection_rule, "subsystems_dir": resolved["subsystems_dir_rel"], "subsystem_lookup": "scripts/release_control/subsystem_lookup.py", "status_lookup": "scripts/release_control/status_lookup.py", @@ -420,6 +443,8 @@ def main(argv: list[str] | None = None) -> int: *[f" - {rel}" for rel in payload["startup_files"]], "startup_commands:", *[f" - {command}" for command in payload["startup_commands"]], + f"default_pick_surface={payload['default_pick_surface']}", + f"selection_rule={payload['selection_rule']}", "targeted_lookup_commands:", *[f" - {command}" for command in payload["targeted_lookup_commands"]], "escalation_files:", diff --git a/scripts/release_control/control_plane_audit_test.py b/scripts/release_control/control_plane_audit_test.py index 7324377f5..52149be48 100644 --- a/scripts/release_control/control_plane_audit_test.py +++ b/scripts/release_control/control_plane_audit_test.py @@ -98,6 +98,16 @@ class ControlPlaneAuditTest(unittest.TestCase): entrypoint["startup_commands"], ["python3 scripts/release_control/status_audit.py --pretty"], ) + self.assertEqual(entrypoint["default_pick_surface"], "available_candidate_lane_queue") + self.assertIn("candidate lanes", entrypoint["selection_rule"]) + self.assertIn( + "python3 scripts/release_control/status_lookup.py --candidate-lane --pretty", + entrypoint["targeted_lookup_commands"], + ) + self.assertIn( + "python3 scripts/release_control/status_lookup.py --coverage-gap --pretty", + entrypoint["targeted_lookup_commands"], + ) self.assertIn( "python3 scripts/release_control/status_lookup.py --lane --pretty", entrypoint["targeted_lookup_commands"], diff --git a/scripts/release_control/status_lookup.py b/scripts/release_control/status_lookup.py index b8bcb3737..51a02472e 100644 --- a/scripts/release_control/status_lookup.py +++ b/scripts/release_control/status_lookup.py @@ -13,6 +13,8 @@ from status_audit import audit_status_payload, load_status_payload, status_schem ENTRY_OPTIONS: tuple[tuple[str, str, str], ...] = ( + ("coverage_gap", "coverage_gaps", "id"), + ("candidate_lane", "candidate_lanes", "id"), ("lane", "lanes", "id"), ("assertion", "readiness_assertions", "id"), ("release_gate", "release_gates", "id"), @@ -52,7 +54,7 @@ def lookup_status_entry(report: dict[str, Any], *, kind: str, entry_id: str) -> raise KeyError(f"{collection} is not a list in status report") for entry in entries: if isinstance(entry, dict) and str(entry.get(key)) == entry_id: - return { + result = { "kind": kind, "collection": collection, "id": entry_id, @@ -60,12 +62,34 @@ def lookup_status_entry(report: dict[str, Any], *, kind: str, entry_id: str) -> "control_plane": report.get("control_plane", {}), "summary": report.get("summary", {}), } + if kind == "candidate_lane": + queue_item = next( + ( + item + for item in report.get("candidate_lane_queue", []) + if isinstance(item, dict) and str(item.get("candidate_lane_id")) == entry_id + ), + None, + ) + if queue_item is not None: + result["queue_item"] = queue_item + if kind == "coverage_gap": + linked_candidates = [ + str(candidate.get("id")) + for candidate in report.get("candidate_lanes", []) + if isinstance(candidate, dict) + and entry_id in [str(gap_id) for gap_id in candidate.get("coverage_gap_ids", [])] + ] + result["linked_candidate_lane_ids"] = linked_candidates + return result raise KeyError(f"{kind} {entry_id!r} not found") raise KeyError(f"unsupported kind {kind!r}") def parse_args(argv: list[str]) -> argparse.Namespace: parser = argparse.ArgumentParser(description="Lookup one release-control status entry by id.") + parser.add_argument("--coverage-gap", dest="coverage_gap", help="Coverage gap id.") + parser.add_argument("--candidate-lane", dest="candidate_lane", help="Candidate lane id.") parser.add_argument("--lane", help="Lane id, such as L16.") parser.add_argument("--assertion", help="Readiness assertion id, such as RA8.") parser.add_argument("--release-gate", dest="release_gate", help="Release gate id.") @@ -87,6 +111,22 @@ def parse_args(argv: list[str]) -> argparse.Namespace: def _render_collection_specific(lines: list[str], kind: str, entry: dict[str, Any]) -> None: + if kind == "coverage_gap": + lines.extend( + [ + f"status={entry.get('status')} resolution={entry.get('proposed_resolution')} impact={entry.get('coverage_impact')}", + f"lanes={','.join(entry.get('lane_ids', [])) or '-'} repos={','.join(entry.get('repo_ids', [])) or '-'} subsystems={','.join(entry.get('subsystem_ids', [])) or '-'}", + ] + ) + return + if kind == "candidate_lane": + lines.extend( + [ + f"status={entry.get('status')} target={entry.get('target_id')} repos={','.join(entry.get('repo_ids', [])) or '-'}", + f"current_lanes={','.join(entry.get('current_lane_ids', [])) or '-'} subsystems={','.join(entry.get('subsystem_ids', [])) or '-'} coverage_gaps={','.join(entry.get('coverage_gap_ids', [])) or '-'}", + ] + ) + return if kind == "lane": lines.extend( [ @@ -163,6 +203,15 @@ def render_pretty(result: dict[str, Any]) -> str: f"{result['kind']} {result['id']}: {entry.get('summary') or '-'}", ] _render_collection_specific(lines, result["kind"], entry) + if result["kind"] == "candidate_lane": + queue_item = result.get("queue_item", {}) + if queue_item: + lines.append( + f"queue: rank={queue_item.get('rank')} available={queue_item.get('available')} available_rank={queue_item.get('available_rank')}" + ) + if result["kind"] == "coverage_gap": + linked = result.get("linked_candidate_lane_ids", []) + lines.append(f"linked_candidate_lanes={','.join(linked) or '-'}") return "\n".join(lines) diff --git a/scripts/release_control/status_lookup_test.py b/scripts/release_control/status_lookup_test.py index 351ea4aee..bbf54a3a0 100644 --- a/scripts/release_control/status_lookup_test.py +++ b/scripts/release_control/status_lookup_test.py @@ -14,6 +14,30 @@ REPORT = { "summary": { "lane_count": 16, }, + "coverage_gaps": [ + { + "id": "resource-graph-and-change-timeline", + "summary": "Resource graph and timeline are still under-modeled.", + "status": "planned", + "proposed_resolution": "lane-split", + "coverage_impact": 15, + "lane_ids": ["L6", "L13"], + "repo_ids": ["pulse", "pulse-enterprise"], + "subsystem_ids": ["alerts", "api-contracts", "monitoring", "unified-resources"], + } + ], + "candidate_lanes": [ + { + "id": "resource-graph-change-intelligence", + "summary": "Promote canonical resource relationships and cross-resource timelines into an explicit lane.", + "status": "planned", + "target_id": "v6-product-lane-expansion", + "repo_ids": ["pulse", "pulse-enterprise"], + "current_lane_ids": ["L6", "L13"], + "subsystem_ids": ["alerts", "api-contracts", "monitoring", "unified-resources"], + "coverage_gap_ids": ["resource-graph-and-change-timeline"], + } + ], "lanes": [ { "id": "L16", @@ -30,6 +54,14 @@ REPORT = { "blockers": [], } ], + "candidate_lane_queue": [ + { + "candidate_lane_id": "resource-graph-change-intelligence", + "rank": 1, + "available": True, + "available_rank": 1, + } + ], "readiness_assertions": [ { "id": "RA8", @@ -92,11 +124,26 @@ class StatusLookupTest(unittest.TestCase): self.assertEqual(args.lane, "L16") self.assertTrue(args.pretty) + def test_parse_args_accepts_candidate_lane_selector(self) -> None: + args = parse_args(["--candidate-lane", "resource-graph-change-intelligence", "--pretty"]) + self.assertEqual(args.candidate_lane, "resource-graph-change-intelligence") + self.assertTrue(args.pretty) + def test_lookup_status_entry_returns_lane(self) -> None: result = lookup_status_entry(REPORT, kind="lane", entry_id="L16") self.assertEqual(result["entry"]["summary"], "Agent lifecycle and fleet operations.") self.assertEqual(result["control_plane"]["active_profile_id"], "v6") + def test_lookup_status_entry_returns_candidate_lane(self) -> None: + result = lookup_status_entry(REPORT, kind="candidate_lane", entry_id="resource-graph-change-intelligence") + self.assertEqual(result["entry"]["target_id"], "v6-product-lane-expansion") + self.assertEqual(result["queue_item"]["rank"], 1) + + def test_lookup_status_entry_returns_coverage_gap(self) -> None: + result = lookup_status_entry(REPORT, kind="coverage_gap", entry_id="resource-graph-and-change-timeline") + self.assertEqual(result["entry"]["coverage_impact"], 15) + self.assertEqual(result["linked_candidate_lane_ids"], ["resource-graph-change-intelligence"]) + def test_lookup_status_entry_returns_release_gate(self) -> None: result = lookup_status_entry( REPORT, @@ -122,6 +169,19 @@ class StatusLookupTest(unittest.TestCase): self.assertIn("work=lane:L16", rendered) self.assertIn("agent=codex", rendered) + def test_render_pretty_includes_candidate_lane_queue_details(self) -> None: + result = lookup_status_entry(REPORT, kind="candidate_lane", entry_id="resource-graph-change-intelligence") + rendered = render_pretty(result) + self.assertIn("candidate_lane resource-graph-change-intelligence", rendered) + self.assertIn("target=v6-product-lane-expansion", rendered) + self.assertIn("queue: rank=1 available=True available_rank=1", rendered) + + def test_render_pretty_includes_coverage_gap_links(self) -> None: + result = lookup_status_entry(REPORT, kind="coverage_gap", entry_id="resource-graph-and-change-timeline") + rendered = render_pretty(result) + self.assertIn("resolution=lane-split impact=15", rendered) + self.assertIn("linked_candidate_lanes=resource-graph-change-intelligence", rendered) + if __name__ == "__main__": unittest.main() diff --git a/scripts/release_control/subsystem_lookup_test.py b/scripts/release_control/subsystem_lookup_test.py index e54043523..4e98817d5 100644 --- a/scripts/release_control/subsystem_lookup_test.py +++ b/scripts/release_control/subsystem_lookup_test.py @@ -13,7 +13,7 @@ class SubsystemLookupTest(unittest.TestCase): self.assertEqual(result["status_audit_errors"], []) self.assertIn( result["control_plane"]["active_target"]["id"], - {"v6-rc-stabilization", "v6-ga-promotion"}, + {"v6-rc-stabilization", "v6-ga-promotion", "v6-product-lane-expansion"}, ) self.assertEqual(result["scope"]["control_plane_repo"], "pulse") self.assertEqual(result["status_summary"]["lane_count"], 16)