2 Commits
Author SHA1 Message Date
admin 2d7bf2404a Align maintained package fixture with planner scope release
Check instruction packages / check (push) Successful in 3s
Check instruction packages / check (pull_request) Successful in 4s
2026-11-13 13:51:48 -05:00
admin f42eba659d Extend planner scope with replaceable checklist and presentation
Check instruction packages / check (push) Failing after 2s
2026-11-13 13:48:44 -05:00
6 changed files with 70 additions and 9 deletions

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@ Public source for RelayView-maintained instruction-only role skills and an illus
| Directory | Status | Role / step | Version | | Directory | Status | Role / step | Version |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `packages/{planner,implementer,reviewer}-investigation` | Maintained automatic guidance | One matching role / step each | 0.7.0 | | `packages/{planner,implementer,reviewer}-investigation` | Maintained automatic guidance | One matching role / step each | 0.7.0 |
| `packages/planner-scope` | Maintained default | Planner / planning | 0.2.0 | | `packages/planner-scope` | Maintained default | Planner / planning | 0.8.0 |
| `packages/implementer-handoff` | Maintained default | Implementer / implementation | 0.2.0 | | `packages/implementer-handoff` | Maintained default | Implementer / implementation | 0.2.0 |
| `packages/issue-designer-default` | Maintained default | Designer / design | 0.6.1 | | `packages/issue-designer-default` | Maintained default | Designer / design | 0.6.1 |
| `packages/designer-wayfinder`, `designer-grilling` | Optional manual guidance | Designer / design | 0.6.0 | | `packages/designer-wayfinder`, `designer-grilling` | Optional manual guidance | Designer / design | 0.6.0 |
+3 -1
View File
@@ -3,7 +3,7 @@ name: planner-scope
description: Check assigned issue scope, neighboring work, and verification before drafting a Plan. description: Check assigned issue scope, neighboring work, and verification before drafting a Plan.
metadata: metadata:
relayview-display-name: Planner scope relayview-display-name: Planner scope
relayview-version: 0.2.0 relayview-version: 0.8.0
--- ---
# Planner scope # Planner scope
@@ -13,3 +13,5 @@ When drafting the assigned Plan, identify the requested behavior, its boundary,
If the owner supplies an admitted work-item identity, use the assigned read tools to inspect it. Preserve source attribution; an issue description is a request, not evidence that its proposed behavior exists. Where tracker access is unavailable, state the missing context instead of guessing a work-item identity. If the owner supplies an admitted work-item identity, use the assigned read tools to inspect it. Preserve source attribution; an issue description is a request, not evidence that its proposed behavior exists. Where tracker access is unavailable, state the missing context instead of guessing a work-item identity.
Write the Plan through the owner's assigned planning interface. The Plan is ready when each requested outcome has an implementation boundary and a checkable success or recovery observation. Owner-controlled workflow stages and checks determine execution authority. Write the Plan through the owner's assigned planning interface. The Plan is ready when each requested outcome has an implementation boundary and a checkable success or recovery observation. Owner-controlled workflow stages and checks determine execution authority.
For a linked Gitea issue, this package declares the owner's transition from `status/ready-for-agent` to `status/in-progress` after it proves that the exact Plan reached the Implementer. Finalize the Plan through the assigned interface, then use owner-reported handoff and issue-claim outcomes when explaining progress to the Operator. An accepted Plan alone does not establish that claim. A user may replace this skill with a Planner fork whose package declares a different target status or disables the claim; follow the selected package's policy recorded for the task.
+7 -4
View File
@@ -1,19 +1,22 @@
{ {
"schemaVersion": 1, "schemaVersion": 2,
"source": { "source": {
"kind": "first-party", "kind": "first-party",
"reference": "v0.2.0" "reference": "v0.8.0"
}, },
"role": "planner", "role": "planner",
"step": "planning", "step": "planning",
"issueClaim": {
"statusLabel": "status/in-progress"
},
"files": [ "files": [
{ {
"path": "SKILL.md", "path": "SKILL.md",
"sha256": "31399ba322d8a4d3ed9814e7fd5d54883b4773c5b7dc3a241b8e14f8f7c16072" "sha256": "7dbd2ace7472a75c69b70ea118333429dfc7d56e5374454724805aa783cc0112"
}, },
{ {
"path": "scope.md", "path": "scope.md",
"sha256": "fc365d5f5c90f878992204235f32b1148aa4934a31f8c10eb063292fb64cf248" "sha256": "abed1a1590273b5f62f1e1f47ba8c92d00693de72c0d5e9b014ed1c911ac0a8e"
} }
] ]
} }
+35
View File
@@ -6,3 +6,38 @@
- Distinguish verified current behavior from a proposal. - Distinguish verified current behavior from a proposal.
- Identify one observable success path and one meaningful failure or recovery path. - Identify one observable success path and one meaningful failure or recovery path.
- Record uncertainty as an open decision; do not turn silence into approval. - Record uncertainty as an open decision; do not turn silence into approval.
Focus on:
- affected files and symbols
- existing patterns and architecture
- invariants and edge cases
- ordering and dependencies between changes
- tests, validation, and likely failure modes
- any assumptions that the implementer must know
- explicitly authorized supporting context that influences behavior
Return a compact structured plan. Prefer YAML-compatible Markdown:
```yaml
objective: ...
constraints:
- ...
steps:
- id: ...
files:
- ...
symbols:
- ...
change: ...
requirements:
- ...
depends_on:
- ...
edge_cases:
- ...
validation:
- ...
open_questions:
- ...
```
+11 -1
View File
@@ -12,6 +12,16 @@ ROOT = Path(__file__).resolve().parents[1]
class PackageTests(unittest.TestCase): class PackageTests(unittest.TestCase):
def test_planner_scope_presentation_and_claim(self):
package = ROOT / "packages/planner-scope"
check_package(package)
text = (package / "scope.md").read_text()
for phrase in ("affected files and symbols", "invariants and edge cases", "YAML-compatible Markdown", "open_questions:"):
self.assertIn(phrase, text)
self.assertNotIn("follow-up monitor", text)
manifest = json.loads((package / "relayview-skill.json").read_text())
self.assertEqual(manifest["issueClaim"], {"statusLabel": "status/in-progress"})
def test_role_investigation_packages(self): def test_role_investigation_packages(self):
for role, step in (("planner", "planning"), ("implementer", "implementation"), ("reviewer", "review")): for role, step in (("planner", "planning"), ("implementer", "implementation"), ("reviewer", "review")):
package = ROOT / "packages" / f"{role}-investigation" package = ROOT / "packages" / f"{role}-investigation"
@@ -103,7 +113,7 @@ class PackageTests(unittest.TestCase):
package = ROOT / "packages" / name package = ROOT / "packages" / name
manifest = json.loads((package / "relayview-skill.json").read_text()) manifest = json.loads((package / "relayview-skill.json").read_text())
self.assertEqual((manifest["role"], manifest["step"]), (role, step)) self.assertEqual((manifest["role"], manifest["step"]), (role, step))
self.assertEqual(manifest["source"], {"kind": "first-party", "reference": "v0.2.0"}) self.assertEqual(manifest["source"], {"kind": "first-party", "reference": "v0.8.0" if name == "planner-scope" else "v0.2.0"})
self.assertIn(resource, [item["path"] for item in manifest["files"]]) self.assertIn(resource, [item["path"] for item in manifest["files"]])
self.assertIn(marker, (package / "SKILL.md").read_text() + (package / resource).read_text()) self.assertIn(marker, (package / "SKILL.md").read_text() + (package / resource).read_text())
+13 -2
View File
@@ -44,15 +44,26 @@ def check_package(path):
manifest = json.loads(_text(raw_manifest, str(sidecar))) manifest = json.loads(_text(raw_manifest, str(sidecar)))
except (ValueError, TypeError) as error: except (ValueError, TypeError) as error:
_fail(f"{sidecar}: invalid JSON: {error}") _fail(f"{sidecar}: invalid JSON: {error}")
if not isinstance(manifest, dict) or set(manifest) != {"schemaVersion", "source", "role", "step", "files"}: if not isinstance(manifest, dict) or (
(manifest.get("schemaVersion") == 1 and set(manifest) != {"schemaVersion", "source", "role", "step", "files"}) or
(manifest.get("schemaVersion") == 2 and set(manifest) != {"schemaVersion", "source", "role", "step", "files", "issueClaim"}) or
manifest.get("schemaVersion") not in (1, 2)
):
_fail(f"{path}: unsupported manifest fields") _fail(f"{path}: unsupported manifest fields")
source = manifest["source"] source = manifest["source"]
if not isinstance(source, dict) or set(source) != {"kind", "reference"}: if not isinstance(source, dict) or set(source) != {"kind", "reference"}:
_fail(f"{path}: invalid source") _fail(f"{path}: invalid source")
if source["kind"] not in ("first-party", "user") or not isinstance(source["reference"], str) or not re.fullmatch(r"[A-Za-z0-9._:-]{1,128}", source["reference"]): if source["kind"] not in ("first-party", "user") or not isinstance(source["reference"], str) or not re.fullmatch(r"[A-Za-z0-9._:-]{1,128}", source["reference"]):
_fail(f"{path}: invalid source identity") _fail(f"{path}: invalid source identity")
if manifest["schemaVersion"] != 1 or (manifest["role"], manifest["step"]) not in (("planner", "planning"), ("implementer", "implementation"), ("reviewer", "review"), ("designer", "design")): if (manifest["role"], manifest["step"]) not in (("planner", "planning"), ("implementer", "implementation"), ("reviewer", "review"), ("designer", "design")):
_fail(f"{path}: incompatible role or step") _fail(f"{path}: incompatible role or step")
if manifest["schemaVersion"] == 2:
claim = manifest["issueClaim"]
label = claim.get("statusLabel") if isinstance(claim, dict) else None
if (manifest["role"], manifest["step"]) != ("planner", "planning") or not isinstance(claim, dict) or set(claim) != {"statusLabel"} or (
label is not None and (not isinstance(label, str) or not re.fullmatch(r"status/[a-z][a-z0-9-]{0,63}", label) or label == "status/ready-for-agent")
):
_fail(f"{path}: invalid issue claim policy")
files = manifest["files"] files = manifest["files"]
if not isinstance(files, list) or not 1 <= len(files) <= 16: if not isinstance(files, list) or not 1 <= len(files) <= 16:
_fail(f"{path}: invalid file list") _fail(f"{path}: invalid file list")