From 07634ab1448c07c9269cef30e957ff03697c2feb Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 12:11:52 +0000 Subject: [PATCH 1/7] feat: require complete architecture task breakdowns --- SKILL.md | 14 +++++++++++++- tests/test_task_breakdown_policy.py | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/test_task_breakdown_policy.py diff --git a/SKILL.md b/SKILL.md index 4318b4d..56b0d85 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: corp-v1-channel-architecture description: "Use when operating or synchronizing a Corp v1 project's architecture channel. Maintains C4-based architecture documentation, Draw.io diagrams, architecture decisions, and requirements while correlating verified activity across the project's seven channels." -version: 1.6.2 +version: 1.7.0 author: Hermes Agent license: MIT metadata: @@ -202,6 +202,17 @@ Use stable IDs such as `FR-0001` and `NFR-0001`. Requirements must be unambiguou Architecture derives and maintains implementation-task semantics, dependencies, sequencing, and readiness from the FR/NFR solution. Scope hosts the canonical task records and reader pages under their owning Feature; Architecture must not create a competing task registry page or task navigation. +Architecture owns complete Task decomposition for every Feature allocated to the release. Before reporting a release planning-ready, Architecture must: + +1. review existing Tasks and retain, revise, or supersede them according to the current Feature outcomes and Architecture boundaries; +2. define at least two independently executable Tasks per Feature unless a recorded Architecture rationale proves that one atomic Task is the smallest verifiable boundary; +3. map the Feature's Tasks collectively to every acceptance outcome and every applicable requirement, with reciprocal canonical traceability; +4. encode within-Feature sequencing and every cross-Feature prerequisite as acyclic Task dependencies; +5. give each Task one specific outcome, bounded scope, repository/component owner, future acceptance-evidence requirement, and canonical/display identity; +6. keep draft Tasks separate from implementation approval and Kanban Focus admission. + +Architecture must not report planning readiness while any Feature allocated to the release lacks this complete Task breakdown. A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate. + ```text canonical_id | display_id | feature | outcome | scope | dependencies | owner | status | acceptance evidence | affected repository/component ``` @@ -291,6 +302,7 @@ Requires team approval for: - [ ] ADR, FR, and NFR entries have stable IDs and traceability. - [ ] Every solution Feature has explicit human `Approved for Solution` evidence. - [ ] Eligible Features have dependency-aware task derivation and version proposals, with canonical task reader pages under their Scope Feature. +- [ ] Every Feature allocated to the planned release has a reviewed, non-placeholder Task breakdown covering every acceptance outcome and applicable requirement, with acyclic within-Feature and cross-Feature dependencies. - [ ] Task display IDs use `-TS-` without rewriting historic canonical identities, evidence, or append-only hashes. - [ ] Only a human team member moved a Feature to `Approved for Implementation` or finalized its version. - [ ] Tasks were proposed to Kanban with readiness/dependency evidence; Architecture did not self-admit them to Focus `InBacklog`. diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py new file mode 100644 index 0000000..703f135 --- /dev/null +++ b/tests/test_task_breakdown_policy.py @@ -0,0 +1,25 @@ +from pathlib import Path +import unittest + + +class TaskBreakdownPolicyTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.skill = Path(__file__).parents[1].joinpath("SKILL.md").read_text() + + def test_architecture_owns_complete_release_task_breakdown(self): + required = [ + "Architecture owns complete Task decomposition", + "every Feature allocated to the release", + "review existing Tasks", + "at least two independently executable Tasks", + "every acceptance outcome", + "every applicable requirement", + "must not report planning readiness", + ] + for marker in required: + self.assertIn(marker, self.skill) + + +if __name__ == "__main__": + unittest.main() From 091617ffe8f3841ab9393724d7bc7dfa175f60a4 Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 12:25:56 +0000 Subject: [PATCH 2/7] fix: preserve task lifecycle approval evidence --- SKILL.md | 4 +++- tests/test_task_breakdown_policy.py | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/SKILL.md b/SKILL.md index 56b0d85..ed54fe7 100644 --- a/SKILL.md +++ b/SKILL.md @@ -204,7 +204,7 @@ Architecture derives and maintains implementation-task semantics, dependencies, Architecture owns complete Task decomposition for every Feature allocated to the release. Before reporting a release planning-ready, Architecture must: -1. review existing Tasks and retain, revise, or supersede them according to the current Feature outcomes and Architecture boundaries; +1. Architecture creates missing Tasks, reviews existing Tasks, and retains, revises, supersedes, or removes them according to the current Feature outcomes and Architecture boundaries. Architecture may freely revise or remove only draft Tasks with no implementation approval, Kanban admission, execution, or completion evidence; 2. define at least two independently executable Tasks per Feature unless a recorded Architecture rationale proves that one atomic Task is the smallest verifiable boundary; 3. map the Feature's Tasks collectively to every acceptance outcome and every applicable requirement, with reciprocal canonical traceability; 4. encode within-Feature sequencing and every cross-Feature prerequisite as acyclic Task dependencies; @@ -213,6 +213,8 @@ Architecture owns complete Task decomposition for every Feature allocated to the Architecture must not report planning readiness while any Feature allocated to the release lacks this complete Task breakdown. A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate. +Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten. Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links. A material change to Task scope, outcome, dependency, repository, or component must invalidate prior readiness evidence and return the affected record to the appropriate pre-approval state; renewed human `Approved for Implementation` and a separate exact-task Kanban Focus admission are required where applicable before execution resumes. + ```text canonical_id | display_id | feature | outcome | scope | dependencies | owner | status | acceptance evidence | affected repository/component ``` diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index 703f135..9c93240 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -11,7 +11,7 @@ class TaskBreakdownPolicyTest(unittest.TestCase): required = [ "Architecture owns complete Task decomposition", "every Feature allocated to the release", - "review existing Tasks", + "reviews existing Tasks", "at least two independently executable Tasks", "every acceptance outcome", "every applicable requirement", @@ -20,6 +20,27 @@ class TaskBreakdownPolicyTest(unittest.TestCase): for marker in required: self.assertIn(marker, self.skill) + def test_task_lifecycle_and_readiness_rules_are_fail_closed(self): + required = [ + "version: 1.7.0", + "repository/component owner", + "future acceptance-evidence requirement", + "within-Feature sequencing", + "cross-Feature prerequisite", + "acyclic Task dependencies", + "creates missing Tasks", + "freely revise or remove only draft Tasks", + "must not be deleted or silently rewritten", + "Superseded or Cancelled", + "replacement links", + "invalidate prior readiness evidence", + "pre-approval state", + "renewed human `Approved for Implementation`", + "separate exact-task Kanban Focus admission", + ] + for marker in required: + self.assertIn(marker, self.skill) + if __name__ == "__main__": unittest.main() From a7efaf86fe63e8b12914f09679486fec6680fa54 Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 12:36:14 +0000 Subject: [PATCH 3/7] fix: require structured task contracts --- SKILL.md | 2 +- tests/test_task_breakdown_policy.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/SKILL.md b/SKILL.md index ed54fe7..67aeecc 100644 --- a/SKILL.md +++ b/SKILL.md @@ -208,7 +208,7 @@ Architecture owns complete Task decomposition for every Feature allocated to the 2. define at least two independently executable Tasks per Feature unless a recorded Architecture rationale proves that one atomic Task is the smallest verifiable boundary; 3. map the Feature's Tasks collectively to every acceptance outcome and every applicable requirement, with reciprocal canonical traceability; 4. encode within-Feature sequencing and every cross-Feature prerequisite as acyclic Task dependencies; -5. give each Task one specific outcome, bounded scope, repository/component owner, future acceptance-evidence requirement, and canonical/display identity; +5. give each Task one specific outcome, repository/component owner, canonical/display identity, task-specific implementation artifacts, concrete inputs and outputs, failure boundaries, exclusions, verification steps, and future acceptance-evidence requirements; 6. keep draft Tasks separate from implementation approval and Kanban Focus admission. Architecture must not report planning readiness while any Feature allocated to the release lacks this complete Task breakdown. A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate. diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index 9c93240..13cbc3e 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -24,7 +24,12 @@ class TaskBreakdownPolicyTest(unittest.TestCase): required = [ "version: 1.7.0", "repository/component owner", - "future acceptance-evidence requirement", + "acceptance-evidence requirements", + "implementation artifacts", + "inputs and outputs", + "failure boundaries", + "exclusions", + "verification steps", "within-Feature sequencing", "cross-Feature prerequisite", "acyclic Task dependencies", From ef7bdf015b4bc8fe7fffd7ecfa5446bae50c4ccb Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 12:38:36 +0000 Subject: [PATCH 4/7] test: lock task lifecycle protections --- tests/test_task_breakdown_policy.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index 13cbc3e..a6b77ed 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -6,6 +6,7 @@ class TaskBreakdownPolicyTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.skill = Path(__file__).parents[1].joinpath("SKILL.md").read_text() + cls.task_section = cls.skill.split("## Task and Dependency Breakdown", 1)[1].split("## Version Allocation", 1)[0] def test_architecture_owns_complete_release_task_breakdown(self): required = [ @@ -18,11 +19,10 @@ class TaskBreakdownPolicyTest(unittest.TestCase): "must not report planning readiness", ] for marker in required: - self.assertIn(marker, self.skill) + self.assertIn(marker, self.task_section) def test_task_lifecycle_and_readiness_rules_are_fail_closed(self): required = [ - "version: 1.7.0", "repository/component owner", "acceptance-evidence requirements", "implementation artifacts", @@ -42,9 +42,13 @@ class TaskBreakdownPolicyTest(unittest.TestCase): "pre-approval state", "renewed human `Approved for Implementation`", "separate exact-task Kanban Focus admission", + "Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten.", + "Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links.", + "A material change to Task scope, outcome, dependency, repository, or component must invalidate prior readiness evidence", ] + self.assertIn("version: 1.7.0", self.skill) for marker in required: - self.assertIn(marker, self.skill) + self.assertIn(marker, self.task_section) if __name__ == "__main__": From e324610416da01b740278aa2d4aa4f6dfa7a26df Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 14:46:50 +0000 Subject: [PATCH 5/7] fix: enforce bounded task planning policy --- SKILL.md | 14 +++-- tests/test_task_breakdown_policy.py | 85 +++++++++++++++-------------- 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/SKILL.md b/SKILL.md index 67aeecc..52c3bf8 100644 --- a/SKILL.md +++ b/SKILL.md @@ -202,18 +202,22 @@ Use stable IDs such as `FR-0001` and `NFR-0001`. Requirements must be unambiguou Architecture derives and maintains implementation-task semantics, dependencies, sequencing, and readiness from the FR/NFR solution. Scope hosts the canonical task records and reader pages under their owning Feature; Architecture must not create a competing task registry page or task navigation. -Architecture owns complete Task decomposition for every Feature allocated to the release. Before reporting a release planning-ready, Architecture must: +Architecture owns complete Task decomposition for every Feature allocated to the release. + +Before reporting a release planning-ready, Architecture must: 1. Architecture creates missing Tasks, reviews existing Tasks, and retains, revises, supersedes, or removes them according to the current Feature outcomes and Architecture boundaries. Architecture may freely revise or remove only draft Tasks with no implementation approval, Kanban admission, execution, or completion evidence; -2. define at least two independently executable Tasks per Feature unless a recorded Architecture rationale proves that one atomic Task is the smallest verifiable boundary; -3. map the Feature's Tasks collectively to every acceptance outcome and every applicable requirement, with reciprocal canonical traceability; -4. encode within-Feature sequencing and every cross-Feature prerequisite as acyclic Task dependencies; +2. define between two and six independently executable Tasks per Feature; permit one Task only when a recorded Architecture rationale proves it is the smallest atomic, independently verifiable boundary; +3. map the Feature's Tasks collectively, exactly, and reciprocally to every acceptance-outcome ID and every applicable active `FR-*` and `NFR-*` record; +4. encode acyclic within-Feature sequencing and require every entry Task to depend on all terminal Tasks of every prerequisite Feature; 5. give each Task one specific outcome, repository/component owner, canonical/display identity, task-specific implementation artifacts, concrete inputs and outputs, failure boundaries, exclusions, verification steps, and future acceptance-evidence requirements; 6. keep draft Tasks separate from implementation approval and Kanban Focus admission. Architecture must not report planning readiness while any Feature allocated to the release lacks this complete Task breakdown. A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate. -Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten. Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links. A material change to Task scope, outcome, dependency, repository, or component must invalidate prior readiness evidence and return the affected record to the appropriate pre-approval state; renewed human `Approved for Implementation` and a separate exact-task Kanban Focus admission are required where applicable before execution resumes. +Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten. Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links. + +A material change to Task scope, outcome, dependency, repository, or component invalidates the Task's existing implementation approval, returns the Task to its pre-approval state, and always requires renewed human `Approved for Implementation` before implementation can resume. After renewed approval, execution still requires a separate exact-task Kanban Focus admission. ```text canonical_id | display_id | feature | outcome | scope | dependencies | owner | status | acceptance evidence | affected repository/component diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index a6b77ed..6089180 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -1,54 +1,57 @@ from pathlib import Path +import re import unittest +COMMENT = re.compile(r"", re.DOTALL) + + +def task_section(skill: str) -> str: + operative = COMMENT.sub("", skill) + return operative.split("## Task and Dependency Breakdown", 1)[1].split("## Version Allocation", 1)[0] + + +def policy_failures(section: str, approval_rule: str) -> list[str]: + section = COMMENT.sub("", section) + patterns = { + "ownership": r"(?m)^Architecture owns complete Task decomposition for every Feature allocated to the release\.$", + "lifecycle": r"(?m)^1\. Architecture creates missing Tasks, reviews existing Tasks, and retains, revises, supersedes, or removes them .+ may freely revise or remove only draft Tasks .+;$", + "cardinality": r"(?m)^2\. define between two and six independently executable Tasks per Feature; permit one Task only when a recorded Architecture rationale proves it is the smallest atomic, independently verifiable boundary;$", + "mapping": r"(?m)^3\. map the Feature's Tasks collectively, exactly, and reciprocally to every acceptance-outcome ID and every applicable active `FR-\*` and `NFR-\*` record;$", + "dependencies": r"(?m)^4\. encode acyclic within-Feature sequencing and require every entry Task to depend on all terminal Tasks of every prerequisite Feature;$", + "contract": r"(?m)^5\. give each Task one specific outcome, repository/component owner, canonical/display identity, task-specific implementation artifacts, concrete inputs and outputs, failure boundaries, exclusions, verification steps, and future acceptance-evidence requirements;$", + "separate-gates": r"(?m)^6\. keep draft Tasks separate from implementation approval and Kanban Focus admission\.$", + "protected-history": r"(?m)^Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten\. Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links\.$", + "approval-invalidation": approval_rule, + } + return [name for name, pattern in patterns.items() if re.search(pattern, section) is None] + + class TaskBreakdownPolicyTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.skill = Path(__file__).parents[1].joinpath("SKILL.md").read_text() - cls.task_section = cls.skill.split("## Task and Dependency Breakdown", 1)[1].split("## Version Allocation", 1)[0] + cls.task_section = task_section(cls.skill) + cls.approval_rule = ( + r"(?m)^A material change to Task scope, outcome, dependency, repository, or component invalidates the Task's existing implementation approval, returns the Task to its pre-approval state, and always requires renewed human `Approved for Implementation` before implementation can resume\. After renewed approval, execution still requires a separate exact-task Kanban Focus admission\.$" + ) - def test_architecture_owns_complete_release_task_breakdown(self): - required = [ - "Architecture owns complete Task decomposition", - "every Feature allocated to the release", - "reviews existing Tasks", - "at least two independently executable Tasks", - "every acceptance outcome", - "every applicable requirement", - "must not report planning readiness", - ] - for marker in required: - self.assertIn(marker, self.task_section) - - def test_task_lifecycle_and_readiness_rules_are_fail_closed(self): - required = [ - "repository/component owner", - "acceptance-evidence requirements", - "implementation artifacts", - "inputs and outputs", - "failure boundaries", - "exclusions", - "verification steps", - "within-Feature sequencing", - "cross-Feature prerequisite", - "acyclic Task dependencies", - "creates missing Tasks", - "freely revise or remove only draft Tasks", - "must not be deleted or silently rewritten", - "Superseded or Cancelled", - "replacement links", - "invalidate prior readiness evidence", - "pre-approval state", - "renewed human `Approved for Implementation`", - "separate exact-task Kanban Focus admission", - "Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten.", - "Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links.", - "A material change to Task scope, outcome, dependency, repository, or component must invalidate prior readiness evidence", - ] + def test_operational_policy_is_complete_and_structured(self): self.assertIn("version: 1.7.0", self.skill) - for marker in required: - self.assertIn(marker, self.task_section) + self.assertEqual(policy_failures(self.task_section, self.approval_rule), []) + + def test_comments_and_weakened_rules_cannot_satisfy_policy(self): + self.assertTrue(policy_failures(f"", self.approval_rule)) + mutations = { + "cardinality": ("between two and six", "at least two"), + "mapping": ("exactly, and reciprocally", "loosely"), + "dependencies": ("all terminal Tasks", "some Tasks"), + "approval": ("invalidates the Task's existing implementation approval", "invalidates prior readiness evidence"), + "renewal": ("always requires renewed human", "may require renewed human"), + } + for name, (old, new) in mutations.items(): + with self.subTest(name=name): + self.assertTrue(policy_failures(self.task_section.replace(old, new), self.approval_rule)) if __name__ == "__main__": From 5cc95e0ce97c61e23d9351ede77ccbabee5c9845 Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 14:55:22 +0000 Subject: [PATCH 6/7] test: reject weakened draft protections --- tests/test_task_breakdown_policy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index 6089180..686e77d 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -15,7 +15,7 @@ def policy_failures(section: str, approval_rule: str) -> list[str]: section = COMMENT.sub("", section) patterns = { "ownership": r"(?m)^Architecture owns complete Task decomposition for every Feature allocated to the release\.$", - "lifecycle": r"(?m)^1\. Architecture creates missing Tasks, reviews existing Tasks, and retains, revises, supersedes, or removes them .+ may freely revise or remove only draft Tasks .+;$", + "lifecycle": r"(?m)^1\. Architecture creates missing Tasks, reviews existing Tasks, and retains, revises, supersedes, or removes them according to the current Feature outcomes and Architecture boundaries\. Architecture may freely revise or remove only draft Tasks with no implementation approval, Kanban admission, execution, or completion evidence;$", "cardinality": r"(?m)^2\. define between two and six independently executable Tasks per Feature; permit one Task only when a recorded Architecture rationale proves it is the smallest atomic, independently verifiable boundary;$", "mapping": r"(?m)^3\. map the Feature's Tasks collectively, exactly, and reciprocally to every acceptance-outcome ID and every applicable active `FR-\*` and `NFR-\*` record;$", "dependencies": r"(?m)^4\. encode acyclic within-Feature sequencing and require every entry Task to depend on all terminal Tasks of every prerequisite Feature;$", @@ -43,6 +43,7 @@ class TaskBreakdownPolicyTest(unittest.TestCase): def test_comments_and_weakened_rules_cannot_satisfy_policy(self): self.assertTrue(policy_failures(f"", self.approval_rule)) mutations = { + "draft-protection": ("with no implementation approval, Kanban admission, execution, or completion evidence", "even with implementation approval, Kanban admission, execution, or completion evidence"), "cardinality": ("between two and six", "at least two"), "mapping": ("exactly, and reciprocally", "loosely"), "dependencies": ("all terminal Tasks", "some Tasks"), From 08dd1996e6168ca34f10aba2ec4988b0abcfcb18 Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 2 Sep 2026 14:58:53 +0000 Subject: [PATCH 7/7] test: protect planning readiness gate --- tests/test_task_breakdown_policy.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_task_breakdown_policy.py b/tests/test_task_breakdown_policy.py index 686e77d..09e5b9d 100644 --- a/tests/test_task_breakdown_policy.py +++ b/tests/test_task_breakdown_policy.py @@ -21,6 +21,7 @@ def policy_failures(section: str, approval_rule: str) -> list[str]: "dependencies": r"(?m)^4\. encode acyclic within-Feature sequencing and require every entry Task to depend on all terminal Tasks of every prerequisite Feature;$", "contract": r"(?m)^5\. give each Task one specific outcome, repository/component owner, canonical/display identity, task-specific implementation artifacts, concrete inputs and outputs, failure boundaries, exclusions, verification steps, and future acceptance-evidence requirements;$", "separate-gates": r"(?m)^6\. keep draft Tasks separate from implementation approval and Kanban Focus admission\.$", + "planning-readiness": r"(?m)^Architecture must not report planning readiness while any Feature allocated to the release lacks this complete Task breakdown\. A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate\.$", "protected-history": r"(?m)^Approved, Kanban-admitted, in-progress, or completed Tasks must not be deleted or silently rewritten\. Retain an obsolete Task with a terminal Superseded or Cancelled status, its prior evidence and history, and explicit replacement links\.$", "approval-invalidation": approval_rule, } @@ -44,6 +45,8 @@ class TaskBreakdownPolicyTest(unittest.TestCase): self.assertTrue(policy_failures(f"", self.approval_rule)) mutations = { "draft-protection": ("with no implementation approval, Kanban admission, execution, or completion evidence", "even with implementation approval, Kanban admission, execution, or completion evidence"), + "planning-readiness": ("must not report planning readiness", "may report planning readiness"), + "placeholder-rejection": ("A Feature-shaped placeholder Task, a generated empty Task group, or requirement coverage without executable Tasks does not satisfy the gate.", ""), "cardinality": ("between two and six", "at least two"), "mapping": ("exactly, and reciprocally", "loosely"), "dependencies": ("all terminal Tasks", "some Tasks"),