Files
issue-core/INTENT.md
tegwick b605d970e3 feat: rename to issue-core and add task ingestion endpoint
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>
2026-05-17 05:16:27 +02:00

117 lines
5.0 KiB
Markdown

# INTENT — issue-core
## Why it exists
The Coulomb org needs a **single, observable place where tasks land** — regardless
of whether they were created by a human typing a CLI command, by an automation
like activity-core acting on a rule, or by an agent acting on instructions.
Without a single landing zone, task creation fragments across:
- Per-repo Gitea issue trackers (siloed, no cross-repo view)
- Ad hoc files and TODO comments (invisible, unaudited)
- Agent-local memory and notebooks (lost when the agent ends)
- External SaaS trackers (rate-limited, off-network)
issue-core gives every actor — human or machine — one stable, observable place
to file work, and one stable surface to consume work from.
## What it is
A **task lifecycle manager** with a pluggable-backend architecture.
Responsibilities:
- **Ingestion**: accept new tasks via CLI, REST (`POST /issues/`), and — in the
future — NATS subscriptions.
- **Storage**: route each task to the configured backend (Gitea, SQLite, GitHub).
- **Lifecycle**: create → assign → update → close, with state transitions that
hold regardless of backend.
- **Querying**: list, search, filter across the active backend.
- **Synchronization**: bidirectional sync between local SQLite (source of truth
for offline work) and remote backends.
Backends today: **local SQLite**, **Gitea**. Planned: **GitHub**, **GitLab**, **JIRA**.
The CLI entry points are `issue` (primary) and `issue-core` (explicit alias).
## What it is NOT
issue-core is intentionally narrow. The following live elsewhere:
- **Not a project manager.** Phases, campaigns, milestones spanning multiple tasks,
dependency graphs across tasks, gantt-style scheduling — that is the domain of
`project-core` (planned). issue-core deals in individual tasks, not in plans
composed of tasks.
- **Not a spawn audit trail.** When activity-core fires a rule that creates a task,
the *spawn event* (who fired, what rule, what triggering event) is recorded in
activity-core's `task_spawn_log`. issue-core only stores the resulting task and
its `triggering_event_id` reference back. The audit-of-creation belongs to the
emitter.
- **Not an event bus.** Communication between services flows over NATS (and
state-hub progress events). issue-core consumes events, but does not relay them.
- **Not a notification system.** Surfacing "your task changed" to humans is the
job of the relevant UI / digest / chatbot layer, not issue-core.
- **Not a workflow engine.** State transitions are simple (open → closed, with
a few in-between states). Conditional routing, approvals, multi-step
workflows — out of scope.
## How it fits
```
+-------------------+
| activity-core |
| IssueSink (REST) |
+---------+---------+
|
POST /issues/ (TaskSpec payload)
|
v
+------------+ +-------+--------+ +-----------------+
| Humans +----->| |<-----+ Agents |
| CLI: | | issue-core | | (CLI or REST) |
| $ issue | | | | |
+------------+ +-------+--------+ +-----------------+
|
+---------+----------+
| Backend router |
+---+------+------+--+
| | |
v v v
+------+ +-----+ +------+
|Gitea | |SQLite| |GitHub|
+------+ +-----+ +------+
```
**Upstream of issue-core (emitters):**
- **activity-core** — emits tasks via `IssueSink` when a rule fires or an
instruction declares one. Payload: `TaskSpec` over `POST /issues/`.
- **Humans** — `$ issue create ...` from terminals; future web UI.
- **Agents** — same REST surface or CLI.
**Downstream of issue-core (consumers):**
- **Humans and agents** assigned tasks consume them via `$ issue list`, web UI,
or per-backend native UIs (Gitea web, GitHub PR view, etc.).
- **state-hub** receives progress events as tasks move through their lifecycle.
- **Status updates** flow back to issue-core, not to the original emitter —
activity-core does not track what happened to the task it spawned.
## Success looks like
- Every task in the Coulomb org is discoverable from one query surface.
- activity-core can fire a rule and have the resulting task land in the right
backend with the right metadata, with no human in the loop.
- The CLI experience is identical across SQLite-only laptops and full Gitea-
backed servers.
- Offline work syncs back cleanly when connectivity returns.
## See also
- `SCOPE.md` — concrete in/out-of-scope decisions and integration boundaries.
- `ROADMAP.md` — feature trajectory.
- `workplans/` — active workstreams.
- activity-core `docs/adr/adr-001-event-bridge-architecture.md` — the IssueSink
contract that issue-core honors at `POST /issues/`.