Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
"""Task specification the worker consumes.
|
|
|
|
|
|
|
|
|
|
MVP source is a JSON file matching what the activity-core issue-core sink
|
|
|
|
|
emits per rule action (task_template/description/target_repo/labels), plus
|
|
|
|
|
executor-specific fields. A future source polls issue-core directly.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
2026-08-23 13:23:50 +02:00
|
|
|
from rein_aharness.repository_grant import RepositoryGrant, RepositoryGrantError
|
|
|
|
|
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
class TaskSpecError(ValueError):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class TaskSpec:
|
|
|
|
|
title: str
|
|
|
|
|
description: str
|
|
|
|
|
target_repo: Path
|
|
|
|
|
agent: str = "coach"
|
|
|
|
|
labels: list[str] = field(default_factory=list)
|
|
|
|
|
hub_task_id: str | None = None
|
|
|
|
|
completion_event_type: str = "executor_run"
|
|
|
|
|
timeout_seconds: int = 900
|
2026-08-23 13:23:50 +02:00
|
|
|
repository_grant: RepositoryGrant | None = None
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def from_file(cls, path: str | Path) -> "TaskSpec":
|
|
|
|
|
raw = json.loads(Path(path).read_text())
|
|
|
|
|
missing = {"title", "description", "target_repo"} - set(raw)
|
|
|
|
|
if missing:
|
|
|
|
|
raise TaskSpecError(f"task spec missing field(s): {', '.join(sorted(missing))}")
|
|
|
|
|
target = Path(raw["target_repo"]).expanduser()
|
|
|
|
|
if not (target / ".git").is_dir():
|
|
|
|
|
raise TaskSpecError(f"target_repo is not a git repository: {target}")
|
2026-08-23 13:23:50 +02:00
|
|
|
grant = None
|
|
|
|
|
if "repository_grant" in raw:
|
|
|
|
|
try:
|
|
|
|
|
grant = RepositoryGrant.from_mapping(raw["repository_grant"])
|
|
|
|
|
except RepositoryGrantError as exc:
|
|
|
|
|
raise TaskSpecError(f"invalid repository_grant: {exc}") from exc
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
return cls(
|
|
|
|
|
title=str(raw["title"]),
|
|
|
|
|
description=str(raw["description"]),
|
|
|
|
|
target_repo=target,
|
|
|
|
|
agent=str(raw.get("agent", "coach")),
|
|
|
|
|
labels=[str(label) for label in raw.get("labels", [])],
|
|
|
|
|
hub_task_id=raw.get("hub_task_id"),
|
|
|
|
|
completion_event_type=str(raw.get("completion_event_type", "executor_run")),
|
|
|
|
|
timeout_seconds=int(raw.get("timeout_seconds", 900)),
|
2026-08-23 13:23:50 +02:00
|
|
|
repository_grant=grant,
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
)
|