Skip to content

Commit e944d33

Browse files
chore(board): remove example-task.json; document schema in board README
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 12c23fa commit e944d33

8 files changed

Lines changed: 51 additions & 27 deletions

File tree

.github/workflows/ci.yml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ jobs:
7676
"handoff/BOOTSTRAP.md",
7777
"handoff/STATE.md",
7878
"handoff/board/README.md",
79-
"handoff/board/todo/example-task.json",
8079
"handoff/board/doing/.gitkeep",
8180
"handoff/board/done/.gitkeep",
8281
"docs/CURSOR_PROMPTS.md",
@@ -108,18 +107,25 @@ jobs:
108107
print(f"\n{len(missing)} file(s) missing.", file=sys.stderr)
109108
sys.exit(1)
110109
111-
- name: Validate example task JSON
110+
- name: Validate GNAP task schema (board new)
112111
shell: python
113112
run: |
114-
import json, sys
115-
with open("handoff/board/todo/example-task.json", encoding="utf-8") as f:
116-
data = json.load(f)
117-
required = ["id", "title", "status", "assigned_to", "created_at"]
113+
import json, subprocess, sys
114+
from pathlib import Path
115+
116+
subprocess.run(
117+
[sys.executable, "-m", "graphstack", "board", "new", "schema-check", "CI schema probe"],
118+
check=True,
119+
)
120+
path = Path("handoff/board/todo/schema-check.json")
121+
data = json.loads(path.read_text(encoding="utf-8"))
122+
required = ["id", "title", "status", "created_at"]
118123
missing = [k for k in required if k not in data]
124+
path.unlink(missing_ok=True)
119125
if missing:
120-
print(f"Missing keys: {missing}", file=sys.stderr)
126+
print(f"board new() missing keys: {missing}", file=sys.stderr)
121127
sys.exit(1)
122-
print("example-task.json schema OK")
128+
print("GNAP task schema OK")
123129
124130
- name: Run graphstack pytest suite
125131
run: python -m pytest scripts/graphstack/tests -v

handoff/board/README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,30 @@ board/
2626

2727
## Task File Format
2828

29-
See `board/todo/example-task.json` for the schema.
29+
Create `board/todo/<task-id>.json` (filename must match `id`):
30+
31+
```json
32+
{
33+
"id": "add-rate-limiting",
34+
"title": "Add rate limiting to login endpoint",
35+
"created_at": "2026-05-04T10:00:00Z",
36+
"created_by": "architect",
37+
"brief": "handoff/BRIEF.md",
38+
"graph_nodes": [],
39+
"criteria_count": 0,
40+
"priority": "normal",
41+
"status": "todo",
42+
"assigned_to": null,
43+
"started_at": null,
44+
"completed_at": null,
45+
"notes": ""
46+
}
47+
```
48+
49+
Or use the CLI:
50+
51+
```bash
52+
python -m graphstack board new <task-id> "Task title here"
53+
```
54+
55+
Required fields: `id`, `title`, `status`, `created_at`.

orchestrator/ORCHESTRATOR.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Execute this sequence exactly on every session start. Each step has a fallback
2626
→ If directory empty or missing: no tasks in progress — skip silently
2727
→ If 1+ files found: note which tasks are in progress
2828
29-
5. Read handoff/board/todo/*.json (exclude example-task.json)
29+
5. Read handoff/board/todo/*.json
3030
→ If empty: no pending tasks — skip silently
3131
→ If 1+ files found: note how many tasks are waiting
3232

scripts/graphstack/board.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import sys
1212
from pathlib import Path
1313

14-
from .constants import BOARD_DIR, DOING_DIR, DONE_DIR, EXAMPLE_TASK_NAME, TODO_DIR
14+
from .constants import BOARD_DIR, DOING_DIR, DONE_DIR, TODO_DIR
1515
from .platform_utils import echo, run_git, utc_now_iso
1616

1717
VALID_ROLES = ("architect", "builder", "reviewer", "qa", "ship", "bootstrapper")
@@ -47,13 +47,10 @@ def _print_task(path: Path) -> None:
4747
)
4848

4949

50-
def _iter_tasks(directory: Path, exclude_example: bool = False) -> list[Path]:
50+
def _iter_tasks(directory: Path) -> list[Path]:
5151
if not directory.is_dir():
5252
return []
53-
files = sorted(directory.glob("*.json"))
54-
if exclude_example:
55-
files = [f for f in files if f.name != EXAMPLE_TASK_NAME]
56-
return files
53+
return sorted(directory.glob("*.json"))
5754

5855

5956
def _git_commit_board(message: str) -> None:
@@ -69,7 +66,7 @@ def cmd_status(_args: argparse.Namespace) -> int:
6966
echo(f" {'TASK ID':<32} {'STATUS':<10} {'ASSIGNED':<12} TITLE")
7067
echo(" " + "-" * 54)
7168

72-
todo = _iter_tasks(TODO_DIR, exclude_example=True)
69+
todo = _iter_tasks(TODO_DIR)
7370
doing = _iter_tasks(DOING_DIR)
7471
done = _iter_tasks(DONE_DIR)
7572

scripts/graphstack/constants.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
GRAPH_JSON = GRAPHIFY_OUT / "graph.json"
2121
GRAPH_HTML = GRAPHIFY_OUT / "graph.html"
2222

23-
EXAMPLE_TASK_NAME = "example-task.json"
24-
2523
STALE_GRAPH_HOURS = 24
24+
25+
# Required keys for GNAP board task JSON files (see handoff/board/README.md).
26+
TASK_REQUIRED_KEYS = ("id", "title", "status", "created_at")

scripts/graphstack/installer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
(".cursor/skills/ship/SHIP.md", ".cursor/skills/ship/SHIP.md"),
5353
(".cursor/skills/bootstrapper/BOOTSTRAPPER.md", ".cursor/skills/bootstrapper/BOOTSTRAPPER.md"),
5454
("handoff/board/README.md", "handoff/board/README.md"),
55-
("handoff/board/todo/example-task.json", "handoff/board/todo/example-task.json"),
5655
("docs/CURSOR_PROMPTS.md", "docs/CURSOR_PROMPTS.md"),
5756
("scripts/board.sh", "scripts/board.sh"),
5857
("scripts/board.ps1", "scripts/board.ps1"),

scripts/graphstack/tests/test_installer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def test_install_creates_full_layout(tmp_path: Path, monkeypatch: pytest.MonkeyP
3939
"orchestrator/TOKEN_OPTIMIZER.md",
4040
".cursor/skills/builder/BUILDER.md",
4141
"handoff/board/README.md",
42-
"handoff/board/todo/example-task.json",
4342
"handoff/STATE.md",
4443
"scripts/board.sh",
4544
"scripts/board.ps1",

scripts/graphstack/validate.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
BOARD_DIR,
1818
DOING_DIR,
1919
DONE_DIR,
20-
EXAMPLE_TASK_NAME,
2120
GRAPH_REPORT,
2221
HANDOFF_DIR,
22+
TASK_REQUIRED_KEYS,
2323
TODO_DIR,
2424
)
2525
from .platform_utils import echo, git_available, graphify_available, run_git
2626

27-
TASK_REQUIRED_KEYS = ("id", "title", "status", "created_at")
2827
BRIEF_TEMPLATE_MARKERS = (
2928
"[Feature/Change Name]",
3029
"YYYY-MM-DD",
@@ -77,10 +76,7 @@ def _iter_board_tasks() -> list[Path]:
7776
for directory in (TODO_DIR, DOING_DIR, DONE_DIR):
7877
if not directory.is_dir():
7978
continue
80-
for path in sorted(directory.glob("*.json")):
81-
if path.name == EXAMPLE_TASK_NAME:
82-
continue
83-
paths.append(path)
79+
paths.extend(sorted(directory.glob("*.json")))
8480
return paths
8581

8682

0 commit comments

Comments
 (0)