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>
117 lines
5.0 KiB
Markdown
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/`.
|