generated from coulomb/repo-seed
Renames the package, distribution, CLI alias, Makefile targets, and working directory from issue-facade to issue-core, signalling its role as the authoritative task lifecycle manager for the Coulomb org (peer to activity-core, rules-core, project-core). Adds POST /issues/ ingestion endpoint for activity-core's IssueSink, under a new optional [api] extra. The endpoint is served by `issue serve`, authenticates via the ISSUE_CORE_API_KEY env var (Bearer or X-API-Key header), and routes the TaskSpec payload to the configured default backend with full traceability metadata embedded in sync_metadata. - T01: Python package issue_tracker -> issue_core, dir rename - T02: registered in state hub under custodian domain - T03: INTENT.md (what it is, what it isn't, how it fits) - T04: SCOPE.md (in/out-of-scope, integration boundaries) - T05: POST /issues/ via FastAPI + Uvicorn, 9 unit tests - T06: docs/nats-task-ingestion.md design stub Closes ISSC-WP-0001. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
165 lines
5.8 KiB
Markdown
165 lines
5.8 KiB
Markdown
# SCOPE — issue-core
|
|
|
|
Concrete in-scope / out-of-scope decisions for issue-core. Paired with `INTENT.md`,
|
|
which explains *why*; this file states *what* and *what not*.
|
|
|
|
## In scope
|
|
|
|
### Task CRUD across backends
|
|
|
|
- **Create** issues with title, description, labels, priority, type, milestone,
|
|
assignee, due date.
|
|
- **Read** individual issues and lists with filters (state, labels, priority,
|
|
assignee, text search).
|
|
- **Update** any mutable field on existing issues.
|
|
- **Close / reopen** with state transitions enforced at the domain layer.
|
|
- **Delete** where the backend allows (local SQLite; soft-archive elsewhere).
|
|
- **Comment** threads on issues.
|
|
|
|
### Backend abstraction
|
|
|
|
- A single `IssueBackend` ABC contract that every backend implements.
|
|
- `BackendCapabilities` declares which optional features a backend supports
|
|
(bulk update, search, milestones, etc.).
|
|
- A `BackendFactory` registry that maps config to backend instances.
|
|
|
|
### Backends shipped today
|
|
|
|
- **Local SQLite** — offline source of truth.
|
|
- **Gitea** — REST API integration.
|
|
|
|
### Backends planned
|
|
|
|
- **GitHub** — Issues + PRs.
|
|
- **GitLab** — Issues.
|
|
- **JIRA** — issues with story-points.
|
|
|
|
### Ingestion surfaces
|
|
|
|
- **CLI** (`issue` / `issue-core`) for humans and agents on a shell.
|
|
- **REST** (`POST /issues/`) for automation — primarily activity-core's
|
|
`IssueSink`, but open to any well-authenticated client.
|
|
- **NATS subscriber** (design stub only — implementation deferred until
|
|
activity-core migrates from REST to NATS, see `docs/nats-task-ingestion.md`).
|
|
|
|
### Synchronization
|
|
|
|
- Local SQLite ↔ remote backends, bidirectional.
|
|
- `get_issues_modified_since()` on `SyncableBackend` for incremental sync.
|
|
- Conflict resolution via `SyncableBackend.resolve_sync_conflict()`.
|
|
- Sync metadata (last-synced timestamps, remote IDs) stored on `Issue.sync_metadata`.
|
|
|
|
### State Hub integration
|
|
|
|
- Registered as a custodian-domain repo.
|
|
- Emits `add_progress_event()` calls on significant task lifecycle moments.
|
|
- Surfaces blocked tasks via the hub's `list_blocked_tasks()` view.
|
|
|
|
## Out of scope
|
|
|
|
### Project management
|
|
|
|
Phases, campaigns, milestones-as-plans, dependency graphs between tasks,
|
|
gantt-style scheduling, OKR linkage. **That is `project-core` (planned).**
|
|
issue-core operates on individual tasks. A milestone field exists for
|
|
flat grouping, not for multi-stage plans.
|
|
|
|
### Spawn audit trail
|
|
|
|
When activity-core's IssueSink files a task here, the *spawn event* (who fired
|
|
the rule, against which activity definition, on which triggering event) is
|
|
recorded in **activity-core's `task_spawn_log`**. issue-core stores the resulting
|
|
task and a back-reference (`triggering_event_id`) — nothing more.
|
|
|
|
Symmetrically: issue-core does not push status updates back to activity-core.
|
|
Lifecycle updates stay here; activity-core does not care what happens to a task
|
|
it spawned.
|
|
|
|
### Event bus / message broker
|
|
|
|
Inter-service communication runs on NATS managed elsewhere. issue-core consumes
|
|
specific subjects (future) and exposes a REST surface; it does not relay events
|
|
between other services.
|
|
|
|
### Notifications
|
|
|
|
Telling a human "your task changed" is the job of the relevant UI, digest,
|
|
chatbot, or notification service — not issue-core. issue-core emits progress
|
|
events; downstream consumers decide what to do with them.
|
|
|
|
### Workflow / approval engine
|
|
|
|
State machine is intentionally small (OPEN, CLOSED, IN_PROGRESS, BLOCKED).
|
|
Conditional routing, approval chains, multi-step workflows, SLA timers — all
|
|
out of scope.
|
|
|
|
### UI
|
|
|
|
issue-core is CLI + REST first. Each backend brings its own native UI
|
|
(Gitea web, GitHub web, etc.) and that is enough. A web UI for issue-core
|
|
itself is not on the roadmap.
|
|
|
|
### Identity / access management
|
|
|
|
Authentication relies on backend credentials (Gitea tokens, GitHub tokens) and
|
|
on a service-level API key for the REST ingestion endpoint. issue-core is not a
|
|
user directory.
|
|
|
|
## Integration boundaries
|
|
|
|
### Upstream emitters
|
|
|
|
| Emitter | Transport | Payload | Notes |
|
|
|----------------|----------------------|--------------------------|-------|
|
|
| Human CLI | local process call | CLI args | The classic path. |
|
|
| activity-core | REST `POST /issues/` | `TaskSpec` (see below) | Primary integration; planned NATS migration. |
|
|
| Agents | REST or CLI | `TaskSpec` or CLI args | Same surfaces as humans/automation. |
|
|
|
|
### Downstream consumers
|
|
|
|
| Consumer | Mechanism | Notes |
|
|
|----------------------|------------------------------------|-------|
|
|
| Humans / agents | `issue list`, web UI, backend UI | Standard task pickup. |
|
|
| state-hub | `add_progress_event()` calls | Lifecycle visibility. |
|
|
| Backend remote (e.g. Gitea) | direct backend write | Pass-through for the storage layer. |
|
|
|
|
### `TaskSpec` payload (from activity-core's IssueSink)
|
|
|
|
```json
|
|
{
|
|
"title": "string",
|
|
"description": "string",
|
|
"target_repo": "string",
|
|
"priority": "high | medium | low",
|
|
"labels": ["string"],
|
|
"due_in_days": 7,
|
|
"source_type": "rule | instruction",
|
|
"source_id": "string",
|
|
"triggering_event_id": "uuid",
|
|
"activity_definition_id": "string"
|
|
}
|
|
```
|
|
|
|
### `POST /issues/` response
|
|
|
|
```json
|
|
{
|
|
"issue_id": "string",
|
|
"issue_url": "string or null",
|
|
"backend": "gitea | sqlite | github"
|
|
}
|
|
```
|
|
|
|
The `issue_id` is the canonical back-reference activity-core stores in its
|
|
`task_spawn_log`. It is owned and managed by issue-core; activity-core does not
|
|
mutate it.
|
|
|
|
## See also
|
|
|
|
- `INTENT.md` — why issue-core exists and how it fits in the Coulomb org.
|
|
- `ROADMAP.md` — feature trajectory.
|
|
- `workplans/ISSC-WP-0001-rename-and-task-ingestion.md` — current rename +
|
|
ingestion workstream.
|
|
- activity-core `docs/adr/adr-001-event-bridge-architecture.md` — the upstream
|
|
side of the IssueSink contract.
|