|
19 | 19 | from pdca_harness.config import Config, LeafConfig |
20 | 20 |
|
21 | 21 | DESIGN_TPL = Path(__file__).resolve().parents[1] / "templates" / "design-proposal.md.tpl" |
| 22 | +POINTER_TPL = Path(__file__).resolve().parents[1] / "templates" / "plan-pointer.md.tpl" |
22 | 23 |
|
23 | 24 |
|
24 | 25 | def _stub_config(root: Path) -> Config: |
@@ -528,6 +529,42 @@ def test_feature_brief_flows_and_renders_goal(self) -> None: |
528 | 529 | self.assertIn("the capability this adds", summary) # the Goal value, not blank |
529 | 530 |
|
530 | 531 |
|
| 532 | +class PlanPointerBrief(unittest.TestCase): |
| 533 | + """A pointer-brief (issue #67): the Plan is a reference to the host's own planning |
| 534 | + artifact (ADR / proposal / spec), not a brief authored here. It carries the same |
| 535 | + parsed-field contract, so the driver treats it as a normal PLANNED brief.""" |
| 536 | + |
| 537 | + def setUp(self) -> None: |
| 538 | + self.tmp = Path(tempfile.mkdtemp()) |
| 539 | + self.cfg = _stub_config(self.tmp) |
| 540 | + self.d = self.cfg.bundle("ADR") |
| 541 | + self.d.mkdir(parents=True) |
| 542 | + shutil.copyfile(POINTER_TPL, self.d / "brief.md") # the plan-pointer template |
| 543 | + |
| 544 | + def tearDown(self) -> None: |
| 545 | + shutil.rmtree(self.tmp, ignore_errors=True) |
| 546 | + |
| 547 | + def test_template_keeps_driver_parsed_fields(self) -> None: |
| 548 | + fields = brief.parse_fields(self.d / "brief.md") |
| 549 | + for label in ("slug", "success criterion", "repo + branch target", "test file", |
| 550 | + "planning artifact"): |
| 551 | + self.assertIn(label, fields, f"plan-pointer template lost parsed field: {label}") |
| 552 | + |
| 553 | + def test_planning_artifact_reader(self) -> None: |
| 554 | + # brief.planning_artifact reads the pointer; a self-contained brief returns "". |
| 555 | + self.assertTrue(brief.planning_artifact(self.d / "brief.md")) |
| 556 | + plain = self.cfg.bundle("PLAIN") |
| 557 | + plain.mkdir(parents=True) |
| 558 | + (plain / "brief.md").write_text("- **Slug:** x\n", encoding="utf-8") |
| 559 | + self.assertEqual(brief.planning_artifact(plain / "brief.md"), "") |
| 560 | + |
| 561 | + def test_pointer_brief_flows_to_signoff(self) -> None: |
| 562 | + # A pointer-brief is PLANNED and drives Do→Check→sign-off offline like any brief. |
| 563 | + self.assertEqual(state.state(self.d), state.PLANNED) |
| 564 | + self.assertEqual(driver.run_issue(self.d, self.cfg), state.AWAITING_SIGNOFF) |
| 565 | + self.assertTrue((self.d / "SUMMARY.md").exists()) |
| 566 | + |
| 567 | + |
531 | 568 | _TOY_BRIEF = ( |
532 | 569 | "- **Slug:** {slug}\n" |
533 | 570 | "- **Defect:** the count is off by one.\n" |
|
0 commit comments